linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] yavta: Implement compound controls support
@ 2016-05-16 10:02 Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 1/4] Implement VIDIOC_QUERY_EXT_CTRL support Laurent Pinchart
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Laurent Pinchart @ 2016-05-16 10:02 UTC (permalink / raw)
  To: sakari.ailus; +Cc: linux-media

Hello,

This series implements compound controls support for yavta. The support is
currently limited to (multidimensional) arrays of integer types, and will be
extended later as needed.

One point worth noting is patch 4/4 that adds support for setting a control to
a value stored in a file. This is particularly useful for large array controls
as specifying the control value on the command line would be cumbersome.

Laurent Pinchart (4):
  Implement VIDIOC_QUERY_EXT_CTRL support
  Implement compound control get support
  Implement compound control set support
  Support setting control from values stored in a file

 yavta.c | 438 +++++++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 340 insertions(+), 98 deletions(-)

-- 
Regards,

Laurent Pinchart


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] Implement VIDIOC_QUERY_EXT_CTRL support
  2016-05-16 10:02 [PATCH 0/4] yavta: Implement compound controls support Laurent Pinchart
@ 2016-05-16 10:02 ` Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 2/4] Implement compound control get support Laurent Pinchart
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Laurent Pinchart @ 2016-05-16 10:02 UTC (permalink / raw)
  To: sakari.ailus; +Cc: linux-media

Use the new extended control query ioctl when available with an
automatic fall back to VIDIOC_QUERYCTRL.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 yavta.c | 47 +++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 39 insertions(+), 8 deletions(-)

diff --git a/yavta.c b/yavta.c
index 9b8b8998e0dc..af565245f87b 100644
--- a/yavta.c
+++ b/yavta.c
@@ -429,22 +429,52 @@ static void video_log_status(struct device *dev)
 }
 
 static int query_control(struct device *dev, unsigned int id,
-			 struct v4l2_queryctrl *query)
+			 struct v4l2_query_ext_ctrl *query)
 {
+	struct v4l2_queryctrl q;
 	int ret;
 
 	memset(query, 0, sizeof(*query));
 	query->id = id;
 
-	ret = ioctl(dev->fd, VIDIOC_QUERYCTRL, query);
+	ret = ioctl(dev->fd, VIDIOC_QUERY_EXT_CTRL, query);
 	if (ret < 0 && errno != EINVAL)
 		printf("unable to query control 0x%8.8x: %s (%d).\n",
 		       id, strerror(errno), errno);
 
-	return ret;
+	if (!ret || errno != ENOTTY)
+		return ret;
+
+	/*
+	 * If VIDIOC_QUERY_EXT_CTRL isn't available emulate it using
+	 * VIDIOC_QUERYCTRL.
+	 */
+	memset(&q, 0, sizeof(q));
+	q.id = id;
+
+	ret = ioctl(dev->fd, VIDIOC_QUERYCTRL, &q);
+	if (ret < 0) {
+		if (errno != EINVAL)
+			printf("unable to query control 0x%8.8x: %s (%d).\n",
+			       id, strerror(errno), errno);
+		return ret;
+	}
+
+	memset(query, 0, sizeof(*query));
+	query->id = q.id;
+	query->type = q.type;
+	memcpy(query->name, q.name, sizeof(query->name));
+	query->minimum = q.minimum;
+	query->maximum = q.maximum;
+	query->step = q.step;
+	query->default_value = q.default_value;
+	query->flags = q.flags;
+
+	return 0;
 }
 
-static int get_control(struct device *dev, const struct v4l2_queryctrl *query,
+static int get_control(struct device *dev,
+		       const struct v4l2_query_ext_ctrl *query,
 		       struct v4l2_ext_control *ctrl)
 {
 	struct v4l2_ext_controls ctrls;
@@ -494,7 +524,7 @@ static void set_control(struct device *dev, unsigned int id,
 {
 	struct v4l2_ext_controls ctrls;
 	struct v4l2_ext_control ctrl;
-	struct v4l2_queryctrl query;
+	struct v4l2_query_ext_ctrl query;
 	int64_t old_val = val;
 	int is_64;
 	int ret;
@@ -1058,7 +1088,8 @@ static int video_enable(struct device *dev, int enable)
 	return 0;
 }
 
-static void video_query_menu(struct device *dev, struct v4l2_queryctrl *query,
+static void video_query_menu(struct device *dev,
+			     struct v4l2_query_ext_ctrl *query,
 			     unsigned int value)
 {
 	struct v4l2_querymenu menu;
@@ -1083,7 +1114,7 @@ static void video_query_menu(struct device *dev, struct v4l2_queryctrl *query,
 static int video_print_control(struct device *dev, unsigned int id, bool full)
 {
 	struct v4l2_ext_control ctrl;
-	struct v4l2_queryctrl query;
+	struct v4l2_query_ext_ctrl query;
 	char sval[24];
 	char *current = sval;
 	int ret;
@@ -1111,7 +1142,7 @@ static int video_print_control(struct device *dev, unsigned int id, bool full)
 		sprintf(sval, "%d", ctrl.value);
 
 	if (full)
-		printf("control 0x%08x `%s' min %d max %d step %d default %d current %s.\n",
+		printf("control 0x%08x `%s' min %lld max %lld step %lld default %lld current %s.\n",
 			query.id, query.name, query.minimum, query.maximum,
 			query.step, query.default_value, current);
 	else
-- 
2.7.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] Implement compound control get support
  2016-05-16 10:02 [PATCH 0/4] yavta: Implement compound controls support Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 1/4] Implement VIDIOC_QUERY_EXT_CTRL support Laurent Pinchart
@ 2016-05-16 10:02 ` Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 3/4] Implement compound control set support Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 4/4] Support setting control from values stored in a file Laurent Pinchart
  3 siblings, 0 replies; 6+ messages in thread
From: Laurent Pinchart @ 2016-05-16 10:02 UTC (permalink / raw)
  To: sakari.ailus; +Cc: linux-media

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 yavta.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++-----------------
 1 file changed, 116 insertions(+), 42 deletions(-)

diff --git a/yavta.c b/yavta.c
index af565245f87b..360c53fc77c5 100644
--- a/yavta.c
+++ b/yavta.c
@@ -438,12 +438,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
@@ -478,6 +480,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));
@@ -489,34 +492,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,
@@ -1111,12 +1108,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);
@@ -1131,25 +1191,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;
@@ -1175,7 +1249,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.7.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] Implement compound control set support
  2016-05-16 10:02 [PATCH 0/4] yavta: Implement compound controls support Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 1/4] Implement VIDIOC_QUERY_EXT_CTRL support Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 2/4] Implement compound control get support Laurent Pinchart
@ 2016-05-16 10:02 ` Laurent Pinchart
  2016-05-16 10:02 ` [PATCH 4/4] Support setting control from values stored in a file Laurent Pinchart
  3 siblings, 0 replies; 6+ messages in thread
From: Laurent Pinchart @ 2016-05-16 10:02 UTC (permalink / raw)
  To: sakari.ailus; +Cc: linux-media

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 yavta.c | 217 ++++++++++++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 165 insertions(+), 52 deletions(-)

diff --git a/yavta.c b/yavta.c
index 360c53fc77c5..4b531a0360fe 100644
--- a/yavta.c
+++ b/yavta.c
@@ -19,6 +19,7 @@
 
 #define __STDC_FORMAT_MACROS
 
+#include <ctype.h>
 #include <stdio.h>
 #include <string.h>
 #include <fcntl.h>
@@ -516,59 +517,38 @@ static int get_control(struct device *dev,
 	return ret;
 }
 
-static void set_control(struct device *dev, unsigned int id,
-		        int64_t val)
+static int set_control(struct device *dev,
+		       const struct v4l2_query_ext_ctrl *query,
+		       struct v4l2_ext_control *ctrl)
 {
 	struct v4l2_ext_controls ctrls;
-	struct v4l2_ext_control ctrl;
-	struct v4l2_query_ext_ctrl query;
-	int64_t old_val = val;
-	int is_64;
+	struct v4l2_control old;
 	int ret;
 
-	ret = query_control(dev, id, &query);
-	if (ret < 0)
-		return;
-
-	is_64 = query.type == V4L2_CTRL_TYPE_INTEGER64;
-
 	memset(&ctrls, 0, sizeof(ctrls));
-	memset(&ctrl, 0, sizeof(ctrl));
 
-	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(id);
+	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl->id);
 	ctrls.count = 1;
-	ctrls.controls = &ctrl;
+	ctrls.controls = ctrl;
 
-	ctrl.id = id;
-	if (is_64)
-		ctrl.value64 = val;
-	else
-		ctrl.value = val;
+	ctrl->id = query->id;
 
 	ret = ioctl(dev->fd, VIDIOC_S_EXT_CTRLS, &ctrls);
-	if (ret != -1) {
-		if (is_64)
-			val = ctrl.value64;
-		else
-			val = ctrl.value;
-	} else if (!is_64 && query.type != V4L2_CTRL_TYPE_STRING &&
-		   (errno == EINVAL || errno == ENOTTY)) {
-		struct v4l2_control old;
-
-		old.id = id;
-		old.value = val;
-		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;
-	}
+	if (ret != -1)
+		return 0;
 
-	printf("Control 0x%08x set to %" PRId64 ", is %" PRId64 "\n",
-	       id, old_val, val);
+	if (query->flags & V4L2_CTRL_FLAG_HAS_PAYLOAD ||
+	    query->type == V4L2_CTRL_TYPE_INTEGER64 ||
+	    (errno != EINVAL && errno != ENOTTY))
+		return -1;
+
+	old.id = ctrl->id;
+	old.value = ctrl->value;
+	ret = ioctl(dev->fd, VIDIOC_S_CTRL, &old);
+	if (ret != -1)
+		ctrl->value = old.value;
+
+	return ret;
 }
 
 static int video_get_format(struct device *dev)
@@ -1172,7 +1152,7 @@ static void video_print_control_value(const struct v4l2_query_ext_ctrl *query,
 	}
 }
 
-static int video_print_control(struct device *dev, unsigned int id, bool full)
+static int video_get_control(struct device *dev, unsigned int id, bool full)
 {
 	struct v4l2_ext_control ctrl;
 	struct v4l2_query_ext_ctrl query;
@@ -1235,6 +1215,143 @@ static int video_print_control(struct device *dev, unsigned int id, bool full)
 	return query.id;
 }
 
+static int video_parse_control_array(const struct v4l2_query_ext_ctrl *query,
+				     struct v4l2_ext_control *ctrl,
+				     const char *val)
+{
+	unsigned int i;
+	char *endptr;
+	__u32 value;
+
+	for ( ; isspace(*val); ++val) { };
+
+	if (*val++ != '{')
+		return -EINVAL;
+
+	for (i = 0; i < query->elems; ++i) {
+		for ( ; isspace(*val); ++val) { };
+
+		switch (query->type) {
+		case V4L2_CTRL_TYPE_U8:
+		case V4L2_CTRL_TYPE_U16:
+		case V4L2_CTRL_TYPE_U32:
+		default:
+			value = strtoul(val, &endptr, 0);
+			break;
+		}
+
+		if (endptr == NULL)
+			return -EINVAL;
+
+		switch (query->type) {
+		case V4L2_CTRL_TYPE_U8:
+			ctrl->p_u8[i] = value;
+			break;
+		case V4L2_CTRL_TYPE_U16:
+			ctrl->p_u16[i] = value;
+			break;
+		case V4L2_CTRL_TYPE_U32:
+			ctrl->p_u32[i] = value;
+			break;
+		}
+
+		val = endptr;
+		for ( ; isspace(*val); ++val) { };
+
+		if (i != query->elems - 1) {
+			if (*val++ != ',')
+				return -EINVAL;
+			for ( ; isspace(*val); ++val) { };
+		}
+	}
+
+	if (*val++ != '}')
+		return -EINVAL;
+
+	return 0;
+}
+
+static void video_set_control(struct device *dev, unsigned int id,
+			      const char *val)
+{
+	struct v4l2_query_ext_ctrl query;
+	struct v4l2_ext_control ctrl;
+	char *endptr;
+	int ret;
+
+	ret = query_control(dev, id, &query);
+	if (ret < 0)
+		return;
+
+	memset(&ctrl, 0, sizeof(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:
+		case V4L2_CTRL_TYPE_BITMASK:
+			ctrl.value = strtol(val, &endptr, 0);
+			if (*endptr != 0) {
+				printf("Invalid control value '%s'\n", val);
+				return;
+			}
+			break;
+		case V4L2_CTRL_TYPE_INTEGER64:
+			ctrl.value64 = strtoll(val, &endptr, 0);
+			if (*endptr != 0) {
+				printf("Invalid control value '%s'\n", val);
+				return;
+			}
+			break;
+		case V4L2_CTRL_TYPE_STRING:
+			ctrl.size = query.elem_size;
+			ctrl.ptr = malloc(ctrl.size);
+			if (ctrl.ptr == NULL)
+				return;
+			strncpy(ctrl.string, val, ctrl.size);
+			break;
+		default:
+			printf("Unsupported control type\n");
+			return;
+		}
+	} else {
+		switch (query.type) {
+		case V4L2_CTRL_TYPE_U8:
+		case V4L2_CTRL_TYPE_U16:
+		case V4L2_CTRL_TYPE_U32:
+			ctrl.size = query.elem_size * query.elems;
+			ctrl.ptr = malloc(ctrl.size);
+			if (ctrl.ptr == NULL)
+				return;
+			ret = video_parse_control_array(&query, &ctrl, val);
+			if (ret < 0) {
+				printf("Invalid compound control value '%s'\n", val);
+				return;
+			}
+			break;
+		default:
+			printf("Unsupported control type\n");
+			break;
+		}
+	}
+
+	ret = set_control(dev, &query, &ctrl);
+	if (ret < 0) {
+		printf("unable to set control 0x%8.8x: %s (%d).\n",
+			id, strerror(errno), errno);
+	} else {
+		printf("Control 0x%08x set to %s, is ", id, val);
+
+		video_print_control_value(&query, &ctrl);
+		printf("\n");
+	}
+
+	if ((query.flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) && ctrl.ptr)
+		free(ctrl.ptr);
+}
+
 static void video_list_controls(struct device *dev)
 {
 	unsigned int nctrls = 0;
@@ -1252,7 +1369,7 @@ static void video_list_controls(struct device *dev)
 		id |= V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND;
 #endif
 
-		ret = video_print_control(dev, id, true);
+		ret = video_get_control(dev, id, true);
 		if (ret < 0)
 			break;
 
@@ -1972,7 +2089,7 @@ int main(int argc, char *argv[])
 
 	/* Controls */
 	int ctrl_name = 0;
-	int ctrl_value = 0;
+	const char *ctrl_value = NULL;
 
 	/* Video buffers */
 	enum v4l2_memory memtype = V4L2_MEMORY_MMAP;
@@ -2112,11 +2229,7 @@ int main(int argc, char *argv[])
 				printf("Invalid control name '%s'\n", optarg);
 				return 1;
 			}
-			ctrl_value = strtol(endptr + 1, &endptr, 0);
-			if (*endptr != 0) {
-				printf("Invalid control value '%s'\n", optarg);
-				return 1;
-			}
+			ctrl_value = endptr + 1;
 			do_set_control = 1;
 			break;
 		case OPT_BUFFER_SIZE:
@@ -2228,10 +2341,10 @@ int main(int argc, char *argv[])
 		video_log_status(&dev);
 
 	if (do_get_control)
-		video_print_control(&dev, ctrl_name, false);
+		video_get_control(&dev, ctrl_name, false);
 
 	if (do_set_control)
-		set_control(&dev, ctrl_name, ctrl_value);
+		video_set_control(&dev, ctrl_name, ctrl_value);
 
 	if (do_list_controls)
 		video_list_controls(&dev);
-- 
2.7.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] Support setting control from values stored in a file
  2016-05-16 10:02 [PATCH 0/4] yavta: Implement compound controls support Laurent Pinchart
                   ` (2 preceding siblings ...)
  2016-05-16 10:02 ` [PATCH 3/4] Implement compound control set support Laurent Pinchart
@ 2016-05-16 10:02 ` Laurent Pinchart
  2016-05-17  9:06   ` Sakari Ailus
  3 siblings, 1 reply; 6+ messages in thread
From: Laurent Pinchart @ 2016-05-16 10:02 UTC (permalink / raw)
  To: sakari.ailus; +Cc: linux-media

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 yavta.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/yavta.c b/yavta.c
index 4b531a0360fe..d0bcf7f19c7b 100644
--- a/yavta.c
+++ b/yavta.c
@@ -1225,6 +1225,30 @@ static int video_parse_control_array(const struct v4l2_query_ext_ctrl *query,
 
 	for ( ; isspace(*val); ++val) { };
 
+	if (*val == '<') {
+		/* Read the control value from the given file. */
+		ssize_t size;
+		int fd;
+
+		val++;
+		fd = open(val, O_RDONLY);
+		if (fd < 0) {
+			printf("unable to open control file `%s'\n", val);
+			return -EINVAL;
+		}
+
+		size = read(fd, ctrl->ptr, ctrl->size);
+		if (size != (ssize_t)ctrl->size) {
+			printf("error reading control file `%s' (%s)\n", val,
+			       strerror(errno));
+			close(fd);
+			return -EINVAL;
+		}
+
+		close(fd);
+		return 0;
+	}
+
 	if (*val++ != '{')
 		return -EINVAL;
 
-- 
2.7.3


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/4] Support setting control from values stored in a file
  2016-05-16 10:02 ` [PATCH 4/4] Support setting control from values stored in a file Laurent Pinchart
@ 2016-05-17  9:06   ` Sakari Ailus
  0 siblings, 0 replies; 6+ messages in thread
From: Sakari Ailus @ 2016-05-17  9:06 UTC (permalink / raw)
  To: Laurent Pinchart; +Cc: linux-media

Hi Laurent,

Thanks for the set!

On Mon, May 16, 2016 at 01:02:12PM +0300, Laurent Pinchart wrote:
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  yavta.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/yavta.c b/yavta.c
> index 4b531a0360fe..d0bcf7f19c7b 100644
> --- a/yavta.c
> +++ b/yavta.c
> @@ -1225,6 +1225,30 @@ static int video_parse_control_array(const struct v4l2_query_ext_ctrl *query,
>  
>  	for ( ; isspace(*val); ++val) { };
>  
> +	if (*val == '<') {
> +		/* Read the control value from the given file. */
> +		ssize_t size;
> +		int fd;
> +
> +		val++;
> +		fd = open(val, O_RDONLY);
> +		if (fd < 0) {
> +			printf("unable to open control file `%s'\n", val);
> +			return -EINVAL;
> +		}
> +
> +		size = read(fd, ctrl->ptr, ctrl->size);
> +		if (size != (ssize_t)ctrl->size) {
> +			printf("error reading control file `%s' (%s)\n", val,
> +			       strerror(errno));
> +			close(fd);
> +			return -EINVAL;
> +		}
> +
> +		close(fd);
> +		return 0;
> +	}
> +
>  	if (*val++ != '{')
>  		return -EINVAL;
>  

How about adding a new command line option to read the value from a file? I
think that'd be cleaner. I'd also add support for writing binary values to a
file, that would be quite convenient. Write support could be done later as
well.

For patches 1--3:

Acked-by: Sakari Ailus <sakari.ailus@linux.intel.com>

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	XMPP: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2016-05-17  9:07 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-16 10:02 [PATCH 0/4] yavta: Implement compound controls support Laurent Pinchart
2016-05-16 10:02 ` [PATCH 1/4] Implement VIDIOC_QUERY_EXT_CTRL support Laurent Pinchart
2016-05-16 10:02 ` [PATCH 2/4] Implement compound control get support Laurent Pinchart
2016-05-16 10:02 ` [PATCH 3/4] Implement compound control set support Laurent Pinchart
2016-05-16 10:02 ` [PATCH 4/4] Support setting control from values stored in a file Laurent Pinchart
2016-05-17  9:06   ` Sakari Ailus

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).