Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57625593 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab
Browse files

[media] coda: v4l2-compliance fix: overwrite invalid pixel formats with the current setting



This patch fixes the v4l2-compliance "TRY_FMT(G_FMT) != G_FMT" issue.
The driver now overwrites invalid formats with the current setting, using
coda_get_max_dimensions to find device specific max width/height.

Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent 2e9e4f11
Loading
Loading
Loading
Loading
+56 −16
Original line number Diff line number Diff line
@@ -54,8 +54,6 @@

#define CODA_MAX_FRAMEBUFFERS	8

#define MAX_W		8192
#define MAX_H		8192
#define CODA_MAX_FRAME_SIZE	0x100000
#define FMO_SLICE_SAVE_BUF_SIZE         (32)
#define CODA_DEFAULT_GAMMA		4096
@@ -394,6 +392,31 @@ static struct coda_codec *coda_find_codec(struct coda_dev *dev, int src_fourcc,
	return &codecs[k];
}

static void coda_get_max_dimensions(struct coda_dev *dev,
				    struct coda_codec *codec,
				    int *max_w, int *max_h)
{
	struct coda_codec *codecs = dev->devtype->codecs;
	int num_codecs = dev->devtype->num_codecs;
	unsigned int w, h;
	int k;

	if (codec) {
		w = codec->max_w;
		h = codec->max_h;
	} else {
		for (k = 0, w = 0, h = 0; k < num_codecs; k++) {
			w = max(w, codecs[k].max_w);
			h = max(h, codecs[k].max_h);
		}
	}

	if (max_w)
		*max_w = w;
	if (max_h)
		*max_h = h;
}

static char *coda_product_name(int product)
{
	static char buf[9];
@@ -537,8 +560,11 @@ static int coda_g_fmt(struct file *file, void *priv,
	return 0;
}

static int coda_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
static int coda_try_fmt(struct coda_ctx *ctx, struct coda_codec *codec,
			struct v4l2_format *f)
{
	struct coda_dev *dev = ctx->dev;
	struct coda_q_data *q_data;
	unsigned int max_w, max_h;
	enum v4l2_field field;

@@ -552,25 +578,39 @@ static int coda_try_fmt(struct coda_codec *codec, struct v4l2_format *f)
	 * if any of the dimensions is unsupported */
	f->fmt.pix.field = field;

	if (codec) {
		max_w = codec->max_w;
		max_h = codec->max_h;
	} else {
		max_w = MAX_W;
		max_h = MAX_H;
	coda_get_max_dimensions(dev, codec, &max_w, &max_h);
	v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w, W_ALIGN,
			      &f->fmt.pix.height, MIN_H, max_h, H_ALIGN,
			      S_ALIGN);

	switch (f->fmt.pix.pixelformat) {
	case V4L2_PIX_FMT_YUV420:
	case V4L2_PIX_FMT_YVU420:
	case V4L2_PIX_FMT_H264:
	case V4L2_PIX_FMT_MPEG4:
	case V4L2_PIX_FMT_JPEG:
		break;
	default:
		q_data = get_q_data(ctx, f->type);
		f->fmt.pix.pixelformat = q_data->fourcc;
	}
	v4l_bound_align_image(&f->fmt.pix.width, MIN_W, max_w,
			      W_ALIGN, &f->fmt.pix.height,
			      MIN_H, max_h, H_ALIGN, S_ALIGN);

	if (coda_format_is_yuv(f->fmt.pix.pixelformat)) {
	switch (f->fmt.pix.pixelformat) {
	case V4L2_PIX_FMT_YUV420:
	case V4L2_PIX_FMT_YVU420:
		/* Frame stride must be multiple of 8 */
		f->fmt.pix.bytesperline = round_up(f->fmt.pix.width, 8);
		f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
					f->fmt.pix.height * 3 / 2;
	} else { /*encoded formats h.264/mpeg4 */
		break;
	case V4L2_PIX_FMT_H264:
	case V4L2_PIX_FMT_MPEG4:
	case V4L2_PIX_FMT_JPEG:
		f->fmt.pix.bytesperline = 0;
		f->fmt.pix.sizeimage = CODA_MAX_FRAME_SIZE;
		break;
	default:
		BUG();
	}

	return 0;
@@ -605,7 +645,7 @@ static int coda_try_fmt_vid_cap(struct file *file, void *priv,

	f->fmt.pix.colorspace = ctx->colorspace;

	ret = coda_try_fmt(codec, f);
	ret = coda_try_fmt(ctx, codec, f);
	if (ret < 0)
		return ret;

@@ -634,7 +674,7 @@ static int coda_try_fmt_vid_out(struct file *file, void *priv,
	if (!f->fmt.pix.colorspace)
		f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;

	return coda_try_fmt(codec, f);
	return coda_try_fmt(ctx, codec, f);
}

static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)