Commit 13de5a51 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

media: cx18: fix format compliance issues



This properly fills in all the format fields and calculates the
width and height correctly.

Esp. the minimum width and height was wrong.

When changing the standard the width and height also have to be
reset to the corresponding default width/height for the chosen
standard.

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 00d08584
Loading
Loading
Loading
Loading
+44 −27
Original line number Original line Diff line number Diff line
@@ -78,29 +78,43 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
{
{
	struct cx18_open_id *id = fh2id(fh);
	struct cx18_open_id *id = fh2id(fh);
	struct cx18 *cx = id->cx;
	struct cx18 *cx = id->cx;
	int w = fmt->fmt.pix.width;
	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
	int h = fmt->fmt.pix.height;
	int w = pixfmt->width;
	int min_h = 2;
	int h = pixfmt->height;


	w = min(w, 720);
	w = min(w, 720);
	w = max(w, 2);
	w = max(w, 720 / 16);

	h = min(h, cx->is_50hz ? 576 : 480);
	h = max(h, (cx->is_50hz ? 576 : 480) / 8);


	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
		if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_NV12_16L16 &&
		if (pixfmt->pixelformat != V4L2_PIX_FMT_NV12_16L16 &&
		    fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
		    pixfmt->pixelformat != V4L2_PIX_FMT_UYVY)
			fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
			pixfmt->pixelformat = V4L2_PIX_FMT_UYVY;
		/* YUV height must be a multiple of 32 */
		/* YUV height must be a multiple of 32 */
		h &= ~0x1f;
		h = round_up(h, 32);
		min_h = 32;
		/*
		 * HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
		 * UYUV YUV size is (Y=(h*720) + UV=(h*(720)))
		 */
		if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12_16L16) {
			pixfmt->sizeimage = h * 720 * 3 / 2;
			pixfmt->bytesperline = 720; /* First plane */
		} else {
		} else {
		fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
			pixfmt->sizeimage = h * 720 * 2;
			pixfmt->bytesperline = 1440; /* Packed */
		}
	} else {
		pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
		pixfmt->sizeimage = 128 * 1024;
		pixfmt->bytesperline = 0;
	}
	}


	h = min(h, cx->is_50hz ? 576 : 480);
	pixfmt->width = w;
	h = max(h, min_h);
	pixfmt->height = h;

	pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
	fmt->fmt.pix.width = w;
	pixfmt->field = V4L2_FIELD_INTERLACED;
	fmt->fmt.pix.height = h;
	return 0;
	return 0;
}
}


@@ -130,17 +144,8 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
		return -EBUSY;
		return -EBUSY;


	s->pixelformat = fmt->fmt.pix.pixelformat;
	s->pixelformat = fmt->fmt.pix.pixelformat;
	/*
	s->vb_bytes_per_frame = fmt->fmt.pix.sizeimage;
	 * HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
	s->vb_bytes_per_line = fmt->fmt.pix.bytesperline;
	 * UYUV YUV size is (Y=(h*720) + UV=(h*(720)))
	 */
	if (s->pixelformat == V4L2_PIX_FMT_NV12_16L16) {
		s->vb_bytes_per_frame = h * 720 * 3 / 2;
		s->vb_bytes_per_line = 720; /* First plane */
	} else {
		s->vb_bytes_per_frame = h * 720 * 2;
		s->vb_bytes_per_line = 1440; /* Packed */
	}


	format.format.width = cx->cxhdl.width = w;
	format.format.width = cx->cxhdl.width = w;
	format.format.height = cx->cxhdl.height = h;
	format.format.height = cx->cxhdl.height = h;
@@ -253,7 +258,6 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
	return set;
	return set;
}
}



static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
				struct v4l2_format *fmt)
				struct v4l2_format *fmt)
{
{
@@ -614,6 +618,19 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
	cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
	cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
	cx->cxhdl.width = 720;
	cx->cxhdl.width = 720;
	cx->cxhdl.height = cx->is_50hz ? 576 : 480;
	cx->cxhdl.height = cx->is_50hz ? 576 : 480;
	/*
	 * HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
	 * UYUV YUV size is (Y=(h*720) + UV=(h*(720)))
	 */
	if (cx->streams[CX18_ENC_STREAM_TYPE_YUV].pixelformat == V4L2_PIX_FMT_NV12_16L16) {
		cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_frame =
			cx->cxhdl.height * 720 * 3 / 2;
		cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_line = 720;
	} else {
		cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_frame =
			cx->cxhdl.height * 720 * 2;
		cx->streams[CX18_ENC_STREAM_TYPE_YUV].vb_bytes_per_line = 1440;
	}
	cx->vbi.count = cx->is_50hz ? 18 : 12;
	cx->vbi.count = cx->is_50hz ? 18 : 12;
	cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
	cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
	cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
	cx->vbi.start[1] = cx->is_50hz ? 318 : 273;