summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSakari Ailus <sakari.ailus@iki.fi>2012-04-13 23:34:21 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-04-16 19:44:16 +0200
commit82ff2efdb9787737b9f21b6f4759f077c827b238 (patch)
tree2350d0869dd5c0cde3b24977f7f6e0dc6e557d29
parenta0b9478e8d78c219367564ab25512a982101a152 (diff)
Support extended controls, including 64-bit integers
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.ailus@iki.fi> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--yavta.c132
1 files changed, 103 insertions, 29 deletions
diff --git a/yavta.c b/yavta.c
index 3226fa5..f3deae0 100644
--- a/yavta.c
+++ b/yavta.c
@@ -17,9 +17,12 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
*/
+#define __STDC_FORMAT_MACROS
+
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdint.h>
@@ -227,40 +230,105 @@ 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_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_control ctrl;
+ 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;
- printf("Control 0x%08x value %u\n", id, ctrl.value);
+ old.id = id;
+ ret = ioctl(dev->fd, VIDIOC_G_CTRL, &old);
+ if (ret != -1) {
+ *val = old.value;
+ return 0;
+ }
+ }
+
+ 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 %" PRId64 ", is %" PRId64 "\n",
+ id, old_val, val);
}
static int video_get_format(struct device *dev)
@@ -564,9 +632,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
@@ -586,18 +654,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, "%" PRId64, 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);
@@ -1398,10 +1465,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 %" PRId64 "\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);