diff options
-rw-r--r-- | drivers/media/video/v4l1-compat.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c index efb67d29fc0b..ede8543818bf 100644 --- a/drivers/media/video/v4l1-compat.c +++ b/drivers/media/video/v4l1-compat.c | |||
@@ -616,6 +616,8 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
616 | case VIDIOCSPICT: /* set tone controls & partial capture format */ | 616 | case VIDIOCSPICT: /* set tone controls & partial capture format */ |
617 | { | 617 | { |
618 | struct video_picture *pict = arg; | 618 | struct video_picture *pict = arg; |
619 | int mem_err = 0, ovl_err = 0; | ||
620 | |||
619 | memset(&fbuf2, 0, sizeof(fbuf2)); | 621 | memset(&fbuf2, 0, sizeof(fbuf2)); |
620 | 622 | ||
621 | set_v4l_control(inode, file, | 623 | set_v4l_control(inode, file, |
@@ -628,33 +630,59 @@ v4l_compat_translate_ioctl(struct inode *inode, | |||
628 | V4L2_CID_SATURATION, pict->colour, drv); | 630 | V4L2_CID_SATURATION, pict->colour, drv); |
629 | set_v4l_control(inode, file, | 631 | set_v4l_control(inode, file, |
630 | V4L2_CID_WHITENESS, pict->whiteness, drv); | 632 | V4L2_CID_WHITENESS, pict->whiteness, drv); |
633 | /* | ||
634 | * V4L1 uses this ioctl to set both memory capture and overlay | ||
635 | * pixel format, while V4L2 has two different ioctls for this. | ||
636 | * Some cards may not support one or the other, and may support | ||
637 | * different pixel formats for memory vs overlay. | ||
638 | */ | ||
631 | 639 | ||
632 | fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); | 640 | fmt2 = kzalloc(sizeof(*fmt2),GFP_KERNEL); |
633 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 641 | fmt2->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
634 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); | 642 | err = drv(inode, file, VIDIOC_G_FMT, fmt2); |
635 | if (err < 0) | 643 | /* If VIDIOC_G_FMT failed, then the driver likely doesn't |
644 | support memory capture. Trying to set the memory capture | ||
645 | parameters would be pointless. */ | ||
646 | if (err < 0) { | ||
636 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err); | 647 | dprintk("VIDIOCSPICT / VIDIOC_G_FMT: %d\n",err); |
637 | if (fmt2->fmt.pix.pixelformat != | 648 | mem_err = -1000; /* didn't even try */ |
638 | palette_to_pixelformat(pict->palette)) { | 649 | } else if (fmt2->fmt.pix.pixelformat != |
650 | palette_to_pixelformat(pict->palette)) { | ||
639 | fmt2->fmt.pix.pixelformat = palette_to_pixelformat( | 651 | fmt2->fmt.pix.pixelformat = palette_to_pixelformat( |
640 | pict->palette); | 652 | pict->palette); |
641 | err = drv(inode, file, VIDIOC_S_FMT, fmt2); | 653 | mem_err = drv(inode, file, VIDIOC_S_FMT, fmt2); |
642 | if (err < 0) | 654 | if (mem_err < 0) |
643 | dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n",err); | 655 | dprintk("VIDIOCSPICT / VIDIOC_S_FMT: %d\n", |
656 | mem_err); | ||
644 | } | 657 | } |
645 | 658 | ||
646 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); | 659 | err = drv(inode, file, VIDIOC_G_FBUF, &fbuf2); |
647 | if (err < 0) | 660 | /* If VIDIOC_G_FBUF failed, then the driver likely doesn't |
661 | support overlay. Trying to set the overlay parameters | ||
662 | would be quite pointless. */ | ||
663 | if (err < 0) { | ||
648 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err); | 664 | dprintk("VIDIOCSPICT / VIDIOC_G_FBUF: %d\n",err); |
649 | if (fbuf2.fmt.pixelformat != | 665 | ovl_err = -1000; /* didn't even try */ |
650 | palette_to_pixelformat(pict->palette)) { | 666 | } else if (fbuf2.fmt.pixelformat != |
667 | palette_to_pixelformat(pict->palette)) { | ||
651 | fbuf2.fmt.pixelformat = palette_to_pixelformat( | 668 | fbuf2.fmt.pixelformat = palette_to_pixelformat( |
652 | pict->palette); | 669 | pict->palette); |
653 | err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); | 670 | ovl_err = drv(inode, file, VIDIOC_S_FBUF, &fbuf2); |
654 | if (err < 0) | 671 | if (ovl_err < 0) |
655 | dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n",err); | 672 | dprintk("VIDIOCSPICT / VIDIOC_S_FBUF: %d\n", |
656 | err = 0; /* likely fails for non-root */ | 673 | ovl_err); |
657 | } | 674 | } |
675 | if (ovl_err < 0 && mem_err < 0) | ||
676 | /* ioctl failed, couldn't set either parameter */ | ||
677 | if (mem_err != -1000) { | ||
678 | err = mem_err; | ||
679 | } else if (ovl_err == -EPERM) { | ||
680 | err = 0; | ||
681 | } else { | ||
682 | err = ovl_err; | ||
683 | } | ||
684 | else | ||
685 | err = 0; | ||
658 | break; | 686 | break; |
659 | } | 687 | } |
660 | case VIDIOCGTUNER: /* get tuner information */ | 688 | case VIDIOCGTUNER: /* get tuner information */ |