This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/v4l-utils.git tree:

Subject: v4l2-ctl: split up this overly large source.
Author:  Hans Verkuil <[email protected]>
Date:    Thu Jul 26 10:32:06 2012 +0200

Phase one: split off the handling of the common options.

Signed-off-by: Hans Verkuil <[email protected]>
(cherry picked from commit 052dced533310da8e23010b4fe0fa802a0a541f0)

Signed-off-by: Gregor Jasny <[email protected]>

 utils/v4l2-ctl/Makefile            |    2 +-
 utils/v4l2-ctl/v4l2-ctl-common.cpp |  729 ++++++++++++++++++++++++++++++
 utils/v4l2-ctl/v4l2-ctl.cpp        |  872 ++----------------------------------
 utils/v4l2-ctl/v4l2-ctl.h          |  174 +++++++
 4 files changed, 935 insertions(+), 842 deletions(-)

---

http://git.linuxtv.org/v4l-utils.git?a=commitdiff;h=2b763a32b2ec1eeccd06aa01cc97c288285d1f76

diff --git a/utils/v4l2-ctl/Makefile b/utils/v4l2-ctl/Makefile
index 5ea58c7..9432121 100644
--- a/utils/v4l2-ctl/Makefile
+++ b/utils/v4l2-ctl/Makefile
@@ -12,7 +12,7 @@ cx18-ctl: cx18-ctl.o
 ivtv-ctl: ivtv-ctl.o
        $(CC) $(LDFLAGS) -o $@ $^ -lm
 
-v4l2-ctl: v4l2-ctl.o
+v4l2-ctl: v4l2-ctl.o v4l2-ctl-common.o
        $(CXX) $(LDFLAGS) -o $@ $^ -lv4l2 -lv4lconvert -lrt
 
 install: $(TARGETS)
diff --git a/utils/v4l2-ctl/v4l2-ctl-common.cpp 
b/utils/v4l2-ctl/v4l2-ctl-common.cpp
new file mode 100644
index 0000000..af0c3ea
--- /dev/null
+++ b/utils/v4l2-ctl/v4l2-ctl-common.cpp
@@ -0,0 +1,729 @@
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <getopt.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <dirent.h>
+#include <math.h>
+
+#ifdef __linux__
+#include <sys/klog.h>
+#endif
+
+#include <linux/videodev2.h>
+#include <libv4l2.h>
+
+#include <list>
+#include <vector>
+#include <map>
+#include <string>
+#include <algorithm>
+
+#include "v4l2-ctl.h"
+
+typedef std::map<unsigned, std::vector<struct v4l2_ext_control> > 
class2ctrls_map;
+
+typedef std::map<std::string, struct v4l2_queryctrl> ctrl_qmap;
+static ctrl_qmap ctrl_str2q;
+typedef std::map<unsigned, std::string> ctrl_idmap;
+static ctrl_idmap ctrl_id2str;
+
+typedef std::list<std::string> ctrl_get_list;
+static ctrl_get_list get_ctrls;
+
+typedef std::map<std::string, std::string> ctrl_set_map;
+static ctrl_set_map set_ctrls;
+
+typedef std::vector<std::string> dev_vec;
+typedef std::map<std::string, std::string> dev_map;
+
+static enum v4l2_priority prio = V4L2_PRIORITY_UNSET;
+
+void common_usage(void)
+{
+       printf("\nGeneral/Common options:\n"
+              "  --all              display all information available\n"
+              "  -C, --get-ctrl=<ctrl>[,<ctrl>...]\n"
+              "                     get the value of the controls 
[VIDIOC_G_EXT_CTRLS]\n"
+              "  -c, --set-ctrl=<ctrl>=<val>[,<ctrl>=<val>...]\n"
+              "                     set the value of the controls 
[VIDIOC_S_EXT_CTRLS]\n"
+              "  -D, --info         show driver info [VIDIOC_QUERYCAP]\n"
+              "  -d, --device=<dev> use device <dev> instead of /dev/video0\n"
+              "                     if <dev> is a single digit, then 
/dev/video<dev> is used\n"
+              "  -h, --help         display this help message\n"
+              "  --help-all         all options\n"
+              "  --help-io          input/output options\n"
+              "  --help-misc        miscellaneous options\n"
+              "  --help-overlay     overlay format options\n"
+              "  --help-selection   crop/selection options\n"
+              "  --help-stds        standards and other video timings 
options\n"
+              "  --help-tuner       tuner/modulator options\n"
+              "  --help-vbi         VBI format options\n"
+              "  --help-vidcap      video capture format options\n"
+              "  --help-vidout      vidout output format options\n"
+              "  -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"
+              "  -w, --wrapper      use the libv4l2 wrapper library.\n"
+              "  --list-devices     list all v4l devices\n"
+              "  --log-status       log the board status in the kernel log 
[VIDIOC_LOG_STATUS]\n"
+              "  --get-priority     query the current access priority 
[VIDIOC_G_PRIORITY]\n"
+              "  --set-priority=<prio>\n"
+              "                     set the new access priority 
[VIDIOC_S_PRIORITY]\n"
+              "                     <prio> is 1 (background), 2 (interactive) 
or 3 (record)\n"
+              "  --silent           only set the result code, do not print any 
messages\n"
+              "  --sleep=<secs>     sleep <secs>, call QUERYCAP and close the 
file handle\n"
+              "  --verbose          turn on verbose ioctl status reporting\n"
+              );
+}
+
+static bool is_v4l_dev(const char *name)
+{
+       return !memcmp(name, "vtx", 3) ||
+               !memcmp(name, "video", 5) ||
+               !memcmp(name, "radio", 5) ||
+               !memcmp(name, "vbi", 3);
+}
+
+static int calc_node_val(const char *s)
+{
+       int n = 0;
+
+       s = strrchr(s, '/') + 1;
+       if (!memcmp(s, "video", 5)) n = 0;
+       else if (!memcmp(s, "radio", 5)) n = 0x100;
+       else if (!memcmp(s, "vbi", 3)) n = 0x200;
+       else if (!memcmp(s, "v4l-subdev", 10)) n = 0x300;
+       n += atol(s + (n >= 0x200 ? 3 : 5));
+       return n;
+}
+
+static bool sort_on_device_name(const std::string &s1, const std::string &s2)
+{
+       int n1 = calc_node_val(s1.c_str());
+       int n2 = calc_node_val(s2.c_str());
+
+       return n1 < n2;
+}
+
+static void list_devices()
+{
+       DIR *dp;
+       struct dirent *ep;
+       dev_vec files;
+       dev_map links;
+       dev_map cards;
+       struct v4l2_capability vcap;
+
+       dp = opendir("/dev");
+       if (dp == NULL) {
+               perror ("Couldn't open the directory");
+               return;
+       }
+       while ((ep = readdir(dp)))
+               if (is_v4l_dev(ep->d_name))
+                       files.push_back(std::string("/dev/") + ep->d_name);
+       closedir(dp);
+
+       /* Find device nodes which are links to other device nodes */
+       for (dev_vec::iterator iter = files.begin();
+                       iter != files.end(); ) {
+               char link[64+1];
+               int link_len;
+               std::string target;
+
+               link_len = readlink(iter->c_str(), link, 64);
+               if (link_len < 0) {     /* Not a link or error */
+                       iter++;
+                       continue;
+               }
+               link[link_len] = '\0';
+
+               /* Only remove from files list if target itself is in list */
+               if (link[0] != '/')     /* Relative link */
+                       target = std::string("/dev/");
+               target += link;
+               if (find(files.begin(), files.end(), target) == files.end()) {
+                       iter++;
+                       continue;
+               }
+
+               /* Move the device node from files to links */
+               if (links[target].empty())
+                       links[target] = *iter;
+               else
+                       links[target] += ", " + *iter;
+               files.erase(iter);
+       }
+
+       std::sort(files.begin(), files.end(), sort_on_device_name);
+
+       for (dev_vec::iterator iter = files.begin();
+                       iter != files.end(); ++iter) {
+               int fd = open(iter->c_str(), O_RDWR);
+               std::string bus_info;
+
+               if (fd < 0)
+                       continue;
+               doioctl(fd, VIDIOC_QUERYCAP, &vcap);
+               close(fd);
+               bus_info = (const char *)vcap.bus_info;
+               if (cards[bus_info].empty())
+                       cards[bus_info] += std::string((char *)vcap.card) + " 
(" + bus_info + "):\n";
+               cards[bus_info] += "\t" + (*iter);
+               if (!(links[*iter].empty()))
+                       cards[bus_info] += " <- " + links[*iter];
+               cards[bus_info] += "\n";
+       }
+       for (dev_map::iterator iter = cards.begin();
+                       iter != cards.end(); ++iter) {
+               printf("%s\n", iter->second.c_str());
+       }
+}
+
+static std::string name2var(unsigned char *name)
+{
+       std::string s;
+       int add_underscore = 0;
+
+       while (*name) {
+               if (isalnum(*name)) {
+                       if (add_underscore)
+                               s += '_';
+                       add_underscore = 0;
+                       s += std::string(1, tolower(*name));
+               }
+               else if (s.length()) add_underscore = 1;
+               name++;
+       }
+       return s;
+}
+
+static std::string safename(const unsigned char *name)
+{
+       std::string s;
+
+       while (*name) {
+               if (*name == '\n') {
+                       s += "\\n";
+               }
+               else if (*name == '\r') {
+                       s += "\\r";
+               }
+               else if (*name == '\f') {
+                       s += "\\f";
+               }
+               else if (*name == '\\') {
+                       s += "\\\\";
+               }
+               else if ((*name & 0x7f) < 0x20) {
+                       char buf[3];
+
+                       sprintf(buf, "%02x", *name);
+                       s += "\\x";
+                       s += buf;
+               }
+               else {
+                       s += *name;
+               }
+               name++;
+       }
+       return s;
+}
+
+static std::string safename(const char *name)
+{
+       return safename((const unsigned char *)name);
+}
+
+static std::string ctrlflags2s(__u32 flags)
+{
+       static const flag_def def[] = {
+               { V4L2_CTRL_FLAG_GRABBED,    "grabbed" },
+               { V4L2_CTRL_FLAG_DISABLED,   "disabled" },
+               { V4L2_CTRL_FLAG_READ_ONLY,  "read-only" },
+               { V4L2_CTRL_FLAG_UPDATE,     "update" },
+               { V4L2_CTRL_FLAG_INACTIVE,   "inactive" },
+               { V4L2_CTRL_FLAG_SLIDER,     "slider" },
+               { V4L2_CTRL_FLAG_WRITE_ONLY, "write-only" },
+               { V4L2_CTRL_FLAG_VOLATILE,   "volatile" },
+               { 0, NULL }
+       };
+       return flags2s(flags, def);
+}
+
+static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl,
+               struct v4l2_ext_control *ctrl, int show_menus)
+{
+       struct v4l2_querymenu qmenu;
+       std::string s = name2var(queryctrl->name);
+       int i;
+
+       memset(&qmenu, 0, sizeof(qmenu));
+       qmenu.id = queryctrl->id;
+       switch (queryctrl->type) {
+       case V4L2_CTRL_TYPE_INTEGER:
+               printf("%31s (int)    : min=%d max=%d step=%d default=%d 
value=%d",
+                               s.c_str(),
+                               queryctrl->minimum, queryctrl->maximum,
+                               queryctrl->step, queryctrl->default_value,
+                               ctrl->value);
+               break;
+       case V4L2_CTRL_TYPE_INTEGER64:
+               printf("%31s (int64)  : value=%lld", s.c_str(), ctrl->value64);
+               break;
+       case V4L2_CTRL_TYPE_STRING:
+               printf("%31s (str)    : min=%d max=%d step=%d value='%s'",
+                               s.c_str(),
+                               queryctrl->minimum, queryctrl->maximum,
+                               queryctrl->step, 
safename(ctrl->string).c_str());
+               break;
+       case V4L2_CTRL_TYPE_BOOLEAN:
+               printf("%31s (bool)   : default=%d value=%d",
+                               s.c_str(),
+                               queryctrl->default_value, ctrl->value);
+               break;
+       case V4L2_CTRL_TYPE_MENU:
+               printf("%31s (menu)   : min=%d max=%d default=%d value=%d",
+                               s.c_str(),
+                               queryctrl->minimum, queryctrl->maximum,
+                               queryctrl->default_value, ctrl->value);
+               break;
+       case V4L2_CTRL_TYPE_INTEGER_MENU:
+               printf("%31s (intmenu): min=%d max=%d default=%d value=%d",
+                               s.c_str(),
+                               queryctrl->minimum, queryctrl->maximum,
+                               queryctrl->default_value, ctrl->value);
+               break;
+       case V4L2_CTRL_TYPE_BUTTON:
+               printf("%31s (button) :", s.c_str());
+               break;
+       case V4L2_CTRL_TYPE_BITMASK:
+               printf("%31s (bitmask): max=0x%08x default=0x%08x value=0x%08x",
+                               s.c_str(), queryctrl->maximum,
+                               queryctrl->default_value, ctrl->value);
+               break;
+       default: break;
+       }
+       if (queryctrl->flags)
+               printf(" flags=%s", ctrlflags2s(queryctrl->flags).c_str());
+       printf("\n");
+       if ((queryctrl->type == V4L2_CTRL_TYPE_MENU ||
+            queryctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) && show_menus) {
+               for (i = queryctrl->minimum; i <= queryctrl->maximum; i++) {
+                       qmenu.index = i;
+                       if (test_ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
+                               continue;
+                       if (queryctrl->type == V4L2_CTRL_TYPE_MENU)
+                               printf("\t\t\t\t%d: %s\n", i, qmenu.name);
+                       else
+                               printf("\t\t\t\t%d: %lld (0x%llx)\n", i, 
qmenu.value, qmenu.value);
+               }
+       }
+}
+
+static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus)
+{
+       struct v4l2_control ctrl;
+       struct v4l2_ext_control ext_ctrl;
+       struct v4l2_ext_controls ctrls;
+
+       memset(&ctrl, 0, sizeof(ctrl));
+       memset(&ext_ctrl, 0, sizeof(ext_ctrl));
+       memset(&ctrls, 0, sizeof(ctrls));
+       if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
+               return 1;
+       if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
+               printf("\n%s\n\n", 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);
+               return 1;
+       }
+       ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(qctrl.id);
+       ctrls.count = 1;
+       ctrls.controls = &ext_ctrl;
+       if (qctrl.type == V4L2_CTRL_TYPE_INTEGER64 ||
+           qctrl.type == V4L2_CTRL_TYPE_STRING ||
+           (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER &&
+            qctrl.id < V4L2_CID_PRIVATE_BASE)) {
+               if (qctrl.type == V4L2_CTRL_TYPE_STRING) {
+                   ext_ctrl.size = qctrl.maximum + 1;
+                   ext_ctrl.string = (char *)malloc(ext_ctrl.size);
+                   ext_ctrl.string[0] = 0;
+               }
+               if (test_ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
+                       printf("error %d getting ext_ctrl %s\n",
+                                       errno, qctrl.name);
+                       return 0;
+               }
+       }
+       else {
+               ctrl.id = qctrl.id;
+               if (test_ioctl(fd, VIDIOC_G_CTRL, &ctrl)) {
+                       printf("error %d getting ctrl %s\n",
+                                       errno, qctrl.name);
+                       return 0;
+               }
+               ext_ctrl.value = ctrl.value;
+       }
+       print_qctrl(fd, &qctrl, &ext_ctrl, show_menus);
+       if (qctrl.type == V4L2_CTRL_TYPE_STRING)
+               free(ext_ctrl.string);
+       return 1;
+}
+
+static void list_controls(int fd, int show_menus)
+{
+       struct v4l2_queryctrl qctrl;
+       int id;
+
+       memset(&qctrl, 0, sizeof(qctrl));
+       qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+       while (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
+                       print_control(fd, qctrl, show_menus);
+               qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+       }
+       if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL)
+               return;
+       for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
+               qctrl.id = id;
+               if (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0)
+                       print_control(fd, qctrl, show_menus);
+       }
+       for (qctrl.id = V4L2_CID_PRIVATE_BASE;
+                       test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; 
qctrl.id++) {
+               print_control(fd, qctrl, show_menus);
+       }
+}
+
+static void find_controls(int fd)
+{
+       struct v4l2_queryctrl qctrl;
+       int id;
+
+       memset(&qctrl, 0, sizeof(qctrl));
+       qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
+       while (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
+               if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS &&
+                   !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
+                       ctrl_str2q[name2var(qctrl.name)] = qctrl;
+                       ctrl_id2str[qctrl.id] = name2var(qctrl.name);
+               }
+               qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
+       }
+       if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL)
+               return;
+       for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
+               qctrl.id = id;
+               if (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0 &&
+                   !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
+                       ctrl_str2q[name2var(qctrl.name)] = qctrl;
+                       ctrl_id2str[qctrl.id] = name2var(qctrl.name);
+               }
+       }
+       for (qctrl.id = V4L2_CID_PRIVATE_BASE;
+                       test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; 
qctrl.id++) {
+               if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
+                       ctrl_str2q[name2var(qctrl.name)] = qctrl;
+                       ctrl_id2str[qctrl.id] = name2var(qctrl.name);
+               }
+       }
+}
+
+int common_find_ctrl_id(const char *name)
+{
+       if (ctrl_str2q.find(name) == ctrl_str2q.end())
+               return 0;
+       return ctrl_str2q[name].id;
+}
+
+void common_process_controls(int fd)
+{
+       find_controls(fd);
+       for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != 
get_ctrls.end(); ++iter) {
+           if (ctrl_str2q.find(*iter) == ctrl_str2q.end()) {
+               fprintf(stderr, "unknown control '%s'\n", (*iter).c_str());
+               exit(1);
+           }
+       }
+       for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != 
set_ctrls.end(); ++iter) {
+           if (ctrl_str2q.find(iter->first) == ctrl_str2q.end()) {
+               fprintf(stderr, "unknown control '%s'\n", iter->first.c_str());
+               exit(1);
+           }
+       }
+}
+
+void common_control_event(const struct v4l2_event *ev)
+{
+       const struct v4l2_event_ctrl *ctrl;
+
+       ctrl = &ev->u.ctrl;
+       printf("ctrl: %s\n", ctrl_id2str[ev->id].c_str());
+       if (ctrl->changes & V4L2_EVENT_CTRL_CH_VALUE) {
+               if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
+                       printf("\tvalue: %lld 0x%llx\n", ctrl->value64, 
ctrl->value64);
+               else
+                       printf("\tvalue: %d 0x%x\n", ctrl->value, ctrl->value);
+       }
+       if (ctrl->changes & V4L2_EVENT_CTRL_CH_FLAGS)
+               printf("\tflags: %s\n", ctrlflags2s(ctrl->flags).c_str());
+}
+
+static bool parse_next_subopt(char **subs, char **value)
+{
+       static char *const subopts[] = {
+           NULL
+       };
+       int opt = getsubopt(subs, subopts, value);
+
+       if (value == NULL) {
+               fprintf(stderr, "No value given to suboption <%s>\n",
+                               subopts[opt]);
+               return true;
+       }
+       return false;
+}
+
+void common_cmd(int ch, char *optarg)
+{
+       char *value, *subs;
+
+       switch (ch) {
+       case OptGetCtrl:
+               subs = optarg;
+               while (*subs != '\0') {
+                       if (parse_next_subopt(&subs, &value)) {
+                               common_usage();
+                               exit(1);
+                       }
+                       if (strchr(value, '=')) {
+                               common_usage();
+                               exit(1);
+                       }
+                       else {
+                               get_ctrls.push_back(value);
+                       }
+               }
+               break;
+       case OptSetCtrl:
+               subs = optarg;
+               while (*subs != '\0') {
+                       if (parse_next_subopt(&subs, &value)) {
+                               common_usage();
+                               exit(1);
+                       }
+                       if (const char *equal = strchr(value, '=')) {
+                               set_ctrls[std::string(value, (equal - value))] 
= equal + 1;
+                       }
+                       else {
+                               fprintf(stderr, "control '%s' without '='\n", 
value);
+                               exit(1);
+                       }
+               }
+               break;
+       case OptSetPriority:
+               prio = (enum v4l2_priority)strtoul(optarg, 0L, 0);
+               break;
+       case OptListDevices:
+               list_devices();
+               break;
+       }
+}
+
+void common_set(int fd)
+{
+       if (options[OptSetPriority]) {
+               if (doioctl(fd, VIDIOC_S_PRIORITY, &prio) >= 0) {
+                       printf("Priority set: %d\n", prio);
+               }
+       }
+
+       if (options[OptSetCtrl] && !set_ctrls.empty()) {
+               struct v4l2_ext_controls ctrls;
+               class2ctrls_map class2ctrls;
+               bool use_ext_ctrls = false;
+
+               memset(&ctrls, 0, sizeof(ctrls));
+               for (ctrl_set_map::iterator iter = set_ctrls.begin();
+                               iter != set_ctrls.end(); ++iter) {
+                       struct v4l2_ext_control ctrl;
+
+                       memset(&ctrl, 0, sizeof(ctrl));
+                       ctrl.id = ctrl_str2q[iter->first].id;
+                       if (ctrl_str2q[iter->first].type == 
V4L2_CTRL_TYPE_INTEGER64)
+                               use_ext_ctrls = true;
+                       if (ctrl_str2q[iter->first].type == 
V4L2_CTRL_TYPE_STRING) {
+                               unsigned len = iter->second.length();
+                               unsigned maxlen = 
ctrl_str2q[iter->first].maximum;
+
+                               use_ext_ctrls = true;
+                               ctrl.size = maxlen + 1;
+                               ctrl.string = (char *)malloc(ctrl.size);
+                               if (len > maxlen) {
+                                       memcpy(ctrl.string, 
iter->second.c_str(), maxlen);
+                                       ctrl.string[maxlen] = 0;
+                               }
+                               else {
+                                       strcpy(ctrl.string, 
iter->second.c_str());
+                               }
+                       } else {
+                               if (V4L2_CTRL_DRIVER_PRIV(ctrl.id))
+                                       use_ext_ctrls = true;
+                               ctrl.value = strtol(iter->second.c_str(), NULL, 
0);
+                       }
+                       
class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl);
+               }
+               for (class2ctrls_map::iterator iter = class2ctrls.begin();
+                               iter != class2ctrls.end(); ++iter) {
+                       if (!use_ext_ctrls &&
+                           (iter->first == V4L2_CTRL_CLASS_USER ||
+                            iter->first == V4L2_CID_PRIVATE_BASE)) {
+                               for (unsigned i = 0; i < iter->second.size(); 
i++) {
+                                       struct v4l2_control ctrl;
+
+                                       ctrl.id = iter->second[i].id;
+                                       ctrl.value = iter->second[i].value;
+                                       if (doioctl(fd, VIDIOC_S_CTRL, &ctrl)) {
+                                               fprintf(stderr, "%s: %s\n",
+                                                               
ctrl_id2str[ctrl.id].c_str(),
+                                                               
strerror(errno));
+                                       }
+                               }
+                               continue;
+                       }
+                       if (iter->second.size()) {
+                               ctrls.ctrl_class = iter->first;
+                               ctrls.count = iter->second.size();
+                               ctrls.controls = &iter->second[0];
+                               if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
+                                       if (ctrls.error_idx >= ctrls.count) {
+                                               fprintf(stderr, "Error setting 
MPEG controls: %s\n",
+                                                               
strerror(errno));
+                                       }
+                                       else {
+                                               fprintf(stderr, "%s: %s\n",
+                                                               
ctrl_id2str[iter->second[ctrls.error_idx].id].c_str(),
+                                                               
strerror(errno));
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+void common_get(int fd)
+{
+       if (options[OptGetCtrl] && !get_ctrls.empty()) {
+               struct v4l2_ext_controls ctrls;
+               class2ctrls_map class2ctrls;
+               bool use_ext_ctrls = false;
+
+               memset(&ctrls, 0, sizeof(ctrls));
+               for (ctrl_get_list::iterator iter = get_ctrls.begin();
+                               iter != get_ctrls.end(); ++iter) {
+                       struct v4l2_ext_control ctrl;
+
+                       memset(&ctrl, 0, sizeof(ctrl));
+                       ctrl.id = ctrl_str2q[*iter].id;
+                       if (ctrl_str2q[*iter].type == V4L2_CTRL_TYPE_INTEGER64)
+                               use_ext_ctrls = true;
+                       if (ctrl_str2q[*iter].type == V4L2_CTRL_TYPE_STRING) {
+                               use_ext_ctrls = true;
+                               ctrl.size = ctrl_str2q[*iter].maximum + 1;
+                               ctrl.string = (char *)malloc(ctrl.size);
+                               ctrl.string[0] = 0;
+                       }
+                       if (V4L2_CTRL_DRIVER_PRIV(ctrl.id))
+                               use_ext_ctrls = true;
+                       
class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl);
+               }
+               for (class2ctrls_map::iterator iter = class2ctrls.begin();
+                               iter != class2ctrls.end(); ++iter) {
+                       if (!use_ext_ctrls &&
+                           (iter->first == V4L2_CTRL_CLASS_USER ||
+                            iter->first == V4L2_CID_PRIVATE_BASE)) {
+                               for (unsigned i = 0; i < iter->second.size(); 
i++) {
+                                       struct v4l2_control ctrl;
+
+                                       ctrl.id = iter->second[i].id;
+                                       doioctl(fd, VIDIOC_G_CTRL, &ctrl);
+                                       printf("%s: %d\n", 
ctrl_id2str[ctrl.id].c_str(), ctrl.value);
+                               }
+                               continue;
+                       }
+                       if (iter->second.size()) {
+                               ctrls.ctrl_class = iter->first;
+                               ctrls.count = iter->second.size();
+                               ctrls.controls = &iter->second[0];
+                               doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls);
+                               for (unsigned i = 0; i < iter->second.size(); 
i++) {
+                                       struct v4l2_ext_control ctrl = 
iter->second[i];
+
+                                       if 
(ctrl_str2q[ctrl_id2str[ctrl.id]].type == V4L2_CTRL_TYPE_STRING)
+                                               printf("%s: '%s'\n", 
ctrl_id2str[ctrl.id].c_str(),
+                                                              
safename(ctrl.string).c_str());
+                                       else
+                                               printf("%s: %d\n", 
ctrl_id2str[ctrl.id].c_str(), ctrl.value);
+                               }
+                       }
+               }
+       }
+
+       if (options[OptGetPriority]) {
+               if (doioctl(fd, VIDIOC_G_PRIORITY, &prio) == 0)
+                       printf("Priority: %d\n", prio);
+       }
+
+       if (options[OptLogStatus]) {
+               static char buf[40960];
+               int len = -1;
+
+               if (doioctl(fd, VIDIOC_LOG_STATUS, NULL) == 0) {
+                       printf("\nStatus Log:\n\n");
+#ifdef __linux__
+                       len = klogctl(3, buf, sizeof(buf) - 1);
+#endif
+                       if (len >= 0) {
+                               char *p = buf;
+                               char *q;
+
+                               buf[len] = 0;
+                               while ((q = strstr(p, "START STATUS"))) {
+                                       p = q + 1;
+                               }
+                               if (p) {
+                                       while (p > buf && *p != '<') p--;
+                                       q = p;
+                                       while ((q = strstr(q, "<6>"))) {
+                                               memcpy(q, "   ", 3);
+                                       }
+                                       printf("%s", p);
+                               }
+                       }
+               }
+       }
+}
+
+void common_list(int fd)
+{
+       if (options[OptListCtrlsMenus]) {
+               list_controls(fd, 1);
+       }
+
+       if (options[OptListCtrls]) {
+               list_controls(fd, 0);
+       }
+}
diff --git a/utils/v4l2-ctl/v4l2-ctl.cpp b/utils/v4l2-ctl/v4l2-ctl.cpp
index ad64751..442db3c 100644
--- a/utils/v4l2-ctl/v4l2-ctl.cpp
+++ b/utils/v4l2-ctl/v4l2-ctl.cpp
@@ -46,179 +46,16 @@
 #include <string>
 #include <algorithm>
 
-/* Short option list
-
-   Please keep in alphabetical order.
-   That makes it easier to see which short options are still free.
-
-   In general the lower case is used to set something and the upper
-   case is used to retrieve a setting. */
-enum Option {
-       OptGetSlicedVbiFormat = 'B',
-       OptSetSlicedVbiFormat = 'b',
-       OptGetCtrl = 'C',
-       OptSetCtrl = 'c',
-       OptSetDevice = 'd',
-       OptGetDriverInfo = 'D',
-       OptGetFreq = 'F',
-       OptSetFreq = 'f',
-       OptHelp = 'h',
-       OptGetInput = 'I',
-       OptSetInput = 'i',
-       OptListCtrls = 'l',
-       OptListCtrlsMenus = 'L',
-       OptListOutputs = 'N',
-       OptListInputs = 'n',
-       OptGetOutput = 'O',
-       OptSetOutput = 'o',
-       OptGetParm = 'P',
-       OptSetParm = 'p',
-       OptGetStandard = 'S',
-       OptSetStandard = 's',
-       OptGetTuner = 'T',
-       OptSetTuner = 't',
-       OptGetVideoFormat = 'V',
-       OptSetVideoFormat = 'v',
-       OptUseWrapper = 'w',
-
-       OptGetVideoMplaneFormat = 128,
-       OptSetVideoMplaneFormat,
-       OptGetSlicedVbiOutFormat,
-       OptGetOverlayFormat,
-       OptGetOutputOverlayFormat,
-       OptGetVbiFormat,
-       OptGetVbiOutFormat,
-       OptGetVideoOutFormat,
-       OptGetVideoOutMplaneFormat,
-       OptSetSlicedVbiOutFormat,
-       OptSetOutputOverlayFormat,
-       OptSetOverlayFormat,
-       //OptSetVbiFormat, TODO
-       //OptSetVbiOutFormat, TODO
-       OptSetVideoOutFormat,
-       OptSetVideoOutMplaneFormat,
-       OptTryVideoOutFormat,
-       OptTryVideoOutMplaneFormat,
-       OptTrySlicedVbiOutFormat,
-       OptTrySlicedVbiFormat,
-       OptTryVideoFormat,
-       OptTryVideoMplaneFormat,
-       OptTryOutputOverlayFormat,
-       OptTryOverlayFormat,
-       //OptTryVbiFormat, TODO
-       //OptTryVbiOutFormat, TODO
-       OptAll,
-       OptStreamOff,
-       OptStreamOn,
-       OptListStandards,
-       OptListFormats,
-       OptListMplaneFormats,
-       OptListFormatsExt,
-       OptListMplaneFormatsExt,
-       OptListFrameSizes,
-       OptListFrameIntervals,
-       OptListOverlayFormats,
-       OptListOutFormats,
-       OptListOutMplaneFormats,
-       OptLogStatus,
-       OptVerbose,
-       OptSilent,
-       OptGetSlicedVbiCap,
-       OptGetSlicedVbiOutCap,
-       OptGetFBuf,
-       OptSetFBuf,
-       OptGetCrop,
-       OptSetCrop,
-       OptGetOutputCrop,
-       OptSetOutputCrop,
-       OptGetOverlayCrop,
-       OptSetOverlayCrop,
-       OptGetOutputOverlayCrop,
-       OptSetOutputOverlayCrop,
-       OptGetSelection,
-       OptSetSelection,
-       OptGetOutputSelection,
-       OptSetOutputSelection,
-       OptGetAudioInput,
-       OptSetAudioInput,
-       OptGetAudioOutput,
-       OptSetAudioOutput,
-       OptListAudioOutputs,
-       OptListAudioInputs,
-       OptGetCropCap,
-       OptGetOutputCropCap,
-       OptGetOverlayCropCap,
-       OptGetOutputOverlayCropCap,
-       OptOverlay,
-       OptSleep,
-       OptGetJpegComp,
-       OptSetJpegComp,
-       OptGetModulator,
-       OptSetModulator,
-       OptListDevices,
-       OptGetOutputParm,
-       OptSetOutputParm,
-       OptQueryStandard,
-       OptPollForEvent,
-       OptWaitForEvent,
-       OptGetPriority,
-       OptSetPriority,
-       OptListDvPresets,
-       OptSetDvPreset,
-       OptGetDvPreset,
-       OptQueryDvPreset,
-       OptListDvTimings,
-       OptQueryDvTimings,
-       OptGetDvTimings,
-       OptSetDvBtTimings,
-       OptGetDvTimingsCap,
-       OptFreqSeek,
-       OptEncoderCmd,
-       OptTryEncoderCmd,
-       OptDecoderCmd,
-       OptTryDecoderCmd,
-       OptTunerIndex,
-       OptHelpTuner,
-       OptHelpIO,
-       OptHelpStds,
-       OptHelpVidCap,
-       OptHelpVidOut,
-       OptHelpOverlay,
-       OptHelpVbi,
-       OptHelpSelection,
-       OptHelpMisc,
-       OptHelpAll,
-       OptLast = 256
-};
 
-static char options[OptLast];
+#include "v4l2-ctl.h"
+
+char options[OptLast];
 
 static int app_result;
 static int verbose;
 
 static unsigned capabilities;
 
-typedef std::map<unsigned, std::vector<struct v4l2_ext_control> > 
class2ctrls_map;
-
-typedef std::map<std::string, struct v4l2_queryctrl> ctrl_qmap;
-static ctrl_qmap ctrl_str2q;
-typedef std::map<unsigned, std::string> ctrl_idmap;
-static ctrl_idmap ctrl_id2str;
-
-typedef std::list<std::string> ctrl_get_list;
-static ctrl_get_list get_ctrls;
-
-typedef std::map<std::string, std::string> ctrl_set_map;
-static ctrl_set_map set_ctrls;
-
-typedef std::vector<std::string> dev_vec;
-typedef std::map<std::string, std::string> dev_map;
-
-typedef struct {
-       unsigned flag;
-       const char *str;
-} flag_def;
-
 static const flag_def service_def[] = {
        { V4L2_SLICED_TELETEXT_B,  "teletext" },
        { V4L2_SLICED_VPS,         "vps" },
@@ -383,44 +220,6 @@ static struct option long_options[] = {
        {0, 0, 0, 0}
 };
 
-static void usage(void)
-{
-       printf("\nGeneral/Common options:\n"
-              "  --all              display all information available\n"
-              "  -C, --get-ctrl=<ctrl>[,<ctrl>...]\n"
-              "                     get the value of the controls 
[VIDIOC_G_EXT_CTRLS]\n"
-              "  -c, --set-ctrl=<ctrl>=<val>[,<ctrl>=<val>...]\n"
-              "                     set the value of the controls 
[VIDIOC_S_EXT_CTRLS]\n"
-              "  -D, --info         show driver info [VIDIOC_QUERYCAP]\n"
-              "  -d, --device=<dev> use device <dev> instead of /dev/video0\n"
-              "                     if <dev> is a single digit, then 
/dev/video<dev> is used\n"
-              "  -h, --help         display this help message\n"
-              "  --help-all         all options\n"
-              "  --help-io          input/output options\n"
-              "  --help-misc        miscellaneous options\n"
-              "  --help-overlay     overlay format options\n"
-              "  --help-selection   crop/selection options\n"
-              "  --help-stds        standards and other video timings 
options\n"
-              "  --help-tuner       tuner/modulator options\n"
-              "  --help-vbi         VBI format options\n"
-              "  --help-vidcap      video capture format options\n"
-              "  --help-vidout      vidout output format options\n"
-              "  -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"
-              "  -w, --wrapper      use the libv4l2 wrapper library.\n"
-              "  --list-devices     list all v4l devices\n"
-              "  --log-status       log the board status in the kernel log 
[VIDIOC_LOG_STATUS]\n"
-              "  --get-priority     query the current access priority 
[VIDIOC_G_PRIORITY]\n"
-              "  --set-priority=<prio>\n"
-              "                     set the new access priority 
[VIDIOC_S_PRIORITY]\n"
-              "                     <prio> is 1 (background), 2 (interactive) 
or 3 (record)\n"
-              "  --silent           only set the result code, do not print any 
messages\n"
-              "  --sleep=<secs>     sleep <secs>, call QUERYCAP and close the 
file handle\n"
-              "  --verbose          turn on verbose ioctl status reporting\n"
-              );
-}
-
 static void usage_tuner(void)
 {
        printf("\nTuner/Modulator options:\n"
@@ -730,7 +529,7 @@ static void usage_misc(void)
 
 static void usage_all(void)
 {
-       usage();
+       common_usage();
        usage_tuner();
        usage_io();
        usage_stds();
@@ -752,12 +551,12 @@ static int test_close(int fd)
        return options[OptUseWrapper] ? v4l2_close(fd) : close(fd);
 }
 
-static int test_ioctl(int fd, int cmd, void *arg)
+int test_ioctl(int fd, int cmd, void *arg)
 {
        return options[OptUseWrapper] ? v4l2_ioctl(fd, cmd, arg) : ioctl(fd, 
cmd, arg);
 }
 
-static int doioctl_name(int fd, unsigned long int request, void *parm, const 
char *name)
+int doioctl_name(int fd, unsigned long int request, void *parm, const char 
*name)
 {
        int retval = test_ioctl(fd, request, parm);
 
@@ -773,8 +572,6 @@ static int doioctl_name(int fd, unsigned long int request, 
void *parm, const cha
        return retval;
 }
 
-#define doioctl(n, r, p) doioctl_name(n, r, p, #r)
-
 static std::string num2s(unsigned num)
 {
        char buf[10];
@@ -878,7 +675,7 @@ static std::string colorspace2s(int val)
        }
 }
 
-static std::string flags2s(unsigned val, const flag_def *def)
+std::string flags2s(unsigned val, const flag_def *def)
 {
        std::string s;
 
@@ -956,258 +753,6 @@ static void print_sliced_vbi_cap(struct 
v4l2_sliced_vbi_cap &cap)
        }
 }
 
-static std::string name2var(unsigned char *name)
-{
-       std::string s;
-       int add_underscore = 0;
-
-       while (*name) {
-               if (isalnum(*name)) {
-                       if (add_underscore)
-                               s += '_';
-                       add_underscore = 0;
-                       s += std::string(1, tolower(*name));
-               }
-               else if (s.length()) add_underscore = 1;
-               name++;
-       }
-       return s;
-}
-
-static std::string safename(const unsigned char *name)
-{
-       std::string s;
-
-       while (*name) {
-               if (*name == '\n') {
-                       s += "\\n";
-               }
-               else if (*name == '\r') {
-                       s += "\\r";
-               }
-               else if (*name == '\f') {
-                       s += "\\f";
-               }
-               else if (*name == '\\') {
-                       s += "\\\\";
-               }
-               else if ((*name & 0x7f) < 0x20) {
-                       char buf[3];
-
-                       sprintf(buf, "%02x", *name);
-                       s += "\\x";
-                       s += buf;
-               }
-               else {
-                       s += *name;
-               }
-               name++;
-       }
-       return s;
-}
-
-static std::string safename(const char *name)
-{
-       return safename((const unsigned char *)name);
-}
-
-static std::string ctrlflags2s(__u32 flags)
-{
-       static const flag_def def[] = {
-               { V4L2_CTRL_FLAG_GRABBED,    "grabbed" },
-               { V4L2_CTRL_FLAG_DISABLED,   "disabled" },
-               { V4L2_CTRL_FLAG_READ_ONLY,  "read-only" },
-               { V4L2_CTRL_FLAG_UPDATE,     "update" },
-               { V4L2_CTRL_FLAG_INACTIVE,   "inactive" },
-               { V4L2_CTRL_FLAG_SLIDER,     "slider" },
-               { V4L2_CTRL_FLAG_WRITE_ONLY, "write-only" },
-               { V4L2_CTRL_FLAG_VOLATILE,   "volatile" },
-               { 0, NULL }
-       };
-       return flags2s(flags, def);
-}
-
-static void print_qctrl(int fd, struct v4l2_queryctrl *queryctrl,
-               struct v4l2_ext_control *ctrl, int show_menus)
-{
-       struct v4l2_querymenu qmenu;
-       std::string s = name2var(queryctrl->name);
-       int i;
-
-       memset(&qmenu, 0, sizeof(qmenu));
-       qmenu.id = queryctrl->id;
-       switch (queryctrl->type) {
-       case V4L2_CTRL_TYPE_INTEGER:
-               printf("%31s (int)    : min=%d max=%d step=%d default=%d 
value=%d",
-                               s.c_str(),
-                               queryctrl->minimum, queryctrl->maximum,
-                               queryctrl->step, queryctrl->default_value,
-                               ctrl->value);
-               break;
-       case V4L2_CTRL_TYPE_INTEGER64:
-               printf("%31s (int64)  : value=%lld", s.c_str(), ctrl->value64);
-               break;
-       case V4L2_CTRL_TYPE_STRING:
-               printf("%31s (str)    : min=%d max=%d step=%d value='%s'",
-                               s.c_str(),
-                               queryctrl->minimum, queryctrl->maximum,
-                               queryctrl->step, 
safename(ctrl->string).c_str());
-               break;
-       case V4L2_CTRL_TYPE_BOOLEAN:
-               printf("%31s (bool)   : default=%d value=%d",
-                               s.c_str(),
-                               queryctrl->default_value, ctrl->value);
-               break;
-       case V4L2_CTRL_TYPE_MENU:
-               printf("%31s (menu)   : min=%d max=%d default=%d value=%d",
-                               s.c_str(),
-                               queryctrl->minimum, queryctrl->maximum,
-                               queryctrl->default_value, ctrl->value);
-               break;
-       case V4L2_CTRL_TYPE_INTEGER_MENU:
-               printf("%31s (intmenu): min=%d max=%d default=%d value=%d",
-                               s.c_str(),
-                               queryctrl->minimum, queryctrl->maximum,
-                               queryctrl->default_value, ctrl->value);
-               break;
-       case V4L2_CTRL_TYPE_BUTTON:
-               printf("%31s (button) :", s.c_str());
-               break;
-       case V4L2_CTRL_TYPE_BITMASK:
-               printf("%31s (bitmask): max=0x%08x default=0x%08x value=0x%08x",
-                               s.c_str(), queryctrl->maximum,
-                               queryctrl->default_value, ctrl->value);
-               break;
-       default: break;
-       }
-       if (queryctrl->flags)
-               printf(" flags=%s", ctrlflags2s(queryctrl->flags).c_str());
-       printf("\n");
-       if ((queryctrl->type == V4L2_CTRL_TYPE_MENU ||
-            queryctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) && show_menus) {
-               for (i = queryctrl->minimum; i <= queryctrl->maximum; i++) {
-                       qmenu.index = i;
-                       if (test_ioctl(fd, VIDIOC_QUERYMENU, &qmenu))
-                               continue;
-                       if (queryctrl->type == V4L2_CTRL_TYPE_MENU)
-                               printf("\t\t\t\t%d: %s\n", i, qmenu.name);
-                       else
-                               printf("\t\t\t\t%d: %lld (0x%llx)\n", i, 
qmenu.value, qmenu.value);
-               }
-       }
-}
-
-static int print_control(int fd, struct v4l2_queryctrl &qctrl, int show_menus)
-{
-       struct v4l2_control ctrl;
-       struct v4l2_ext_control ext_ctrl;
-       struct v4l2_ext_controls ctrls;
-
-       memset(&ctrl, 0, sizeof(ctrl));
-       memset(&ext_ctrl, 0, sizeof(ext_ctrl));
-       memset(&ctrls, 0, sizeof(ctrls));
-       if (qctrl.flags & V4L2_CTRL_FLAG_DISABLED)
-               return 1;
-       if (qctrl.type == V4L2_CTRL_TYPE_CTRL_CLASS) {
-               printf("\n%s\n\n", 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);
-               return 1;
-       }
-       ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(qctrl.id);
-       ctrls.count = 1;
-       ctrls.controls = &ext_ctrl;
-       if (qctrl.type == V4L2_CTRL_TYPE_INTEGER64 ||
-           qctrl.type == V4L2_CTRL_TYPE_STRING ||
-           (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_USER &&
-            qctrl.id < V4L2_CID_PRIVATE_BASE)) {
-               if (qctrl.type == V4L2_CTRL_TYPE_STRING) {
-                   ext_ctrl.size = qctrl.maximum + 1;
-                   ext_ctrl.string = (char *)malloc(ext_ctrl.size);
-                   ext_ctrl.string[0] = 0;
-               }
-               if (test_ioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls)) {
-                       printf("error %d getting ext_ctrl %s\n",
-                                       errno, qctrl.name);
-                       return 0;
-               }
-       }
-       else {
-               ctrl.id = qctrl.id;
-               if (test_ioctl(fd, VIDIOC_G_CTRL, &ctrl)) {
-                       printf("error %d getting ctrl %s\n",
-                                       errno, qctrl.name);
-                       return 0;
-               }
-               ext_ctrl.value = ctrl.value;
-       }
-       print_qctrl(fd, &qctrl, &ext_ctrl, show_menus);
-       if (qctrl.type == V4L2_CTRL_TYPE_STRING)
-               free(ext_ctrl.string);
-       return 1;
-}
-
-static void list_controls(int fd, int show_menus)
-{
-       struct v4l2_queryctrl qctrl;
-       int id;
-
-       memset(&qctrl, 0, sizeof(qctrl));
-       qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
-       while (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
-                       print_control(fd, qctrl, show_menus);
-               qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
-       }
-       if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL)
-               return;
-       for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
-               qctrl.id = id;
-               if (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0)
-                       print_control(fd, qctrl, show_menus);
-       }
-       for (qctrl.id = V4L2_CID_PRIVATE_BASE;
-                       test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; 
qctrl.id++) {
-               print_control(fd, qctrl, show_menus);
-       }
-}
-
-static void find_controls(int fd)
-{
-       struct v4l2_queryctrl qctrl;
-       int id;
-
-       memset(&qctrl, 0, sizeof(qctrl));
-       qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
-       while (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0) {
-               if (qctrl.type != V4L2_CTRL_TYPE_CTRL_CLASS &&
-                   !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
-                       ctrl_str2q[name2var(qctrl.name)] = qctrl;
-                       ctrl_id2str[qctrl.id] = name2var(qctrl.name);
-               }
-               qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
-       }
-       if (qctrl.id != V4L2_CTRL_FLAG_NEXT_CTRL)
-               return;
-       for (id = V4L2_CID_USER_BASE; id < V4L2_CID_LASTP1; id++) {
-               qctrl.id = id;
-               if (test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0 &&
-                   !(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
-                       ctrl_str2q[name2var(qctrl.name)] = qctrl;
-                       ctrl_id2str[qctrl.id] = name2var(qctrl.name);
-               }
-       }
-       for (qctrl.id = V4L2_CID_PRIVATE_BASE;
-                       test_ioctl(fd, VIDIOC_QUERYCTRL, &qctrl) == 0; 
qctrl.id++) {
-               if (!(qctrl.flags & V4L2_CTRL_FLAG_DISABLED)) {
-                       ctrl_str2q[name2var(qctrl.name)] = qctrl;
-                       ctrl_id2str[qctrl.id] = name2var(qctrl.name);
-               }
-       }
-}
 
 static std::string fbufcap2s(unsigned cap)
 {
@@ -1759,120 +1304,6 @@ static v4l2_std_id parse_ntsc(const char *ntsc)
        return 0;
 }
 
-static bool is_v4l_dev(const char *name)
-{
-       return !memcmp(name, "vtx", 3) ||
-               !memcmp(name, "video", 5) ||
-               !memcmp(name, "radio", 5) ||
-               !memcmp(name, "vbi", 3);
-}
-
-static int calc_node_val(const char *s)
-{
-       int n = 0;
-
-       s = strrchr(s, '/') + 1;
-       if (!memcmp(s, "video", 5)) n = 0;
-       else if (!memcmp(s, "radio", 5)) n = 0x100;
-       else if (!memcmp(s, "vbi", 3)) n = 0x200;
-       else if (!memcmp(s, "vtx", 3)) n = 0x300;
-       n += atol(s + (n >= 0x200 ? 3 : 5));
-       return n;
-}
-
-static bool sort_on_device_name(const std::string &s1, const std::string &s2)
-{
-       int n1 = calc_node_val(s1.c_str());
-       int n2 = calc_node_val(s2.c_str());
-
-       return n1 < n2;
-}
-
-static void list_devices()
-{
-       DIR *dp;
-       struct dirent *ep;
-       dev_vec files;
-       dev_map links;
-       dev_map cards;
-       struct v4l2_capability vcap;
-
-       dp = opendir("/dev");
-       if (dp == NULL) {
-               perror ("Couldn't open the directory");
-               return;
-       }
-       while ((ep = readdir(dp)))
-               if (is_v4l_dev(ep->d_name))
-                       files.push_back(std::string("/dev/") + ep->d_name);
-       closedir(dp);
-
-#if 0
-       dp = opendir("/dev/v4l");
-       if (dp) {
-               while (ep = readdir(dp))
-                       if (is_v4l_dev(ep->d_name))
-                               files.push_back(std::string("/dev/v4l/") + 
ep->d_name);
-               closedir(dp);
-       }
-#endif
-
-       /* Find device nodes which are links to other device nodes */
-       for (dev_vec::iterator iter = files.begin();
-                       iter != files.end(); ) {
-               char link[64+1];
-               int link_len;
-               std::string target;
-
-               link_len = readlink(iter->c_str(), link, 64);
-               if (link_len < 0) {     /* Not a link or error */
-                       iter++;
-                       continue;
-               }
-               link[link_len] = '\0';
-
-               /* Only remove from files list if target itself is in list */
-               if (link[0] != '/')     /* Relative link */
-                       target = std::string("/dev/");
-               target += link;
-               if (find(files.begin(), files.end(), target) == files.end()) {
-                       iter++;
-                       continue;
-               }
-
-               /* Move the device node from files to links */
-               if (links[target].empty())
-                       links[target] = *iter;
-               else
-                       links[target] += ", " + *iter;
-               files.erase(iter);
-       }
-
-       std::sort(files.begin(), files.end(), sort_on_device_name);
-
-       for (dev_vec::iterator iter = files.begin();
-                       iter != files.end(); ++iter) {
-               int fd = open(iter->c_str(), O_RDWR);
-               std::string bus_info;
-
-               if (fd < 0)
-                       continue;
-               doioctl(fd, VIDIOC_QUERYCAP, &vcap);
-               close(fd);
-               bus_info = (const char *)vcap.bus_info;
-               if (cards[bus_info].empty())
-                       cards[bus_info] += std::string((char *)vcap.card) + " 
(" + bus_info + "):\n";
-               cards[bus_info] += "\t" + (*iter);
-               if (!(links[*iter].empty()))
-                       cards[bus_info] += " <- " + links[*iter];
-               cards[bus_info] += "\n";
-       }
-       for (dev_map::iterator iter = cards.begin();
-                       iter != cards.end(); ++iter) {
-               printf("%s\n", iter->second.c_str());
-       }
-}
-
 static int parse_subopt(char **subs, const char * const *subopts, char **value)
 {
        int opt = getsubopt(subs, (char * const *)subopts, value);
@@ -1889,21 +1320,6 @@ static int parse_subopt(char **subs, const char * const 
*subopts, char **value)
        return opt;
 }
 
-static bool parse_next_subopt(char **subs, char **value)
-{
-       static char *const subopts[] = {
-           NULL
-       };
-       int opt = getsubopt(subs, subopts, value);
-
-       if (value == NULL) {
-               fprintf(stderr, "No value given to suboption <%s>\n",
-                               subopts[opt]);
-               return true;
-       }
-       return false;
-}
-
 static std::string partstd2s(const char *prefix, const char *stds[], unsigned 
long long std)
 {
        std::string s = std::string(prefix) + "-";
@@ -2410,8 +1826,6 @@ static enum v4l2_field parse_field(const char *s)
 
 static void print_event(const struct v4l2_event *ev)
 {
-       const struct v4l2_event_ctrl *ctrl;
-
        printf("%ld.%06ld: event %u, pending %u: ",
                        ev->timestamp.tv_sec, ev->timestamp.tv_nsec / 1000,
                        ev->sequence, ev->pending);
@@ -2423,16 +1837,7 @@ static void print_event(const struct v4l2_event *ev)
                printf("eos\n");
                break;
        case V4L2_EVENT_CTRL:
-               ctrl = &ev->u.ctrl;
-               printf("ctrl: %s\n", ctrl_id2str[ev->id].c_str());
-               if (ctrl->changes & V4L2_EVENT_CTRL_CH_VALUE) {
-                       if (ctrl->type == V4L2_CTRL_TYPE_INTEGER64)
-                               printf("\tvalue: %lld 0x%llx\n", ctrl->value64, 
ctrl->value64);
-                       else
-                               printf("\tvalue: %d 0x%x\n", ctrl->value, 
ctrl->value);
-               }
-               if (ctrl->changes & V4L2_EVENT_CTRL_CH_FLAGS)
-                       printf("\tflags: %s\n", 
ctrlflags2s(ctrl->flags).c_str());
+               common_control_event(ev);
                break;
        case V4L2_EVENT_FRAME_SYNC:
                printf("frame_sync %d\n", ev->u.frame_sync.frame_sequence);
@@ -2559,12 +1964,11 @@ int main(int argc, char **argv)
        int overlay;                    /* overlay */
        unsigned int *set_overlay_fmt_ptr = NULL;
        struct v4l2_format *overlay_fmt_ptr = NULL;
+       unsigned secs = 0;
        __u32 wait_for_event = 0;       /* wait for this event */
        const char *wait_event_id = NULL;
        __u32 poll_for_event = 0;       /* poll for this event */
        const char *poll_event_id = NULL;
-       unsigned secs = 0;
-       enum v4l2_priority prio = V4L2_PRIORITY_UNSET;
        char short_options[26 * 2 * 2 + 1];
        int idx = 0;
        int ret;
@@ -2604,7 +2008,7 @@ int main(int argc, char **argv)
        memset(&freq_seek, 0, sizeof(freq_seek));
 
        if (argc == 1) {
-               usage();
+               common_usage();
                return 0;
        }
        for (i = 0; long_options[i].name; i++) {
@@ -2626,7 +2030,7 @@ int main(int argc, char **argv)
                options[(int)ch] = 1;
                switch (ch) {
                case OptHelp:
-                       usage();
+                       common_usage();
                        return 0;
                case OptHelpTuner:
                        usage_tuner();
@@ -2668,6 +2072,9 @@ int main(int argc, char **argv)
                                device = newdev;
                        }
                        break;
+               case OptSleep:
+                       secs = strtoul(optarg, 0L, 0);
+                       break;
                case OptSetVideoOutMplaneFormat:
                case OptTryVideoOutMplaneFormat:
                case OptSetVideoOutFormat:
@@ -2970,38 +2377,6 @@ int main(int argc, char **argv)
                case OptSetOutputParm:
                        output_fps = strtod(optarg, NULL);
                        break;
-               case OptGetCtrl:
-                       subs = optarg;
-                       while (*subs != '\0') {
-                               if (parse_next_subopt(&subs, &value)) {
-                                   usage();
-                                   exit(1);
-                               }
-                               if (strchr(value, '=')) {
-                                   usage();
-                                   exit(1);
-                               }
-                               else {
-                                   get_ctrls.push_back(value);
-                               }
-                       }
-                       break;
-               case OptSetCtrl:
-                       subs = optarg;
-                       while (*subs != '\0') {
-                               if (parse_next_subopt(&subs, &value)) {
-                                   usage();
-                                   exit(1);
-                               }
-                               if (const char *equal = strchr(value, '=')) {
-                                   set_ctrls[std::string(value, (equal - 
value))] = equal + 1;
-                               }
-                               else {
-                                   fprintf(stderr, "control '%s' without 
'='\n", value);
-                                   exit(1);
-                               }
-                       }
-                       break;
                case OptSetTuner:
                        if (!strcmp(optarg, "stereo"))
                                mode = V4L2_TUNER_MODE_STEREO;
@@ -3153,12 +2528,6 @@ int main(int argc, char **argv)
                        }
                        break;
                }
-               case OptSleep:
-                       secs = strtoul(optarg, 0L, 0);
-                       break;
-               case OptSetPriority:
-                       prio = (enum v4l2_priority)strtoul(optarg, 0L, 0);
-                       break;
                case OptWaitForEvent:
                        wait_for_event = parse_event(optarg, &wait_event_id);
                        if (wait_for_event == 0)
@@ -3169,9 +2538,6 @@ int main(int argc, char **argv)
                        if (poll_for_event == 0)
                                return 1;
                        break;
-               case OptListDevices:
-                       list_devices();
-                       break;
                case OptSetDvPreset:
                        dv_preset.preset = strtoul(optarg, 0L, 0);
                        break;
@@ -3249,13 +2615,16 @@ int main(int argc, char **argv)
                case ':':
                        fprintf(stderr, "Option '%s' requires a value\n",
                                argv[optind]);
-                       usage();
+                       common_usage();
                        return 1;
                case '?':
                        if (argv[optind])
                                fprintf(stderr, "Unknown argument '%s'\n", 
argv[optind]);
-                       usage();
+                       common_usage();
                        return 1;
+               default:
+                       common_cmd(ch, optarg);
+                       break;
                }
        }
        if (optind < argc) {
@@ -3263,7 +2632,7 @@ int main(int argc, char **argv)
                while (optind < argc)
                        printf("%s ", argv[optind++]);
                printf("\n");
-               usage();
+               common_usage();
                return 1;
        }
 
@@ -3276,26 +2645,16 @@ int main(int argc, char **argv)
        verbose = options[OptVerbose];
        doioctl(fd, VIDIOC_QUERYCAP, &vcap);
        capabilities = vcap.capabilities;
-       find_controls(fd);
-       for (ctrl_get_list::iterator iter = get_ctrls.begin(); iter != 
get_ctrls.end(); ++iter) {
-           if (ctrl_str2q.find(*iter) == ctrl_str2q.end()) {
-               fprintf(stderr, "unknown control '%s'\n", (*iter).c_str());
-               exit(1);
-           }
-       }
-       for (ctrl_set_map::iterator iter = set_ctrls.begin(); iter != 
set_ctrls.end(); ++iter) {
-           if (ctrl_str2q.find(iter->first) == ctrl_str2q.end()) {
-               fprintf(stderr, "unknown control '%s'\n", iter->first.c_str());
-               exit(1);
-           }
-       }
+
+       common_process_controls(fd);
+
        if (wait_for_event == V4L2_EVENT_CTRL && wait_event_id)
-               if (ctrl_str2q.find(wait_event_id) == ctrl_str2q.end()) {
+               if (!common_find_ctrl_id(wait_event_id)) {
                        fprintf(stderr, "unknown control '%s'\n", 
wait_event_id);
                        exit(1);
                }
        if (poll_for_event == V4L2_EVENT_CTRL && poll_event_id)
-               if (ctrl_str2q.find(poll_event_id) == ctrl_str2q.end()) {
+               if (!common_find_ctrl_id(poll_event_id)) {
                        fprintf(stderr, "unknown control '%s'\n", 
poll_event_id);
                        exit(1);
                }
@@ -3331,6 +2690,7 @@ int main(int argc, char **argv)
                options[OptGetPriority] = 1;
                options[OptGetSelection] = 1;
                options[OptGetOutputSelection] = 1;
+               options[OptListCtrls] = 1;
                get_sel_target = -1;
                options[OptSilent] = 1;
        }
@@ -3363,11 +2723,7 @@ int main(int argc, char **argv)
                doioctl(fd, VIDIOC_STREAMOFF, &type);
        }
 
-       if (options[OptSetPriority]) {
-               if (doioctl(fd, VIDIOC_S_PRIORITY, &prio) >= 0) {
-                       printf("Priority set: %d\n", prio);
-               }
-       }
+       common_set(fd);
 
        if (options[OptSetFreq]) {
                double fac = 16;
@@ -3731,78 +3087,6 @@ int main(int argc, char **argv)
        if (options[OptSetOutputSelection]) {
                do_selection(fd, set_selection_out, vselection_out, 
V4L2_BUF_TYPE_VIDEO_OUTPUT);
        }
-
-       if (options[OptSetCtrl] && !set_ctrls.empty()) {
-               struct v4l2_ext_controls ctrls;
-               class2ctrls_map class2ctrls;
-               bool use_ext_ctrls = false;
-
-               memset(&ctrls, 0, sizeof(ctrls));
-               for (ctrl_set_map::iterator iter = set_ctrls.begin();
-                               iter != set_ctrls.end(); ++iter) {
-                       struct v4l2_ext_control ctrl;
-
-                       memset(&ctrl, 0, sizeof(ctrl));
-                       ctrl.id = ctrl_str2q[iter->first].id;
-                       if (ctrl_str2q[iter->first].type == 
V4L2_CTRL_TYPE_INTEGER64)
-                               use_ext_ctrls = true;
-                       if (ctrl_str2q[iter->first].type == 
V4L2_CTRL_TYPE_STRING) {
-                               unsigned len = iter->second.length();
-                               unsigned maxlen = 
ctrl_str2q[iter->first].maximum;
-
-                               use_ext_ctrls = true;
-                               ctrl.size = maxlen + 1;
-                               ctrl.string = (char *)malloc(ctrl.size);
-                               if (len > maxlen) {
-                                       memcpy(ctrl.string, 
iter->second.c_str(), maxlen);
-                                       ctrl.string[maxlen] = 0;
-                               }
-                               else {
-                                       strcpy(ctrl.string, 
iter->second.c_str());
-                               }
-                       } else {
-                               if (V4L2_CTRL_DRIVER_PRIV(ctrl.id))
-                                       use_ext_ctrls = true;
-                               ctrl.value = strtol(iter->second.c_str(), NULL, 
0);
-                       }
-                       
class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl);
-               }
-               for (class2ctrls_map::iterator iter = class2ctrls.begin();
-                               iter != class2ctrls.end(); ++iter) {
-                       if (!use_ext_ctrls &&
-                           (iter->first == V4L2_CTRL_CLASS_USER ||
-                            iter->first == V4L2_CID_PRIVATE_BASE)) {
-                               for (unsigned i = 0; i < iter->second.size(); 
i++) {
-                                       struct v4l2_control ctrl;
-
-                                       ctrl.id = iter->second[i].id;
-                                       ctrl.value = iter->second[i].value;
-                                       if (doioctl(fd, VIDIOC_S_CTRL, &ctrl)) {
-                                               fprintf(stderr, "%s: %s\n",
-                                                               
ctrl_id2str[ctrl.id].c_str(),
-                                                               
strerror(errno));
-                                       }
-                               }
-                               continue;
-                       }
-                       if (iter->second.size()) {
-                               ctrls.ctrl_class = iter->first;
-                               ctrls.count = iter->second.size();
-                               ctrls.controls = &iter->second[0];
-                               if (doioctl(fd, VIDIOC_S_EXT_CTRLS, &ctrls)) {
-                                       if (ctrls.error_idx >= ctrls.count) {
-                                               fprintf(stderr, "Error setting 
MPEG controls: %s\n",
-                                                               
strerror(errno));
-                                       }
-                                       else {
-                                               fprintf(stderr, "%s: %s\n",
-                                                               
ctrl_id2str[iter->second[ctrls.error_idx].id].c_str(),
-                                                               
strerror(errno));
-                                       }
-                               }
-                       }
-               }
-       }
        
        if (options[OptFreqSeek]) {
                freq_seek.tuner = tuner_index;
@@ -4170,62 +3454,6 @@ int main(int argc, char **argv)
                }
        }
 
-       if (options[OptGetCtrl] && !get_ctrls.empty()) {
-               struct v4l2_ext_controls ctrls;
-               class2ctrls_map class2ctrls;
-               bool use_ext_ctrls = false;
-
-               memset(&ctrls, 0, sizeof(ctrls));
-               for (ctrl_get_list::iterator iter = get_ctrls.begin();
-                               iter != get_ctrls.end(); ++iter) {
-                       struct v4l2_ext_control ctrl;
-
-                       memset(&ctrl, 0, sizeof(ctrl));
-                       ctrl.id = ctrl_str2q[*iter].id;
-                       if (ctrl_str2q[*iter].type == V4L2_CTRL_TYPE_INTEGER64)
-                               use_ext_ctrls = true;
-                       if (ctrl_str2q[*iter].type == V4L2_CTRL_TYPE_STRING) {
-                               use_ext_ctrls = true;
-                               ctrl.size = ctrl_str2q[*iter].maximum + 1;
-                               ctrl.string = (char *)malloc(ctrl.size);
-                               ctrl.string[0] = 0;
-                       }
-                       if (V4L2_CTRL_DRIVER_PRIV(ctrl.id))
-                               use_ext_ctrls = true;
-                       
class2ctrls[V4L2_CTRL_ID2CLASS(ctrl.id)].push_back(ctrl);
-               }
-               for (class2ctrls_map::iterator iter = class2ctrls.begin();
-                               iter != class2ctrls.end(); ++iter) {
-                       if (!use_ext_ctrls &&
-                           (iter->first == V4L2_CTRL_CLASS_USER ||
-                            iter->first == V4L2_CID_PRIVATE_BASE)) {
-                               for (unsigned i = 0; i < iter->second.size(); 
i++) {
-                                       struct v4l2_control ctrl;
-
-                                       ctrl.id = iter->second[i].id;
-                                       doioctl(fd, VIDIOC_G_CTRL, &ctrl);
-                                       printf("%s: %d\n", 
ctrl_id2str[ctrl.id].c_str(), ctrl.value);
-                               }
-                               continue;
-                       }
-                       if (iter->second.size()) {
-                               ctrls.ctrl_class = iter->first;
-                               ctrls.count = iter->second.size();
-                               ctrls.controls = &iter->second[0];
-                               doioctl(fd, VIDIOC_G_EXT_CTRLS, &ctrls);
-                               for (unsigned i = 0; i < iter->second.size(); 
i++) {
-                                       struct v4l2_ext_control ctrl = 
iter->second[i];
-
-                                       if 
(ctrl_str2q[ctrl_id2str[ctrl.id]].type == V4L2_CTRL_TYPE_STRING)
-                                               printf("%s: '%s'\n", 
ctrl_id2str[ctrl.id].c_str(),
-                                                              
safename(ctrl.string).c_str());
-                                       else
-                                               printf("%s: %d\n", 
ctrl_id2str[ctrl.id].c_str(), ctrl.value);
-                               }
-                       }
-               }
-       }
-
        if (options[OptGetTuner]) {
                struct v4l2_tuner vt;
 
@@ -4268,38 +3496,6 @@ int main(int argc, char **argv)
                }
        }
 
-       if (options[OptGetPriority]) {
-               if (doioctl(fd, VIDIOC_G_PRIORITY, &prio) == 0)
-                       printf("Priority: %d\n", prio);
-       }
-
-       if (options[OptLogStatus]) {
-               static char buf[40960];
-               int len;
-
-               if (doioctl(fd, VIDIOC_LOG_STATUS, NULL) == 0) {
-                       printf("\nStatus Log:\n\n");
-                       len = klogctl(3, buf, sizeof(buf) - 1);
-                       if (len >= 0) {
-                               char *p = buf;
-                               char *q;
-
-                               buf[len] = 0;
-                               while ((q = strstr(p, "START STATUS"))) {
-                                       p = q + 1;
-                               }
-                               if (p) {
-                                       while (p > buf && *p != '<') p--;
-                                       q = p;
-                                       while ((q = strstr(q, "<6>"))) {
-                                               memcpy(q, "   ", 3);
-                                       }
-                                       printf("%s", p);
-                               }
-                       }
-               }
-       }
-
        /* List options */
 
        if (options[OptListInputs]) {
@@ -4434,6 +3630,8 @@ int main(int argc, char **argv)
                print_video_formats(fd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE);
        }
 
+       common_list(fd);
+
        if (options[OptGetSlicedVbiCap]) {
                struct v4l2_sliced_vbi_cap cap;
 
@@ -4452,14 +3650,6 @@ int main(int argc, char **argv)
                }
        }
 
-       if (options[OptListCtrlsMenus]) {
-               list_controls(fd, 1);
-       }
-
-       if (options[OptListCtrls]) {
-               list_controls(fd, 0);
-       }
-
        if (options[OptListDvPresets]) {
                dv_enum_preset.index = 0;
                printf("ioctl: VIDIOC_ENUM_DV_PRESETS\n");
@@ -4500,7 +3690,7 @@ int main(int argc, char **argv)
                memset(&sub, 0, sizeof(sub));
                sub.type = wait_for_event;
                if (wait_for_event == V4L2_EVENT_CTRL)
-                       sub.id = ctrl_str2q[wait_event_id].id;
+                       sub.id = common_find_ctrl_id(wait_event_id);
                if (!doioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub))
                        if (!doioctl(fd, VIDIOC_DQEVENT, &ev))
                                print_event(&ev);
@@ -4514,7 +3704,7 @@ int main(int argc, char **argv)
                sub.flags = V4L2_EVENT_SUB_FL_SEND_INITIAL;
                sub.type = poll_for_event;
                if (poll_for_event == V4L2_EVENT_CTRL)
-                       sub.id = ctrl_str2q[poll_event_id].id;
+                       sub.id = common_find_ctrl_id(poll_event_id);
                if (!doioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub)) {
                        fd_set fds;
                        __u32 seq = 0;
diff --git a/utils/v4l2-ctl/v4l2-ctl.h b/utils/v4l2-ctl/v4l2-ctl.h
new file mode 100644
index 0000000..6b0f65c
--- /dev/null
+++ b/utils/v4l2-ctl/v4l2-ctl.h
@@ -0,0 +1,174 @@
+#ifndef _V4L2_CTL_H
+#define _V4L2_CTL_H
+
+/* Available options.
+
+   Please keep the first part (options < 128) in alphabetical order.
+   That makes it easier to see which short options are still free.
+
+   In general the lower case is used to set something and the upper
+   case is used to retrieve a setting. */
+enum Option {
+       OptGetSlicedVbiFormat = 'B',
+       OptSetSlicedVbiFormat = 'b',
+       OptGetCtrl = 'C',
+       OptSetCtrl = 'c',
+       OptSetDevice = 'd',
+       OptGetDriverInfo = 'D',
+       OptGetFreq = 'F',
+       OptSetFreq = 'f',
+       OptHelp = 'h',
+       OptGetInput = 'I',
+       OptSetInput = 'i',
+       OptListCtrls = 'l',
+       OptListCtrlsMenus = 'L',
+       OptListOutputs = 'N',
+       OptListInputs = 'n',
+       OptGetOutput = 'O',
+       OptSetOutput = 'o',
+       OptGetParm = 'P',
+       OptSetParm = 'p',
+       OptGetStandard = 'S',
+       OptSetStandard = 's',
+       OptGetTuner = 'T',
+       OptSetTuner = 't',
+       OptGetVideoFormat = 'V',
+       OptSetVideoFormat = 'v',
+       OptUseWrapper = 'w',
+
+       OptGetVideoMplaneFormat = 128,
+       OptSetVideoMplaneFormat,
+       OptGetSlicedVbiOutFormat,
+       OptGetOverlayFormat,
+       OptGetOutputOverlayFormat,
+       OptGetVbiFormat,
+       OptGetVbiOutFormat,
+       OptGetVideoOutFormat,
+       OptGetVideoOutMplaneFormat,
+       OptSetSlicedVbiOutFormat,
+       OptSetOutputOverlayFormat,
+       OptSetOverlayFormat,
+       //OptSetVbiFormat, TODO
+       //OptSetVbiOutFormat, TODO
+       OptSetVideoOutFormat,
+       OptSetVideoOutMplaneFormat,
+       OptTryVideoOutFormat,
+       OptTryVideoOutMplaneFormat,
+       OptTrySlicedVbiOutFormat,
+       OptTrySlicedVbiFormat,
+       OptTryVideoFormat,
+       OptTryVideoMplaneFormat,
+       OptTryOutputOverlayFormat,
+       OptTryOverlayFormat,
+       //OptTryVbiFormat, TODO
+       //OptTryVbiOutFormat, TODO
+       OptAll,
+       OptStreamOff,
+       OptStreamOn,
+       OptListStandards,
+       OptListFormats,
+       OptListMplaneFormats,
+       OptListFormatsExt,
+       OptListMplaneFormatsExt,
+       OptListFrameSizes,
+       OptListFrameIntervals,
+       OptListOverlayFormats,
+       OptListOutFormats,
+       OptListOutMplaneFormats,
+       OptLogStatus,
+       OptVerbose,
+       OptSilent,
+       OptGetSlicedVbiCap,
+       OptGetSlicedVbiOutCap,
+       OptGetFBuf,
+       OptSetFBuf,
+       OptGetCrop,
+       OptSetCrop,
+       OptGetOutputCrop,
+       OptSetOutputCrop,
+       OptGetOverlayCrop,
+       OptSetOverlayCrop,
+       OptGetOutputOverlayCrop,
+       OptSetOutputOverlayCrop,
+       OptGetSelection,
+       OptSetSelection,
+       OptGetOutputSelection,
+       OptSetOutputSelection,
+       OptGetAudioInput,
+       OptSetAudioInput,
+       OptGetAudioOutput,
+       OptSetAudioOutput,
+       OptListAudioOutputs,
+       OptListAudioInputs,
+       OptGetCropCap,
+       OptGetOutputCropCap,
+       OptGetOverlayCropCap,
+       OptGetOutputOverlayCropCap,
+       OptOverlay,
+       OptSleep,
+       OptGetJpegComp,
+       OptSetJpegComp,
+       OptGetModulator,
+       OptSetModulator,
+       OptListDevices,
+       OptGetOutputParm,
+       OptSetOutputParm,
+       OptQueryStandard,
+       OptPollForEvent,
+       OptWaitForEvent,
+       OptGetPriority,
+       OptSetPriority,
+       OptListDvPresets,
+       OptSetDvPreset,
+       OptGetDvPreset,
+       OptQueryDvPreset,
+       OptListDvTimings,
+       OptQueryDvTimings,
+       OptGetDvTimings,
+       OptSetDvBtTimings,
+       OptGetDvTimingsCap,
+       OptFreqSeek,
+       OptEncoderCmd,
+       OptTryEncoderCmd,
+       OptDecoderCmd,
+       OptTryDecoderCmd,
+       OptTunerIndex,
+       OptHelpTuner,
+       OptHelpIO,
+       OptHelpStds,
+       OptHelpVidCap,
+       OptHelpVidOut,
+       OptHelpOverlay,
+       OptHelpVbi,
+       OptHelpSelection,
+       OptHelpMisc,
+       OptHelpAll,
+       OptLast = 256
+};
+
+extern char options[OptLast];
+
+typedef struct {
+       unsigned flag;
+       const char *str;
+} flag_def;
+
+// v4l2-ctl.cpp
+int doioctl_name(int fd, unsigned long int request, void *parm, const char 
*name);
+int test_ioctl(int fd, int cmd, void *arg);
+std::string flags2s(unsigned val, const flag_def *def);
+
+#define doioctl(n, r, p) doioctl_name(n, r, p, #r)
+
+// v4l2-ctl-common.cpp
+void common_usage(void);
+void common_cmd(int ch, char *optarg);
+void common_set(int fd);
+void common_get(int fd);
+void common_list(int fd);
+void common_process_controls(int fd);
+void common_control_event(const struct v4l2_event *ev);
+int common_find_ctrl_id(const char *name);
+
+
+#endif

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to