Commit 31e582e9 authored by Hans de Goede's avatar Hans de Goede Committed by Mauro Carvalho Chehab

[media] pwc: Properly fill all fields on try_fmt

Before this patch the resulting values from a try_fmt were different then
those from a s_fmt with the same parameters. try_fmt simply did not
touch / fill some values like bytesperline at all.

This patch also corrects bytesperline to the proper value for a planar
format such as the YUV420P format the pwc driver produces, which is
the bytesperline value for the biggest plane, rather then those
of all planes added together.
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 5bbe18d7
...@@ -395,25 +395,16 @@ int pwc_init_controls(struct pwc_device *pdev) ...@@ -395,25 +395,16 @@ int pwc_init_controls(struct pwc_device *pdev)
return hdl->error; return hdl->error;
} }
static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f) static void pwc_vidioc_fill_fmt(struct v4l2_format *f,
int width, int height, u32 pixfmt)
{ {
memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
f->fmt.pix.width = pdev->width; f->fmt.pix.width = width;
f->fmt.pix.height = pdev->height; f->fmt.pix.height = height;
f->fmt.pix.field = V4L2_FIELD_NONE; f->fmt.pix.field = V4L2_FIELD_NONE;
if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) { f->fmt.pix.pixelformat = pixfmt;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; f->fmt.pix.bytesperline = f->fmt.pix.width;
f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.width * 3 / 2;
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
} else {
/* vbandlength contains 4 lines ... */
f->fmt.pix.bytesperline = pdev->vbandlength/4;
f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame);
if (DEVICE_USE_CODEC1(pdev->type))
f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1;
else
f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2;
}
PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() "
"width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n",
f->fmt.pix.width, f->fmt.pix.width,
...@@ -458,8 +449,10 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) ...@@ -458,8 +449,10 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f)
} }
size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height); size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height);
f->fmt.pix.width = pwc_image_sizes[size][0]; pwc_vidioc_fill_fmt(f,
f->fmt.pix.height = pwc_image_sizes[size][1]; pwc_image_sizes[size][0],
pwc_image_sizes[size][1],
f->fmt.pix.pixelformat);
return 0; return 0;
} }
...@@ -480,11 +473,6 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) ...@@ -480,11 +473,6 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
pixelformat = f->fmt.pix.pixelformat; pixelformat = f->fmt.pix.pixelformat;
if (pixelformat != V4L2_PIX_FMT_YUV420 &&
pixelformat != V4L2_PIX_FMT_PWC1 &&
pixelformat != V4L2_PIX_FMT_PWC2)
return -EINVAL;
mutex_lock(&pdev->udevlock); mutex_lock(&pdev->udevlock);
if (!pdev->udev) { if (!pdev->udev) {
ret = -ENODEV; ret = -ENODEV;
...@@ -511,7 +499,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) ...@@ -511,7 +499,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
if (ret == 0) { if (ret == 0) {
pdev->pixfmt = pixelformat; pdev->pixfmt = pixelformat;
pwc_vidioc_fill_fmt(pdev, f); pwc_vidioc_fill_fmt(f, pdev->width, pdev->height,
pdev->pixfmt);
} }
leave: leave:
...@@ -962,10 +951,13 @@ static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) ...@@ -962,10 +951,13 @@ static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
{ {
struct pwc_device *pdev = video_drvdata(file); struct pwc_device *pdev = video_drvdata(file);
if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */ mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */
PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
pdev->width, pdev->height); pdev->width, pdev->height);
pwc_vidioc_fill_fmt(pdev, f); pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt);
mutex_unlock(&pdev->udevlock); mutex_unlock(&pdev->udevlock);
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment