Fall back to regular S_CTRL / G_CTRL if extended controls aren't available.

Also don't try to get value for classes.

Signed-off-by: Sakari Ailus <sakari.ai...@iki.fi>
---
 yavta.c |  130 ++++++++++++++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 100 insertions(+), 30 deletions(-)

diff --git a/yavta.c b/yavta.c
index af6f3be..d3a4a0e 100644
--- a/yavta.c
+++ b/yavta.c
@@ -230,40 +230,104 @@ static void video_close(struct device *dev)
        close(dev->fd);
 }
 
-static void uvc_get_control(struct device *dev, unsigned int id)
+static unsigned int get_control_type(struct device *dev, unsigned int id)
 {
-       struct v4l2_control ctrl;
+       struct v4l2_queryctrl query;
        int ret;
 
+       memset(&query, 0, sizeof(query));
+
+       query.id = id;
+       ret = ioctl(dev->fd, VIDIOC_QUERYCTRL, &query);
+       if (ret == -1)
+               return V4L2_CTRL_TYPE_INTEGER;
+
+       return query.type;
+}
+
+static int get_control(struct device *dev, unsigned int id, int type,
+                      int64_t *val)
+{
+       struct v4l2_ext_controls ctrls;
+       struct v4l2_ext_control ctrl;
+       int ret;
+       
+       memset(&ctrls, 0, sizeof(ctrls));
+       memset(&ctrl, 0, sizeof(ctrl));
+
+       ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(id);
+       ctrls.count = 1;
+       ctrls.controls = &ctrl;
+
        ctrl.id = id;
 
-       ret = ioctl(dev->fd, VIDIOC_G_CTRL, &ctrl);
-       if (ret < 0) {
-               printf("unable to get control: %s (%d).\n",
-                       strerror(errno), errno);
-               return;
+       ret = ioctl(dev->fd, VIDIOC_G_EXT_CTRLS, &ctrls);
+       if (ret != -1) {
+               if (type == V4L2_CTRL_TYPE_INTEGER64)
+                       *val = ctrl.value64;
+               else
+                       *val = ctrl.value;
+               return 0;
+       }
+       if (errno == EINVAL || errno == ENOTTY) {
+               struct v4l2_control old;
+
+               old.id = id;
+               ret = ioctl(dev->fd, VIDIOC_G_CTRL, &old);
+               if (ret != -1) {
+                       *val = old.value;
+                       return 0;
+               }
        }
 
-       printf("Control 0x%08x value %u\n", id, ctrl.value);
+       printf("unable to get control 0x%8.8x: %s (%d).\n",
+               id, strerror(errno), errno);
+       return -1;
 }
 
-static void uvc_set_control(struct device *dev, unsigned int id, int value)
+static void set_control(struct device *dev, unsigned int id, int type,
+                       int64_t val)
 {
-       struct v4l2_control ctrl;
+       struct v4l2_ext_controls ctrls;
+       struct v4l2_ext_control ctrl;
+       int is_64 = type == V4L2_CTRL_TYPE_INTEGER64;
+       int64_t old_val = val;
        int ret;
+       
+       memset(&ctrls, 0, sizeof(ctrls));
+       memset(&ctrl, 0, sizeof(ctrl));
+
+       ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(id);
+       ctrls.count = 1;
+       ctrls.controls = &ctrl;
 
        ctrl.id = id;
-       ctrl.value = value;
+       if (is_64)
+               ctrl.value64 = val;
+       else
+               ctrl.value = val;
 
-       ret = ioctl(dev->fd, VIDIOC_S_CTRL, &ctrl);
-       if (ret < 0) {
-               printf("unable to set control: %s (%d).\n",
-                       strerror(errno), errno);
+       ret = ioctl(dev->fd, VIDIOC_S_EXT_CTRLS, &ctrls);
+       if (ret != -1) {
+               if (is_64)
+                       val = ctrl.value64;
+               else
+                       val = ctrl.value;
+       } else if (errno == EINVAL || errno == ENOTTY) {
+               struct v4l2_control old;
+
+               old.id = id;
+               ret = ioctl(dev->fd, VIDIOC_S_CTRL, &old);
+               if (ret != -1)
+                       val = old.value;
+       }
+       if (ret == -1) {
+               printf("unable to set control 0x%8.8x: %s (%d).\n",
+                       id, strerror(errno), errno);
                return;
        }
-
-       printf("Control 0x%08x set to %u, is %u\n", id, value,
-               ctrl.value);
+       
+       printf("Control 0x%08x set to %lld, is %lld\n", id, old_val, val);
 }
 
 static int video_get_format(struct device *dev)
@@ -567,9 +631,9 @@ static void video_query_menu(struct device *dev, struct 
v4l2_queryctrl *query)
 static void video_list_controls(struct device *dev)
 {
        struct v4l2_queryctrl query;
-       struct v4l2_control ctrl;
        unsigned int nctrls = 0;
-       char value[12];
+       char value[24];
+       int64_t val64;
        int ret;
 
 #ifndef V4L2_CTRL_FLAG_NEXT_CTRL
@@ -589,18 +653,17 @@ static void video_list_controls(struct device *dev)
                if (query.flags & V4L2_CTRL_FLAG_DISABLED)
                        continue;
 
-               ctrl.id = query.id;
-               ret = ioctl(dev->fd, VIDIOC_G_CTRL, &ctrl);
-               if (ret < 0)
-                       strcpy(value, "n/a");
-               else
-                       sprintf(value, "%d", ctrl.value);
-
                if (query.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
                        printf("--- %s (class 0x%08x) ---\n", query.name, 
query.id);
                        continue;
                }
 
+               ret = get_control(dev, query.id, query.type, &val64);
+               if (ret < 0)
+                       strcpy(value, "n/a");
+               else
+                       sprintf(value, "%lld", val64);
+
                printf("control 0x%08x `%s' min %d max %d step %d default %d 
current %s.\n",
                        query.id, query.name, query.minimum, query.maximum,
                        query.step, query.default_value, value);
@@ -1401,10 +1464,17 @@ int main(int argc, char *argv[])
 
        dev.memtype = memtype;
 
-       if (do_get_control)
-               uvc_get_control(&dev, ctrl_name);
+       if (do_get_control) {
+               int64_t val;
+               ret = get_control(&dev, ctrl_name, 
+                                 get_control_type(&dev, ctrl_name), &val);
+               if (ret >= 0)
+                       printf("Control 0x%08x value %lld\n", ctrl_name, val);
+       }
+               
        if (do_set_control)
-               uvc_set_control(&dev, ctrl_name, ctrl_value);
+               set_control(&dev, ctrl_name, get_control_type(&dev, ctrl_name),
+                           ctrl_value);
 
        if (do_list_controls)
                video_list_controls(&dev);
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to