Signed-off-by: Laurent Pinchart <[email protected]>
---
yavta.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 116 insertions(+), 42 deletions(-)
diff --git a/yavta.c b/yavta.c
index b9b8bb8..006bab6 100644
--- a/yavta.c
+++ b/yavta.c
@@ -416,12 +416,14 @@ static int query_control(struct device *dev, unsigned int
id,
query->id = id;
ret = ioctl(dev->fd, VIDIOC_QUERY_EXT_CTRL, query);
- if (ret < 0 && errno != EINVAL)
+ if (!ret || errno == EINVAL)
+ return ret;
+
+ if (errno != ENOTTY) {
printf("unable to query control 0x%8.8x: %s (%d).\n",
id, strerror(errno), errno);
-
- if (!ret || errno != ENOTTY)
return ret;
+ }
/*
* If VIDIOC_QUERY_EXT_CTRL isn't available emulate it using
@@ -456,6 +458,7 @@ static int get_control(struct device *dev,
struct v4l2_ext_control *ctrl)
{
struct v4l2_ext_controls ctrls;
+ struct v4l2_control old;
int ret;
memset(&ctrls, 0, sizeof(ctrls));
@@ -467,34 +470,28 @@ static int get_control(struct device *dev,
ctrl->id = query->id;
- if (query->type == V4L2_CTRL_TYPE_STRING) {
- ctrl->string = malloc(query->maximum + 1);
- if (ctrl->string == NULL)
+ if (query->flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {
+ ctrl->size = query->elems * query->elem_size;
+ ctrl->ptr = malloc(ctrl->size);
+ if (ctrl->ptr == NULL)
return -ENOMEM;
-
- ctrl->size = query->maximum + 1;
}
ret = ioctl(dev->fd, VIDIOC_G_EXT_CTRLS, &ctrls);
if (ret != -1)
return 0;
- if (query->type != V4L2_CTRL_TYPE_INTEGER64 &&
- query->type != V4L2_CTRL_TYPE_STRING &&
- (errno == EINVAL || errno == ENOTTY)) {
- struct v4l2_control old;
+ if (query->flags & V4L2_CTRL_FLAG_HAS_PAYLOAD ||
+ query->type == V4L2_CTRL_TYPE_INTEGER64 ||
+ (errno != EINVAL && errno != ENOTTY))
+ return -1;
- old.id = query->id;
- ret = ioctl(dev->fd, VIDIOC_G_CTRL, &old);
- if (ret != -1) {
- ctrl->value = old.value;
- return 0;
- }
- }
+ old.id = query->id;
+ ret = ioctl(dev->fd, VIDIOC_G_CTRL, &old);
+ if (ret != -1)
+ ctrl->value = old.value;
- printf("unable to get control 0x%8.8x: %s (%d).\n",
- query->id, strerror(errno), errno);
- return -1;
+ return ret;
}
static void set_control(struct device *dev, unsigned int id,
@@ -1087,12 +1084,75 @@ static void video_query_menu(struct device *dev,
};
}
+static void video_print_control_array(const struct v4l2_query_ext_ctrl *query,
+ struct v4l2_ext_control *ctrl)
+{
+ unsigned int i;
+
+ printf("{");
+
+ for (i = 0; i < query->elems; ++i) {
+ switch (query->type) {
+ case V4L2_CTRL_TYPE_U8:
+ printf("%u", ctrl->p_u8[i]);
+ break;
+ case V4L2_CTRL_TYPE_U16:
+ printf("%u", ctrl->p_u16[i]);
+ break;
+ case V4L2_CTRL_TYPE_U32:
+ printf("%u", ctrl->p_u32[i]);
+ break;
+ }
+
+ if (i != query->elems - 1)
+ printf(", ");
+ }
+
+ printf("}");
+}
+
+static void video_print_control_value(const struct v4l2_query_ext_ctrl *query,
+ struct v4l2_ext_control *ctrl)
+{
+ if (query->nr_of_dims == 0) {
+ switch (query->type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_INTEGER_MENU:
+ printf("%d", ctrl->value);
+ break;
+ case V4L2_CTRL_TYPE_BITMASK:
+ printf("0x%08x", ctrl->value);
+ break;
+ case V4L2_CTRL_TYPE_INTEGER64:
+ printf("%lld", ctrl->value64);
+ break;
+ case V4L2_CTRL_TYPE_STRING:
+ printf("%s", ctrl->string);
+ break;
+ }
+
+ return;
+ }
+
+ switch (query->type) {
+ case V4L2_CTRL_TYPE_U8:
+ case V4L2_CTRL_TYPE_U16:
+ case V4L2_CTRL_TYPE_U32:
+ video_print_control_array(query, ctrl);
+ break;
+ default:
+ printf("unsupported");
+ break;
+ }
+}
+
static int video_print_control(struct device *dev, unsigned int id, bool full)
{
struct v4l2_ext_control ctrl;
struct v4l2_query_ext_ctrl query;
- char sval[24];
- char *current = sval;
+ unsigned int i;
int ret;
ret = query_control(dev, id, &query);
@@ -1107,25 +1167,39 @@ static int video_print_control(struct device *dev,
unsigned int id, bool full)
return query.id;
}
- ret = get_control(dev, &query, &ctrl);
- if (ret < 0)
- strcpy(sval, "n/a");
- else if (query.type == V4L2_CTRL_TYPE_INTEGER64)
- sprintf(sval, "%lld", ctrl.value64);
- else if (query.type == V4L2_CTRL_TYPE_STRING)
- current = ctrl.string;
- else
- sprintf(sval, "%d", ctrl.value);
-
- if (full)
- printf("control 0x%08x `%s' min %lld max %lld step %lld default
%lld current %s.\n",
+ if (full) {
+ printf("control 0x%08x `%s' min %lld max %lld step %lld default
%lld ",
query.id, query.name, query.minimum, query.maximum,
- query.step, query.default_value, current);
- else
- printf("control 0x%08x current %s.\n", query.id, current);
+ query.step, query.default_value);
+ if (query.nr_of_dims) {
+ for (i = 0; i < query.nr_of_dims; ++i)
+ printf("[%u]", query.dims[i]);
+ printf(" ");
+ }
+ } else {
+ printf("control 0x%08x ", query.id);
+ }
+
+ if (query.type == V4L2_CTRL_TYPE_BUTTON) {
+ /* Button controls have no current value. */
+ printf("\n");
+ return query.id;
+ }
+
+ printf("current ");
+
+ ret = get_control(dev, &query, &ctrl);
+ if (ret < 0) {
+ printf("n/a\n");
+ printf("unable to get control 0x%8.8x: %s (%d).\n",
+ query.id, strerror(errno), errno);
+ } else {
+ video_print_control_value(&query, &ctrl);
+ printf("\n");
+ }
- if (query.type == V4L2_CTRL_TYPE_STRING)
- free(ctrl.string);
+ if ((query.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) && ctrl.ptr)
+ free(ctrl.ptr);
if (!full)
return query.id;
@@ -1151,7 +1225,7 @@ static void video_list_controls(struct device *dev)
#else
id = 0;
while (1) {
- id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+ id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
#endif
ret = video_print_control(dev, id, true);
--
2.0.4
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html