summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKieran Bingham <kieran.bingham@ideasonboard.com>2018-12-03 12:03:31 +0000
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2019-02-20 14:39:41 +0200
commit9b02433547ab823d7963d6ceb91b4330ac2c477e (patch)
tree30f6a8fac9ee9e65abd42cf45d4b5a27f6418fbf
parent4480b561404fbec790faa884d968c5291916fd55 (diff)
Add support to reset device controls
Provide a new option '--reset-controls' which will enumerate the available controls on a device or sub-device, and re-initialise them to defaults. Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--yavta.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/yavta.c b/yavta.c
index d1bfd38..1490878 100644
--- a/yavta.c
+++ b/yavta.c
@@ -527,7 +527,8 @@ static int query_control(struct device *dev, unsigned int id,
static int get_control(struct device *dev,
const struct v4l2_query_ext_ctrl *query,
- struct v4l2_ext_control *ctrl)
+ struct v4l2_ext_control *ctrl,
+ unsigned int which)
{
struct v4l2_ext_controls ctrls;
struct v4l2_control old;
@@ -536,7 +537,7 @@ static int get_control(struct device *dev,
memset(&ctrls, 0, sizeof(ctrls));
memset(ctrl, 0, sizeof(*ctrl));
- ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(query->id);
+ ctrls.which = which;
ctrls.count = 1;
ctrls.controls = ctrl;
@@ -1295,7 +1296,7 @@ static int video_get_control(struct device *dev,
printf("current ");
- ret = get_control(dev, query, &ctrl);
+ ret = get_control(dev, query, &ctrl, V4L2_CTRL_WHICH_CUR_VAL);
if (ret < 0) {
printf("n/a\n");
printf("unable to get control 0x%8.8x: %s (%d).\n",
@@ -1478,6 +1479,51 @@ static void video_list_controls(struct device *dev)
printf("No control found.\n");
}
+static int video_reset_control(struct device *dev,
+ const struct v4l2_query_ext_ctrl *query)
+{
+ struct v4l2_ext_control ctrl = { .value = query->default_value, };
+ int ret;
+
+ if (query->flags & V4L2_CTRL_FLAG_DISABLED)
+ return 0;
+
+ if (query->type == V4L2_CTRL_TYPE_CTRL_CLASS)
+ return 0;
+
+ /*
+ * For controls with payloads the default value must be retrieved with
+ * a VIDIOC_G_EXT_CTRLS call. If the V4L2_CTRL_WHICH_DEF_VAL flag isn't
+ * supported by the kernel (it got introduced in v4.5, while controls
+ * with payloads were introduced in v3.17), there isn't much we can do,
+ * so skip resetting the control.
+ */
+ if (query->flags & V4L2_CTRL_FLAG_HAS_PAYLOAD) {
+ ret = get_control(dev, query, &ctrl, V4L2_CTRL_WHICH_DEF_VAL);
+ if (ret < 0)
+ return 0;
+ }
+
+ set_control(dev, query, &ctrl);
+
+ if (query->flags & V4L2_CTRL_FLAG_HAS_PAYLOAD)
+ free(ctrl.ptr);
+
+ return 1;
+}
+
+static void video_reset_controls(struct device *dev)
+{
+ int ret;
+
+ ret = video_for_each_control(dev, video_reset_control);
+ if (ret < 0)
+ return;
+
+ if (ret)
+ printf("%u control%s reset.\n", ret, ret > 1 ? "s" : "");
+}
+
static void video_enum_frame_intervals(struct device *dev, __u32 pixelformat,
unsigned int width, unsigned int height)
{
@@ -2099,6 +2145,7 @@ static void usage(const char *argv0)
printf(" --premultiplied Color components are premultiplied by alpha value\n");
printf(" --queue-late Queue buffers after streamon, not before\n");
printf(" --requeue-last Requeue the last buffers before streamoff\n");
+ printf(" --reset-controls Reset all available controls to their default value\n");
printf(" --timestamp-source Set timestamp source on output buffers [eof, soe]\n");
printf(" --skip n Skip the first n frames\n");
printf(" --sleep-forever Sleep forever after configuring the device\n");
@@ -2121,6 +2168,7 @@ static void usage(const char *argv0)
#define OPT_PREMULTIPLIED 269
#define OPT_QUEUE_LATE 270
#define OPT_DATA_PREFIX 271
+#define OPT_RESET_CONTROLS 272
static struct option opts[] = {
{"buffer-size", 1, 0, OPT_BUFFER_SIZE},
@@ -2149,6 +2197,7 @@ static struct option opts[] = {
{"queue-late", 0, 0, OPT_QUEUE_LATE},
{"get-control", 1, 0, 'r'},
{"requeue-last", 0, 0, OPT_REQUEUE_LAST},
+ {"reset-controls", 0, 0, OPT_RESET_CONTROLS},
{"realtime", 2, 0, 'R'},
{"size", 1, 0, 's'},
{"set-control", 1, 0, 'w'},
@@ -2176,6 +2225,7 @@ int main(int argc, char *argv[])
int do_enum_formats = 0, do_set_format = 0;
int do_enum_inputs = 0, do_set_input = 0;
int do_list_controls = 0, do_get_control = 0, do_set_control = 0;
+ int do_reset_controls = 0;
int do_sleep_forever = 0, do_requeue_last = 0;
int do_rt = 0, do_log_status = 0;
int no_query = 0, do_queue_late = 0;
@@ -2364,6 +2414,9 @@ int main(int argc, char *argv[])
case OPT_QUEUE_LATE:
do_queue_late = 1;
break;
+ case OPT_RESET_CONTROLS:
+ do_reset_controls = 1;
+ break;
case OPT_REQUEUE_LAST:
do_requeue_last = 1;
break;
@@ -2449,6 +2502,9 @@ int main(int argc, char *argv[])
if (do_list_controls)
video_list_controls(&dev);
+ if (do_reset_controls)
+ video_reset_controls(&dev);
+
if (do_enum_formats) {
printf("- Available formats:\n");
video_enum_formats(&dev, V4L2_BUF_TYPE_VIDEO_CAPTURE);