* [v4l-utils] Add options to v4l2-ctrl to save/load settings to/from a file @ 2018-11-24 17:52 Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite 0 siblings, 1 reply; 11+ messages in thread From: Antonio Ospite @ 2018-11-24 17:52 UTC (permalink / raw) To: linux-media Hi, AFAIK every time a new v4l device is initialized (e.g. USB webcam plugged in) the driver sets the controls to the default value decided by the author in the source code. It is then the responsibility of each v4l2 applications to save and restore any variation to the controls values made by the user if this is required. I was looking for a more generic way to set some controls to non-default values in a more persistent way, my main use case is to avoid *manually* setting "Power Line Frequency" to 50Hz every time I plug in the webcam. Something like what alsactrl[0] does with mixer settings. Maybe pipewire will do that? In the mean time, inspired by [1] I cleaned up the concept and published it as v4l2-persistent-settings[2], the idea is that the user can save the current state of a device and it would be restored automatically via a udev rule the next time the device is initialized. For that, the current device state has to be stored into a file. For now I am massaging the output of "v4l2-ctl -l", saving that to a file, and then parsing the file to generate something I can pass to "v4l2-ctl --set-ctrl"; however it would be handier if v4l2-ctl had a native mechanism to export and import settings. v4l2ctrl from v4l2ucp[3] has options to save settings to a file and reload them from a file, but I would like to use v4l2-ctl instead which is actively maintained. What about adding such options to v4l2-ctl? Thank you, Antonio [0] http://git.alsa-project.org/?p=alsa-utils.git;a=tree;f=alsactl;hb=HEAD [1] https://superuser.com/questions/471597/linux-v4l-webcam-make-settings-stick [2] https://git.ao2.it/v4l2-persistent-settings.git/ [3] https://sourceforge.net/projects/v4l2ucp/ -- Antonio Ospite https://ao2.it https://twitter.com/ao2it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? ^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format 2018-11-24 17:52 [v4l-utils] Add options to v4l2-ctrl to save/load settings to/from a file Antonio Ospite @ 2019-01-03 18:00 ` Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 1/5] v4l2-ctl: list controls with menus when OptAll is specified Antonio Ospite ` (5 more replies) 0 siblings, 6 replies; 11+ messages in thread From: Antonio Ospite @ 2019-01-03 18:00 UTC (permalink / raw) To: linux-media; +Cc: Antonio Ospite Hi, here is an experiment about listing controls values with v4l2-ctl in a way that makes it more easy to reload them, I would use something like that for https://git.ao2.it/v4l2-persistent-settings.git/ Patches 1 and 2 are just warm-up patches to get me familiar again with the v4l2-ctrl codebase, patch 2 is a small preparatory cleanup, and patches 4 and 5 showcase the idea. Thanks, Antonio Antonio Ospite (5): v4l2-ctl: list controls with menus when OptAll is specified v4l2-ctl: list once when both OptListCtrls and OptListCtrlsMenus are there v4l2-ctl: use a dedicated function to print the control class name v4l2-ctl: abstract the mechanism used to print the list of controls v4l2-ctl: add an option to list controls in a machine-readable format utils/v4l2-ctl/v4l2-ctl-common.cpp | 95 +++++++++++++++++++++++++----- utils/v4l2-ctl/v4l2-ctl.1.in | 4 ++ utils/v4l2-ctl/v4l2-ctl.cpp | 3 +- utils/v4l2-ctl/v4l2-ctl.h | 1 + 4 files changed, 88 insertions(+), 15 deletions(-) -- Antonio Ospite https://ao2.it https://twitter.com/ao2it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? ^ permalink raw reply [flat|nested] 11+ messages in thread
* [RFC PATCH 1/5] v4l2-ctl: list controls with menus when OptAll is specified 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite @ 2019-01-03 18:00 ` Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 2/5] v4l2-ctl: list once when both OptListCtrls and OptListCtrlsMenus are there Antonio Ospite ` (4 subsequent siblings) 5 siblings, 0 replies; 11+ messages in thread From: Antonio Ospite @ 2019-01-03 18:00 UTC (permalink / raw) To: linux-media; +Cc: Antonio Ospite When calling "v4l2-ctl --all" the user may expect the most comprehensive output, so also print the menus when listing controls. Signed-off-by: Antonio Ospite <ao2@ao2.it> --- utils/v4l2-ctl/v4l2-ctl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index 8c52c7be..a65262f6 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -1255,7 +1255,7 @@ int main(int argc, char **argv) options[OptGetPriority] = 1; options[OptGetSelection] = 1; options[OptGetOutputSelection] = 1; - options[OptListCtrls] = 1; + options[OptListCtrlsMenus] = 1; options[OptSilent] = 1; } -- 2.20.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 2/5] v4l2-ctl: list once when both OptListCtrls and OptListCtrlsMenus are there 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 1/5] v4l2-ctl: list controls with menus when OptAll is specified Antonio Ospite @ 2019-01-03 18:00 ` Antonio Ospite 2019-01-03 18:01 ` [RFC PATCH 3/5] v4l2-ctl: use a dedicated function to print the control class name Antonio Ospite ` (3 subsequent siblings) 5 siblings, 0 replies; 11+ messages in thread From: Antonio Ospite @ 2019-01-03 18:00 UTC (permalink / raw) To: linux-media; +Cc: Antonio Ospite When both --list-ctrls and --list-ctrls-menus are passed, controls are listed twice which is accurate but can be confusing. Treat --list-ctrls-menus as an option modifier when also --list-ctrls is passed, in order to have the controls listed only once. Signed-off-by: Antonio Ospite <ao2@ao2.it> --- utils/v4l2-ctl/v4l2-ctl-common.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp index 8256cbd9..e2710335 100644 --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp @@ -1091,11 +1091,7 @@ void common_get(cv4l_fd &_fd) void common_list(cv4l_fd &fd) { - if (options[OptListCtrlsMenus]) { - list_controls(fd.g_fd(), 1); - } - - if (options[OptListCtrls]) { - list_controls(fd.g_fd(), 0); + if (options[OptListCtrls] || options[OptListCtrlsMenus]) { + list_controls(fd.g_fd(), options[OptListCtrlsMenus]); } } -- 2.20.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 3/5] v4l2-ctl: use a dedicated function to print the control class name 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 1/5] v4l2-ctl: list controls with menus when OptAll is specified Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 2/5] v4l2-ctl: list once when both OptListCtrls and OptListCtrlsMenus are there Antonio Ospite @ 2019-01-03 18:01 ` Antonio Ospite 2019-01-03 18:01 ` [RFC PATCH 4/5] v4l2-ctl: abstract the mechanism used to print the list of controls Antonio Ospite ` (2 subsequent siblings) 5 siblings, 0 replies; 11+ messages in thread From: Antonio Ospite @ 2019-01-03 18:01 UTC (permalink / raw) To: linux-media; +Cc: Antonio Ospite All the details about the controls are printed in the dedicated function print_qctrl(), use a new dedicated function named print_class_name() to print the control class name as well, this is for symmetry but it is also in preparation for a change which aims to abstract how the controls are printed. Signed-off-by: Antonio Ospite <ao2@ao2.it> --- utils/v4l2-ctl/v4l2-ctl-common.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp index e2710335..5d41d720 100644 --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp @@ -403,6 +403,11 @@ static void print_qctrl(int fd, struct v4l2_query_ext_ctrl *queryctrl, } } +static void print_class_name(const char *name) +{ + printf("\n%s\n\n", name); +} + static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, int show_menus) { struct v4l2_control ctrl; @@ -415,7 +420,7 @@ static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, int show_men if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) return 1; if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) { - printf("\n%s\n\n", qctrl.name); + print_class_name(qctrl.name); return 1; } ext_ctrl.id = qctrl.id; -- 2.20.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 4/5] v4l2-ctl: abstract the mechanism used to print the list of controls 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite ` (2 preceding siblings ...) 2019-01-03 18:01 ` [RFC PATCH 3/5] v4l2-ctl: use a dedicated function to print the control class name Antonio Ospite @ 2019-01-03 18:01 ` Antonio Ospite 2019-01-03 18:01 ` [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format Antonio Ospite 2019-01-07 10:21 ` [RFC PATCH 0/5] v4l2-ctl: list controls values " Hans Verkuil 5 siblings, 0 replies; 11+ messages in thread From: Antonio Ospite @ 2019-01-03 18:01 UTC (permalink / raw) To: linux-media; +Cc: Antonio Ospite Sometimes it may be useful to list the controls using a different output format than the current one used by --list-ctrls, for instance a new printing format could output a string which can be later fed to --set-ctrl. Add an abstraction mechanism to make it possible to add new output formats for controls. Signed-off-by: Antonio Ospite <ao2@ao2.it> --- utils/v4l2-ctl/v4l2-ctl-common.cpp | 32 ++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp index 5d41d720..7777b45c 100644 --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp @@ -30,6 +30,12 @@ struct ctrl_subset { unsigned size[V4L2_CTRL_MAX_DIMS]; }; +struct print_format { + void (*print_class_name)(const char *); + void (*print_qctrl)(int, struct v4l2_query_ext_ctrl *, struct v4l2_ext_control *, int); + int show_menus; +}; + typedef std::map<unsigned, std::vector<struct v4l2_ext_control> > class2ctrls_map; typedef std::map<std::string, struct v4l2_query_ext_ctrl> ctrl_qmap; @@ -408,7 +414,7 @@ static void print_class_name(const char *name) printf("\n%s\n\n", name); } -static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, int show_menus) +static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, struct print_format *format) { struct v4l2_control ctrl; struct v4l2_ext_control ext_ctrl; @@ -420,17 +426,17 @@ static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, int show_men if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) return 1; if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) { - print_class_name(qctrl.name); + format->print_class_name(qctrl.name); return 1; } ext_ctrl.id = qctrl.id; if ((qctrl.flags & V4L2_CTRL_FLAG_WRITE_ONLY) || qctrl.type == V4L2_CTRL_TYPE_BUTTON) { - print_qctrl(fd, &qctrl, &ext_ctrl, show_menus); + format->print_qctrl(fd, &qctrl, &ext_ctrl, format->show_menus); return 1; } if (qctrl.type >= V4L2_CTRL_COMPOUND_TYPES) { - print_qctrl(fd, &qctrl, NULL, show_menus); + format->print_qctrl(fd, &qctrl, NULL, format->show_menus); return 1; } ctrls.which = V4L2_CTRL_ID2WHICH(qctrl.id); @@ -460,7 +466,7 @@ static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, int show_men } ext_ctrl.value = ctrl.value; } - print_qctrl(fd, &qctrl, &ext_ctrl, show_menus); + format->print_qctrl(fd, &qctrl, &ext_ctrl, format->show_menus); if (qctrl.type == V4L2_CTRL_TYPE_STRING) free(ext_ctrl.string); return 1; @@ -512,7 +518,7 @@ static int query_ext_ctrl_ioctl(int fd, struct v4l2_query_ext_ctrl &qctrl) return rc; } -static void list_controls(int fd, int show_menus) +static void list_controls(int fd, struct print_format *format) { const unsigned next_fl = V4L2_CTRL_FLAG_NEXT_CTRL | V4L2_CTRL_FLAG_NEXT_COMPOUND; struct v4l2_query_ext_ctrl qctrl; @@ -521,7 +527,7 @@ static void list_controls(int fd, int show_menus) memset(&qctrl, 0, sizeof(qctrl)); qctrl.id = next_fl; while (query_ext_ctrl_ioctl(fd, qctrl) == 0) { - print_control(fd, qctrl, show_menus); + print_control(fd, qctrl, format); qctrl.id |= next_fl; } if (qctrl.id != next_fl) @@ -529,11 +535,11 @@ static void list_controls(int fd, int show_menus) for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) { qctrl.id = id; if (query_ext_ctrl_ioctl(fd, qctrl) == 0) - print_control(fd, qctrl, show_menus); + print_control(fd, qctrl, format); } for (qctrl.id = V4L2_CID_PRIVATE_BASE; query_ext_ctrl_ioctl(fd, qctrl) == 0; qctrl.id++) { - print_control(fd, qctrl, show_menus); + print_control(fd, qctrl, format); } } @@ -1097,6 +1103,12 @@ void common_get(cv4l_fd &_fd) void common_list(cv4l_fd &fd) { if (options[OptListCtrls] || options[OptListCtrlsMenus]) { - list_controls(fd.g_fd(), options[OptListCtrlsMenus]); + struct print_format classic_format = { + .print_class_name = print_class_name, + .print_qctrl = print_qctrl, + .show_menus = options[OptListCtrlsMenus], + }; + + list_controls(fd.g_fd(), &classic_format); } } -- 2.20.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite ` (3 preceding siblings ...) 2019-01-03 18:01 ` [RFC PATCH 4/5] v4l2-ctl: abstract the mechanism used to print the list of controls Antonio Ospite @ 2019-01-03 18:01 ` Antonio Ospite 2019-01-07 10:18 ` Hans Verkuil 2019-01-07 10:21 ` [RFC PATCH 0/5] v4l2-ctl: list controls values " Hans Verkuil 5 siblings, 1 reply; 11+ messages in thread From: Antonio Ospite @ 2019-01-03 18:01 UTC (permalink / raw) To: linux-media; +Cc: Antonio Ospite Add a new option --list-ctrls-values to list the values of controls in a format which can be passed again to --set-ctrl. This can be useful to save and restore device settings: $ v4l2-ctl --list-ctrls-values >settings.txt 2>/dev/null $ v4l2-ctl --set-ctrl "$(cat settings.txt)" The new option has been tested with the vivid driver and it works well enough to be useful with a real driver as well. String controls are not supported for now, as they may not be parsed correctly by --set-ctrl if they contain a comma or a single quote. Signed-off-by: Antonio Ospite <ao2@ao2.it> --- utils/v4l2-ctl/v4l2-ctl-common.cpp | 72 ++++++++++++++++++++++++++---- utils/v4l2-ctl/v4l2-ctl.1.in | 4 ++ utils/v4l2-ctl/v4l2-ctl.cpp | 1 + utils/v4l2-ctl/v4l2-ctl.h | 1 + 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp index 7777b45c..b4124608 100644 --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp @@ -93,6 +93,9 @@ void common_usage(void) " -l, --list-ctrls display all controls and their values [VIDIOC_QUERYCTRL]\n" " -L, --list-ctrls-menus\n" " display all controls and their menus [VIDIOC_QUERYMENU]\n" + " -m, --list-ctrls-values\n" + " display all controls and their values in a format compatible with\n" + " --set-ctrls (the 'm' stands for \"machine readable output\")\n" " -r, --subset <ctrl>[,<offset>,<size>]+\n" " the subset of the N-dimensional array to get/set for control <ctrl>,\n" " for every dimension an (<offset>, <size>) tuple is given.\n" @@ -409,6 +412,46 @@ static void print_qctrl(int fd, struct v4l2_query_ext_ctrl *queryctrl, } } +static void print_qctrl_values(int fd, struct v4l2_query_ext_ctrl *queryctrl, + struct v4l2_ext_control *ctrl, int show_menus) +{ + std::string s = name2var(queryctrl->name); + + if (queryctrl->nr_of_dims == 0) { + switch (queryctrl->type) { + case V4L2_CTRL_TYPE_INTEGER: + case V4L2_CTRL_TYPE_BOOLEAN: + case V4L2_CTRL_TYPE_MENU: + case V4L2_CTRL_TYPE_INTEGER_MENU: + printf("%s=%d,", s.c_str(), ctrl->value); + break; + case V4L2_CTRL_TYPE_BITMASK: + printf("%s=0x%08x,", s.c_str(), ctrl->value); + break; + case V4L2_CTRL_TYPE_INTEGER64: + printf("%s=%lld,", s.c_str(), ctrl->value64); + break; + case V4L2_CTRL_TYPE_STRING: + fprintf(stderr, "%s: string controls unsupported for now\n", queryctrl->name); + break; + default: + fprintf(stderr, "%s: unsupported payload type\n", queryctrl->name); + break; + } + } + + if (queryctrl->nr_of_dims) + fprintf(stderr, "%s: unsupported payload type (multi-dimensional)\n", queryctrl->name); + + if (queryctrl->flags) + fprintf(stderr, "%s: ignoring flags\n", queryctrl->name); + + if ((queryctrl->type == V4L2_CTRL_TYPE_MENU || + queryctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) && show_menus) { + fprintf(stderr, "%s: ignoring menus\n", queryctrl->name); + } +} + static void print_class_name(const char *name) { printf("\n%s\n\n", name); @@ -426,7 +469,8 @@ static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, struct print if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) return 1; if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) { - format->print_class_name(qctrl.name); + if (format->print_class_name) + format->print_class_name(qctrl.name); return 1; } ext_ctrl.id = qctrl.id; @@ -1102,13 +1146,23 @@ void common_get(cv4l_fd &_fd) void common_list(cv4l_fd &fd) { - if (options[OptListCtrls] || options[OptListCtrlsMenus]) { - struct print_format classic_format = { - .print_class_name = print_class_name, - .print_qctrl = print_qctrl, - .show_menus = options[OptListCtrlsMenus], - }; - - list_controls(fd.g_fd(), &classic_format); + if (options[OptListCtrls] || options[OptListCtrlsMenus] || options[OptListCtrlsValues]) { + if (options[OptListCtrlsValues]) { + struct print_format machine_format = { + .print_class_name = NULL, + .print_qctrl = print_qctrl_values, + .show_menus = 0, + }; + + list_controls(fd.g_fd(), &machine_format); + } else { + struct print_format classic_format = { + .print_class_name = print_class_name, + .print_qctrl = print_qctrl, + .show_menus = options[OptListCtrlsMenus], + }; + + list_controls(fd.g_fd(), &classic_format); + } } } diff --git a/utils/v4l2-ctl/v4l2-ctl.1.in b/utils/v4l2-ctl/v4l2-ctl.1.in index e60c2d49..98cc7b72 100644 --- a/utils/v4l2-ctl/v4l2-ctl.1.in +++ b/utils/v4l2-ctl/v4l2-ctl.1.in @@ -98,6 +98,10 @@ Display all controls and their values [VIDIOC_QUERYCTRL]. \fB-L\fR, \fB--list-ctrls-menus\fR Display all controls and their menus [VIDIOC_QUERYMENU]. .TP +\fB-m\fR, \fB--list-ctrls-values\fR +display all controls and their values in a format compatible with +--set-ctrls (the 'm' stands for "machine readable output") +.TP \fB-r\fR, \fB--subset\fR \fI<ctrl>\fR[,\fI<offset>\fR,\fI<size>\fR]+ The subset of the N-dimensional array to get/set for control \fI<ctrl>\fR, for every dimension an (\fI<offset>\fR, \fI<size>\fR) tuple is given. diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp index a65262f6..647e1778 100644 --- a/utils/v4l2-ctl/v4l2-ctl.cpp +++ b/utils/v4l2-ctl/v4l2-ctl.cpp @@ -142,6 +142,7 @@ static struct option long_options[] = { {"info", no_argument, 0, OptGetDriverInfo}, {"list-ctrls", no_argument, 0, OptListCtrls}, {"list-ctrls-menus", no_argument, 0, OptListCtrlsMenus}, + {"list-ctrls-values", no_argument, 0, OptListCtrlsValues}, {"set-ctrl", required_argument, 0, OptSetCtrl}, {"get-ctrl", required_argument, 0, OptGetCtrl}, {"get-tuner", no_argument, 0, OptGetTuner}, diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h index 5a52a0a4..e60a1ea1 100644 --- a/utils/v4l2-ctl/v4l2-ctl.h +++ b/utils/v4l2-ctl/v4l2-ctl.h @@ -65,6 +65,7 @@ enum Option { OptConcise = 'k', OptListCtrls = 'l', OptListCtrlsMenus = 'L', + OptListCtrlsValues = 'm', OptListOutputs = 'N', OptListInputs = 'n', OptGetOutput = 'O', -- 2.20.1 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format 2019-01-03 18:01 ` [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format Antonio Ospite @ 2019-01-07 10:18 ` Hans Verkuil 2019-01-09 21:15 ` Antonio Ospite 0 siblings, 1 reply; 11+ messages in thread From: Hans Verkuil @ 2019-01-07 10:18 UTC (permalink / raw) To: Antonio Ospite, linux-media On 01/03/2019 07:01 PM, Antonio Ospite wrote: > Add a new option --list-ctrls-values to list the values of controls in > a format which can be passed again to --set-ctrl. > > This can be useful to save and restore device settings: > > $ v4l2-ctl --list-ctrls-values >settings.txt 2>/dev/null > $ v4l2-ctl --set-ctrl "$(cat settings.txt)" > > The new option has been tested with the vivid driver and it works well > enough to be useful with a real driver as well. > > String controls are not supported for now, as they may not be parsed > correctly by --set-ctrl if they contain a comma or a single quote. > > Signed-off-by: Antonio Ospite <ao2@ao2.it> > --- > utils/v4l2-ctl/v4l2-ctl-common.cpp | 72 ++++++++++++++++++++++++++---- > utils/v4l2-ctl/v4l2-ctl.1.in | 4 ++ > utils/v4l2-ctl/v4l2-ctl.cpp | 1 + > utils/v4l2-ctl/v4l2-ctl.h | 1 + > 4 files changed, 69 insertions(+), 9 deletions(-) > > diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp > index 7777b45c..b4124608 100644 > --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp > +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp > @@ -93,6 +93,9 @@ void common_usage(void) > " -l, --list-ctrls display all controls and their values [VIDIOC_QUERYCTRL]\n" > " -L, --list-ctrls-menus\n" > " display all controls and their menus [VIDIOC_QUERYMENU]\n" > + " -m, --list-ctrls-values\n" > + " display all controls and their values in a format compatible with\n" > + " --set-ctrls (the 'm' stands for \"machine readable output\")\n" > " -r, --subset <ctrl>[,<offset>,<size>]+\n" > " the subset of the N-dimensional array to get/set for control <ctrl>,\n" > " for every dimension an (<offset>, <size>) tuple is given.\n" > @@ -409,6 +412,46 @@ static void print_qctrl(int fd, struct v4l2_query_ext_ctrl *queryctrl, > } > } > > +static void print_qctrl_values(int fd, struct v4l2_query_ext_ctrl *queryctrl, > + struct v4l2_ext_control *ctrl, int show_menus) > +{ > + std::string s = name2var(queryctrl->name); > + > + if (queryctrl->nr_of_dims == 0) { > + switch (queryctrl->type) { > + case V4L2_CTRL_TYPE_INTEGER: > + case V4L2_CTRL_TYPE_BOOLEAN: > + case V4L2_CTRL_TYPE_MENU: > + case V4L2_CTRL_TYPE_INTEGER_MENU: > + printf("%s=%d,", s.c_str(), ctrl->value); > + break; > + case V4L2_CTRL_TYPE_BITMASK: > + printf("%s=0x%08x,", s.c_str(), ctrl->value); > + break; > + case V4L2_CTRL_TYPE_INTEGER64: > + printf("%s=%lld,", s.c_str(), ctrl->value64); > + break; > + case V4L2_CTRL_TYPE_STRING: > + fprintf(stderr, "%s: string controls unsupported for now\n", queryctrl->name); > + break; > + default: > + fprintf(stderr, "%s: unsupported payload type\n", queryctrl->name); > + break; > + } > + } > + > + if (queryctrl->nr_of_dims) > + fprintf(stderr, "%s: unsupported payload type (multi-dimensional)\n", queryctrl->name); > + > + if (queryctrl->flags) > + fprintf(stderr, "%s: ignoring flags\n", queryctrl->name); > + > + if ((queryctrl->type == V4L2_CTRL_TYPE_MENU || > + queryctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) && show_menus) { > + fprintf(stderr, "%s: ignoring menus\n", queryctrl->name); > + } > +} > + > static void print_class_name(const char *name) > { > printf("\n%s\n\n", name); > @@ -426,7 +469,8 @@ static int print_control(int fd, struct v4l2_query_ext_ctrl &qctrl, struct print > if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED) > return 1; > if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) { > - format->print_class_name(qctrl.name); > + if (format->print_class_name) > + format->print_class_name(qctrl.name); > return 1; > } > ext_ctrl.id = qctrl.id; > @@ -1102,13 +1146,23 @@ void common_get(cv4l_fd &_fd) > > void common_list(cv4l_fd &fd) > { > - if (options[OptListCtrls] || options[OptListCtrlsMenus]) { > - struct print_format classic_format = { > - .print_class_name = print_class_name, > - .print_qctrl = print_qctrl, > - .show_menus = options[OptListCtrlsMenus], > - }; > - > - list_controls(fd.g_fd(), &classic_format); > + if (options[OptListCtrls] || options[OptListCtrlsMenus] || options[OptListCtrlsValues]) { > + if (options[OptListCtrlsValues]) { > + struct print_format machine_format = { > + .print_class_name = NULL, > + .print_qctrl = print_qctrl_values, > + .show_menus = 0, > + }; > + > + list_controls(fd.g_fd(), &machine_format); > + } else { > + struct print_format classic_format = { > + .print_class_name = print_class_name, > + .print_qctrl = print_qctrl, > + .show_menus = options[OptListCtrlsMenus], > + }; > + > + list_controls(fd.g_fd(), &classic_format); > + } I don't like this struct print_format. I would prefer something like this: Rename print_qctrl to print_qctrl_readable() and create a new print_qctrl: static void print_qctrl(int fd, struct v4l2_query_ext_ctrl *queryctrl, struct v4l2_ext_control *ctrl, int show_menus) { if (options[OptListCtrlsValues]) print_qctrl_values(fd, queryctrl, ctrl, show_menus); else print_qctrl_readable(fd, queryctrl, ctrl, show_menus); } And in print_control you can just skip printing the class name if options[OptListCtrlsValues] is set. I would like to see string controls being supported. I would recommend to just write the string as a hexdump. It avoids having to escape characters. The same can be done for compound/array controls. In fact, you could write all controls that way. It would simplify things a lot. Also, when options[OptListCtrlsValues] is set you should skip all WRITE_ONLY controls, all BUTTON controls, and all volatile controls. They are not relevant if you are just interested in controls that can be set. Regards, Hans > } > } > diff --git a/utils/v4l2-ctl/v4l2-ctl.1.in b/utils/v4l2-ctl/v4l2-ctl.1.in > index e60c2d49..98cc7b72 100644 > --- a/utils/v4l2-ctl/v4l2-ctl.1.in > +++ b/utils/v4l2-ctl/v4l2-ctl.1.in > @@ -98,6 +98,10 @@ Display all controls and their values [VIDIOC_QUERYCTRL]. > \fB-L\fR, \fB--list-ctrls-menus\fR > Display all controls and their menus [VIDIOC_QUERYMENU]. > .TP > +\fB-m\fR, \fB--list-ctrls-values\fR > +display all controls and their values in a format compatible with > +--set-ctrls (the 'm' stands for "machine readable output") > +.TP > \fB-r\fR, \fB--subset\fR \fI<ctrl>\fR[,\fI<offset>\fR,\fI<size>\fR]+ > The subset of the N-dimensional array to get/set for control \fI<ctrl>\fR, > for every dimension an (\fI<offset>\fR, \fI<size>\fR) tuple is given. > diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp > index a65262f6..647e1778 100644 > --- a/utils/v4l2-ctl/v4l2-ctl.cpp > +++ b/utils/v4l2-ctl/v4l2-ctl.cpp > @@ -142,6 +142,7 @@ static struct option long_options[] = { > {"info", no_argument, 0, OptGetDriverInfo}, > {"list-ctrls", no_argument, 0, OptListCtrls}, > {"list-ctrls-menus", no_argument, 0, OptListCtrlsMenus}, > + {"list-ctrls-values", no_argument, 0, OptListCtrlsValues}, > {"set-ctrl", required_argument, 0, OptSetCtrl}, > {"get-ctrl", required_argument, 0, OptGetCtrl}, > {"get-tuner", no_argument, 0, OptGetTuner}, > diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h > index 5a52a0a4..e60a1ea1 100644 > --- a/utils/v4l2-ctl/v4l2-ctl.h > +++ b/utils/v4l2-ctl/v4l2-ctl.h > @@ -65,6 +65,7 @@ enum Option { > OptConcise = 'k', > OptListCtrls = 'l', > OptListCtrlsMenus = 'L', > + OptListCtrlsValues = 'm', > OptListOutputs = 'N', > OptListInputs = 'n', > OptGetOutput = 'O', > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format 2019-01-07 10:18 ` Hans Verkuil @ 2019-01-09 21:15 ` Antonio Ospite 2019-01-10 12:05 ` Hans Verkuil 0 siblings, 1 reply; 11+ messages in thread From: Antonio Ospite @ 2019-01-09 21:15 UTC (permalink / raw) To: Hans Verkuil; +Cc: linux-media On Mon, 7 Jan 2019 11:18:58 +0100 Hans Verkuil <hverkuil@xs4all.nl> wrote: > On 01/03/2019 07:01 PM, Antonio Ospite wrote: > > Add a new option --list-ctrls-values to list the values of controls in > > a format which can be passed again to --set-ctrl. > > > > This can be useful to save and restore device settings: > > > > $ v4l2-ctl --list-ctrls-values >settings.txt 2>/dev/null > > $ v4l2-ctl --set-ctrl "$(cat settings.txt)" > > > > The new option has been tested with the vivid driver and it works well > > enough to be useful with a real driver as well. > > > > String controls are not supported for now, as they may not be parsed > > correctly by --set-ctrl if they contain a comma or a single quote. > > > > Signed-off-by: Antonio Ospite <ao2@ao2.it> > > --- > > utils/v4l2-ctl/v4l2-ctl-common.cpp | 72 ++++++++++++++++++++++++++---- > > utils/v4l2-ctl/v4l2-ctl.1.in | 4 ++ > > utils/v4l2-ctl/v4l2-ctl.cpp | 1 + > > utils/v4l2-ctl/v4l2-ctl.h | 1 + > > 4 files changed, 69 insertions(+), 9 deletions(-) > > > > diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp > > index 7777b45c..b4124608 100644 > > --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp > > +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp [...] > > @@ -1102,13 +1146,23 @@ void common_get(cv4l_fd &_fd) > > > > void common_list(cv4l_fd &fd) > > { > > - if (options[OptListCtrls] || options[OptListCtrlsMenus]) { > > - struct print_format classic_format = { > > - .print_class_name = print_class_name, > > - .print_qctrl = print_qctrl, > > - .show_menus = options[OptListCtrlsMenus], > > - }; > > - > > - list_controls(fd.g_fd(), &classic_format); > > + if (options[OptListCtrls] || options[OptListCtrlsMenus] || options[OptListCtrlsValues]) { > > + if (options[OptListCtrlsValues]) { > > + struct print_format machine_format = { > > + .print_class_name = NULL, > > + .print_qctrl = print_qctrl_values, > > + .show_menus = 0, > > + }; > > + > > + list_controls(fd.g_fd(), &machine_format); > > + } else { > > + struct print_format classic_format = { > > + .print_class_name = print_class_name, > > + .print_qctrl = print_qctrl, > > + .show_menus = options[OptListCtrlsMenus], > > + }; > > + > > + list_controls(fd.g_fd(), &classic_format); > > + } > > I don't like this struct print_format. > Hi Hans, the idea was based on two considerations: 1. decide the format once and for all, avoiding to check each time a control is printed. 2. have at least some partial infrastructure in case some other export formats were to be added. But yeah, as 2. seems quite unlikely I can go with a more essential approach for now, no problem. > I would prefer something like this: > > Rename print_qctrl to print_qctrl_readable() and create a new print_qctrl: > > static void print_qctrl(int fd, struct v4l2_query_ext_ctrl *queryctrl, > struct v4l2_ext_control *ctrl, int show_menus) > { > if (options[OptListCtrlsValues]) > print_qctrl_values(fd, queryctrl, ctrl, show_menus); > else > print_qctrl_readable(fd, queryctrl, ctrl, show_menus); > } > Since "readable" here means "human readable", while "values" is meant for a "machine readable" output, I'd "avoid" the word "readable" at all and go with "details" or "description": if (options[OptListCtrlsValues]) print_qctrl_values(fd, queryctrl, ctrl, show_menus); else print_qctrl_details(fd, queryctrl, ctrl, show_menus); > And in print_control you can just skip printing the class name if > options[OptListCtrlsValues] is set. > OK. > I would like to see string controls being supported. I would recommend > to just write the string as a hexdump. It avoids having to escape characters. > > The same can be done for compound/array controls. In fact, you could write > all controls that way. It would simplify things a lot. > But then --set-ctrl would need to be extended to parse the hexdump, wouldn't it? Do you already have a syntax in mind? TBH, I kept things simple hoping to re-use --set-ctrl without too much work. > Also, when options[OptListCtrlsValues] is set you should skip all WRITE_ONLY > controls, all BUTTON controls, and all volatile controls. They are not > relevant if you are just interested in controls that can be set. > That I will do in any case, thank you. > Regards, > > Hans Thank you, Antonio -- Antonio Ospite https://ao2.it https://twitter.com/ao2it A: Because it messes up the order in which people normally read text. See http://en.wikipedia.org/wiki/Posting_style Q: Why is top-posting such a bad thing? ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format 2019-01-09 21:15 ` Antonio Ospite @ 2019-01-10 12:05 ` Hans Verkuil 0 siblings, 0 replies; 11+ messages in thread From: Hans Verkuil @ 2019-01-10 12:05 UTC (permalink / raw) To: Antonio Ospite; +Cc: linux-media On 01/09/19 22:15, Antonio Ospite wrote: > On Mon, 7 Jan 2019 11:18:58 +0100 > Hans Verkuil <hverkuil@xs4all.nl> wrote: > >> On 01/03/2019 07:01 PM, Antonio Ospite wrote: >>> Add a new option --list-ctrls-values to list the values of controls in >>> a format which can be passed again to --set-ctrl. >>> >>> This can be useful to save and restore device settings: >>> >>> $ v4l2-ctl --list-ctrls-values >settings.txt 2>/dev/null >>> $ v4l2-ctl --set-ctrl "$(cat settings.txt)" >>> >>> The new option has been tested with the vivid driver and it works well >>> enough to be useful with a real driver as well. >>> >>> String controls are not supported for now, as they may not be parsed >>> correctly by --set-ctrl if they contain a comma or a single quote. >>> >>> Signed-off-by: Antonio Ospite <ao2@ao2.it> >>> --- >>> utils/v4l2-ctl/v4l2-ctl-common.cpp | 72 ++++++++++++++++++++++++++---- >>> utils/v4l2-ctl/v4l2-ctl.1.in | 4 ++ >>> utils/v4l2-ctl/v4l2-ctl.cpp | 1 + >>> utils/v4l2-ctl/v4l2-ctl.h | 1 + >>> 4 files changed, 69 insertions(+), 9 deletions(-) >>> >>> diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp b/utils/v4l2-ctl/v4l2-ctl-common.cpp >>> index 7777b45c..b4124608 100644 >>> --- a/utils/v4l2-ctl/v4l2-ctl-common.cpp >>> +++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp > [...] >>> @@ -1102,13 +1146,23 @@ void common_get(cv4l_fd &_fd) >>> >>> void common_list(cv4l_fd &fd) >>> { >>> - if (options[OptListCtrls] || options[OptListCtrlsMenus]) { >>> - struct print_format classic_format = { >>> - .print_class_name = print_class_name, >>> - .print_qctrl = print_qctrl, >>> - .show_menus = options[OptListCtrlsMenus], >>> - }; >>> - >>> - list_controls(fd.g_fd(), &classic_format); >>> + if (options[OptListCtrls] || options[OptListCtrlsMenus] || options[OptListCtrlsValues]) { >>> + if (options[OptListCtrlsValues]) { >>> + struct print_format machine_format = { >>> + .print_class_name = NULL, >>> + .print_qctrl = print_qctrl_values, >>> + .show_menus = 0, >>> + }; >>> + >>> + list_controls(fd.g_fd(), &machine_format); >>> + } else { >>> + struct print_format classic_format = { >>> + .print_class_name = print_class_name, >>> + .print_qctrl = print_qctrl, >>> + .show_menus = options[OptListCtrlsMenus], >>> + }; >>> + >>> + list_controls(fd.g_fd(), &classic_format); >>> + } >> >> I don't like this struct print_format. >> > > Hi Hans, > > the idea was based on two considerations: > 1. decide the format once and for all, avoiding to check each time a > control is printed. > 2. have at least some partial infrastructure in case some > other export formats were to be added. > > But yeah, as 2. seems quite unlikely I can go with a more essential > approach for now, no problem. > >> I would prefer something like this: >> >> Rename print_qctrl to print_qctrl_readable() and create a new print_qctrl: >> >> static void print_qctrl(int fd, struct v4l2_query_ext_ctrl *queryctrl, >> struct v4l2_ext_control *ctrl, int show_menus) >> { >> if (options[OptListCtrlsValues]) >> print_qctrl_values(fd, queryctrl, ctrl, show_menus); >> else >> print_qctrl_readable(fd, queryctrl, ctrl, show_menus); >> } >> > > Since "readable" here means "human readable", while "values" is meant > for a "machine readable" output, I'd "avoid" the word "readable" at > all and go with "details" or "description": > > if (options[OptListCtrlsValues]) > print_qctrl_values(fd, queryctrl, ctrl, show_menus); > else > print_qctrl_details(fd, queryctrl, ctrl, show_menus); Hmm. Perhaps we should just be explicit: print_qctrl_machine_readable print_qctrl_human_readable I think that's best. > >> And in print_control you can just skip printing the class name if >> options[OptListCtrlsValues] is set. >> > > OK. > >> I would like to see string controls being supported. I would recommend >> to just write the string as a hexdump. It avoids having to escape characters. >> >> The same can be done for compound/array controls. In fact, you could write >> all controls that way. It would simplify things a lot. >> > > But then --set-ctrl would need to be extended to parse the hexdump, > wouldn't it? Do you already have a syntax in mind? I would add a new --set-ctrl-value option that takes a hexdump. Basically the inverse of --list-ctrls-values. Regards, Hans > > TBH, I kept things simple hoping to re-use --set-ctrl without too much > work. > >> Also, when options[OptListCtrlsValues] is set you should skip all WRITE_ONLY >> controls, all BUTTON controls, and all volatile controls. They are not >> relevant if you are just interested in controls that can be set. >> > > That I will do in any case, thank you. > >> Regards, >> >> Hans > > Thank you, > Antonio > ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite ` (4 preceding siblings ...) 2019-01-03 18:01 ` [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format Antonio Ospite @ 2019-01-07 10:21 ` Hans Verkuil 5 siblings, 0 replies; 11+ messages in thread From: Hans Verkuil @ 2019-01-07 10:21 UTC (permalink / raw) To: Antonio Ospite, linux-media On 01/03/2019 07:00 PM, Antonio Ospite wrote: > Hi, > > here is an experiment about listing controls values with v4l2-ctl in > a way that makes it more easy to reload them, I would use something like > that for https://git.ao2.it/v4l2-persistent-settings.git/ > > Patches 1 and 2 are just warm-up patches to get me familiar again with > the v4l2-ctrl codebase, patch 2 is a small preparatory cleanup, and > patches 4 and 5 showcase the idea. > > Thanks, > Antonio > > Antonio Ospite (5): > v4l2-ctl: list controls with menus when OptAll is specified > v4l2-ctl: list once when both OptListCtrls and OptListCtrlsMenus are > there I merged these first two patches. > v4l2-ctl: use a dedicated function to print the control class name > v4l2-ctl: abstract the mechanism used to print the list of controls > v4l2-ctl: add an option to list controls in a machine-readable format The others need more work, see my review of the last patch. Thanks for working on this! Regards, Hans > > utils/v4l2-ctl/v4l2-ctl-common.cpp | 95 +++++++++++++++++++++++++----- > utils/v4l2-ctl/v4l2-ctl.1.in | 4 ++ > utils/v4l2-ctl/v4l2-ctl.cpp | 3 +- > utils/v4l2-ctl/v4l2-ctl.h | 1 + > 4 files changed, 88 insertions(+), 15 deletions(-) > ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-01-10 12:05 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2018-11-24 17:52 [v4l-utils] Add options to v4l2-ctrl to save/load settings to/from a file Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 0/5] v4l2-ctl: list controls values in a machine-readable format Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 1/5] v4l2-ctl: list controls with menus when OptAll is specified Antonio Ospite 2019-01-03 18:00 ` [RFC PATCH 2/5] v4l2-ctl: list once when both OptListCtrls and OptListCtrlsMenus are there Antonio Ospite 2019-01-03 18:01 ` [RFC PATCH 3/5] v4l2-ctl: use a dedicated function to print the control class name Antonio Ospite 2019-01-03 18:01 ` [RFC PATCH 4/5] v4l2-ctl: abstract the mechanism used to print the list of controls Antonio Ospite 2019-01-03 18:01 ` [RFC PATCH 5/5] v4l2-ctl: add an option to list controls in a machine-readable format Antonio Ospite 2019-01-07 10:18 ` Hans Verkuil 2019-01-09 21:15 ` Antonio Ospite 2019-01-10 12:05 ` Hans Verkuil 2019-01-07 10:21 ` [RFC PATCH 0/5] v4l2-ctl: list controls values " Hans Verkuil
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).