[media] v4l: emulate old crop API using extended crop/compose API
authorTomasz Stanislawski <t.stanislaws@samsung.com>
Tue, 22 Mar 2011 17:04:47 +0000 (14:04 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 11 Jan 2012 01:18:52 +0000 (23:18 -0200)
This patch allows new video drivers to work correctly with applications that
use the old-style crop API.  The old crop ioctl is emulated by using selection
callbacks.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/v4l2-ioctl.c

index 072cfc1a166f6c9fe33cc857d9c54e7d4365c55a..77feeb67e2db389334e186299c882ce4fd87e847 100644 (file)
@@ -1549,11 +1549,32 @@ static long __video_do_ioctl(struct file *file,
        {
                struct v4l2_crop *p = arg;
 
-               if (!ops->vidioc_g_crop)
+               if (!ops->vidioc_g_crop && !ops->vidioc_g_selection)
                        break;
 
                dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
-               ret = ops->vidioc_g_crop(file, fh, p);
+
+               if (ops->vidioc_g_crop) {
+                       ret = ops->vidioc_g_crop(file, fh, p);
+               } else {
+                       /* simulate capture crop using selection api */
+                       struct v4l2_selection s = {
+                               .type = p->type,
+                       };
+
+                       /* crop means compose for output devices */
+                       if (V4L2_TYPE_IS_OUTPUT(p->type))
+                               s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
+                       else
+                               s.target = V4L2_SEL_TGT_CROP_ACTIVE;
+
+                       ret = ops->vidioc_g_selection(file, fh, &s);
+
+                       /* copying results to old structure on success */
+                       if (!ret)
+                               p->c = s.r;
+               }
+
                if (!ret)
                        dbgrect(vfd, "", &p->c);
                break;
@@ -1562,15 +1583,33 @@ static long __video_do_ioctl(struct file *file,
        {
                struct v4l2_crop *p = arg;
 
-               if (!ops->vidioc_s_crop)
+               if (!ops->vidioc_s_crop && !ops->vidioc_s_selection)
                        break;
+
                if (ret_prio) {
                        ret = ret_prio;
                        break;
                }
                dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
                dbgrect(vfd, "", &p->c);
-               ret = ops->vidioc_s_crop(file, fh, p);
+
+               if (ops->vidioc_s_crop) {
+                       ret = ops->vidioc_s_crop(file, fh, p);
+               } else {
+                       /* simulate capture crop using selection api */
+                       struct v4l2_selection s = {
+                               .type = p->type,
+                               .r = p->c,
+                       };
+
+                       /* crop means compose for output devices */
+                       if (V4L2_TYPE_IS_OUTPUT(p->type))
+                               s.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
+                       else
+                               s.target = V4L2_SEL_TGT_CROP_ACTIVE;
+
+                       ret = ops->vidioc_s_selection(file, fh, &s);
+               }
                break;
        }
        case VIDIOC_G_SELECTION:
@@ -1610,11 +1649,42 @@ static long __video_do_ioctl(struct file *file,
                struct v4l2_cropcap *p = arg;
 
                /*FIXME: Should also show v4l2_fract pixelaspect */
-               if (!ops->vidioc_cropcap)
+               if (!ops->vidioc_cropcap && !ops->vidioc_g_selection)
                        break;
 
                dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
-               ret = ops->vidioc_cropcap(file, fh, p);
+               if (ops->vidioc_cropcap) {
+                       ret = ops->vidioc_cropcap(file, fh, p);
+               } else {
+                       struct v4l2_selection s = { .type = p->type };
+
+                       /* obtaining bounds */
+                       if (V4L2_TYPE_IS_OUTPUT(p->type))
+                               s.target = V4L2_SEL_TGT_COMPOSE_BOUNDS;
+                       else
+                               s.target = V4L2_SEL_TGT_CROP_BOUNDS;
+
+                       ret = ops->vidioc_g_selection(file, fh, &s);
+                       if (ret)
+                               break;
+                       p->bounds = s.r;
+
+                       /* obtaining defrect */
+                       if (V4L2_TYPE_IS_OUTPUT(p->type))
+                               s.target = V4L2_SEL_TGT_COMPOSE_DEFAULT;
+                       else
+                               s.target = V4L2_SEL_TGT_CROP_DEFAULT;
+
+                       ret = ops->vidioc_g_selection(file, fh, &s);
+                       if (ret)
+                               break;
+                       p->defrect = s.r;
+
+                       /* setting trivial pixelaspect */
+                       p->pixelaspect.numerator = 1;
+                       p->pixelaspect.denominator = 1;
+               }
+
                if (!ret) {
                        dbgrect(vfd, "bounds ", &p->bounds);
                        dbgrect(vfd, "defrect ", &p->defrect);