diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-01-04 17:46:53 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-01-06 07:48:00 -0500 |
commit | 31e582e9263277173e097e5ef8ce8fdfd2e9bc45 (patch) | |
tree | 31f4a4b0f95e3dca7dc94defa76450f7bb4bfe0f | |
parent | 5bbe18d74f0c163090cd16bd25e252e8806a6c75 (diff) |
[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: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/pwc/pwc-v4l.c | 42 |
1 files changed, 17 insertions, 25 deletions
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 36da7d400907..80e25842e84a 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c | |||
@@ -395,25 +395,16 @@ int pwc_init_controls(struct pwc_device *pdev) | |||
395 | return hdl->error; | 395 | return hdl->error; |
396 | } | 396 | } |
397 | 397 | ||
398 | static void pwc_vidioc_fill_fmt(const struct pwc_device *pdev, struct v4l2_format *f) | 398 | static void pwc_vidioc_fill_fmt(struct v4l2_format *f, |
399 | int width, int height, u32 pixfmt) | ||
399 | { | 400 | { |
400 | memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); | 401 | memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format)); |
401 | f->fmt.pix.width = pdev->width; | 402 | f->fmt.pix.width = width; |
402 | f->fmt.pix.height = pdev->height; | 403 | f->fmt.pix.height = height; |
403 | f->fmt.pix.field = V4L2_FIELD_NONE; | 404 | f->fmt.pix.field = V4L2_FIELD_NONE; |
404 | if (pdev->pixfmt == V4L2_PIX_FMT_YUV420) { | 405 | f->fmt.pix.pixelformat = pixfmt; |
405 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; | 406 | f->fmt.pix.bytesperline = f->fmt.pix.width; |
406 | f->fmt.pix.bytesperline = (f->fmt.pix.width * 3)/2; | 407 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.width * 3 / 2; |
407 | f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; | ||
408 | } else { | ||
409 | /* vbandlength contains 4 lines ... */ | ||
410 | f->fmt.pix.bytesperline = pdev->vbandlength/4; | ||
411 | f->fmt.pix.sizeimage = pdev->frame_size + sizeof(struct pwc_raw_frame); | ||
412 | if (DEVICE_USE_CODEC1(pdev->type)) | ||
413 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC1; | ||
414 | else | ||
415 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_PWC2; | ||
416 | } | ||
417 | PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " | 408 | PWC_DEBUG_IOCTL("pwc_vidioc_fill_fmt() " |
418 | "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", | 409 | "width=%d, height=%d, bytesperline=%d, sizeimage=%d, pixelformat=%c%c%c%c\n", |
419 | f->fmt.pix.width, | 410 | f->fmt.pix.width, |
@@ -458,8 +449,10 @@ static int pwc_vidioc_try_fmt(struct pwc_device *pdev, struct v4l2_format *f) | |||
458 | } | 449 | } |
459 | 450 | ||
460 | size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height); | 451 | size = pwc_get_size(pdev, f->fmt.pix.width, f->fmt.pix.height); |
461 | f->fmt.pix.width = pwc_image_sizes[size][0]; | 452 | pwc_vidioc_fill_fmt(f, |
462 | f->fmt.pix.height = pwc_image_sizes[size][1]; | 453 | pwc_image_sizes[size][0], |
454 | pwc_image_sizes[size][1], | ||
455 | f->fmt.pix.pixelformat); | ||
463 | 456 | ||
464 | return 0; | 457 | return 0; |
465 | } | 458 | } |
@@ -480,11 +473,6 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
480 | 473 | ||
481 | pixelformat = f->fmt.pix.pixelformat; | 474 | pixelformat = f->fmt.pix.pixelformat; |
482 | 475 | ||
483 | if (pixelformat != V4L2_PIX_FMT_YUV420 && | ||
484 | pixelformat != V4L2_PIX_FMT_PWC1 && | ||
485 | pixelformat != V4L2_PIX_FMT_PWC2) | ||
486 | return -EINVAL; | ||
487 | |||
488 | mutex_lock(&pdev->udevlock); | 476 | mutex_lock(&pdev->udevlock); |
489 | if (!pdev->udev) { | 477 | if (!pdev->udev) { |
490 | ret = -ENODEV; | 478 | ret = -ENODEV; |
@@ -511,7 +499,8 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
511 | 499 | ||
512 | if (ret == 0) { | 500 | if (ret == 0) { |
513 | pdev->pixfmt = pixelformat; | 501 | pdev->pixfmt = pixelformat; |
514 | pwc_vidioc_fill_fmt(pdev, f); | 502 | pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, |
503 | pdev->pixfmt); | ||
515 | } | 504 | } |
516 | 505 | ||
517 | leave: | 506 | leave: |
@@ -962,10 +951,13 @@ static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | |||
962 | { | 951 | { |
963 | struct pwc_device *pdev = video_drvdata(file); | 952 | struct pwc_device *pdev = video_drvdata(file); |
964 | 953 | ||
954 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
955 | return -EINVAL; | ||
956 | |||
965 | mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */ | 957 | mutex_lock(&pdev->udevlock); /* To avoid race with s_fmt */ |
966 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", | 958 | PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n", |
967 | pdev->width, pdev->height); | 959 | pdev->width, pdev->height); |
968 | pwc_vidioc_fill_fmt(pdev, f); | 960 | pwc_vidioc_fill_fmt(f, pdev->width, pdev->height, pdev->pixfmt); |
969 | mutex_unlock(&pdev->udevlock); | 961 | mutex_unlock(&pdev->udevlock); |
970 | return 0; | 962 | return 0; |
971 | } | 963 | } |