diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-06-03 09:17:43 +0200 |
---|---|---|
committer | Michael Olbrich <m.olbrich@pengutronix.de> | 2013-09-13 16:29:48 +0200 |
commit | 6301914bc5eb89878255495b206caa04251bef33 (patch) | |
tree | 381b5a6f01f49b07f00c1afd796312d2d755d421 | |
parent | 5290e247a8bdabc6de075fd5fe0c2007ff04f25f (diff) | |
download | gst-plugins-good-6301914bc5eb89878255495b206caa04251bef33.tar.gz gst-plugins-good-6301914bc5eb89878255495b206caa04251bef33.tar.xz |
v4l2: iterate controls with V4L2_CTRL_FLAG_NEXT_CTRL if possible
In v2.6.18 control classes where added to the v4l2 API.
Iterating over CIDs starting with V4L2_CID_BASE will only find controls for
the first control class.
By iterating with V4L2_CTRL_FLAG_NEXT_CTRL all controls are found.
This is necessary to make controls from other control classes available in
the extra-controls property.
If V4L2_CTRL_FLAG_NEXT_CTRL is not defined at compile time or not supported
at runtime then the old mechanism for iterating is used.
https://bugzilla.gnome.org/show_bug.cgi?id=701540
-rw-r--r-- | sys/v4l2/v4l2_calls.c | 37 |
1 files changed, 33 insertions, 4 deletions
diff --git a/sys/v4l2/v4l2_calls.c b/sys/v4l2/v4l2_calls.c index 1b6d5f4b0..4ace236ac 100644 --- a/sys/v4l2/v4l2_calls.c +++ b/sys/v4l2/v4l2_calls.c @@ -109,7 +109,8 @@ cap_failed: static gboolean gst_v4l2_fill_lists (GstV4l2Object * v4l2object) { - gint n; + gint n, next; + struct v4l2_queryctrl control = { 0, }; GstElement *e; @@ -236,11 +237,21 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object) GST_DEBUG_OBJECT (e, " controls+menus"); /* and lastly, controls+menus (if appropriate) */ - for (n = V4L2_CID_BASE;; n++) { - struct v4l2_queryctrl control = { 0, }; +#ifdef V4L2_CTRL_FLAG_NEXT_CTRL + next = V4L2_CTRL_FLAG_NEXT_CTRL; + n = 0; +#else + next = 0; + n = V4L2_CID_BASE; +#endif + control.id = next; + while (TRUE) { GstV4l2ColorBalanceChannel *v4l2channel; GstColorBalanceChannel *channel; + if (!next) + n++; + /* when we reached the last official CID, continue with private CIDs */ if (n == V4L2_CID_LASTP1) { GST_DEBUG_OBJECT (e, "checking private CIDs"); @@ -248,8 +259,19 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object) } GST_DEBUG_OBJECT (e, "checking control %08x", n); - control.id = n; + control.id = n | next; if (v4l2_ioctl (v4l2object->video_fd, VIDIOC_QUERYCTRL, &control) < 0) { + if (next) { + if (n > 0) { + GST_DEBUG_OBJECT (e, "controls finished"); + break; + } else { + GST_DEBUG_OBJECT (e, "V4L2_CTRL_FLAG_NEXT_CTRL not supported."); + next = 0; + n = V4L2_CID_BASE; + continue; + } + } if (errno == EINVAL || errno == ENOTTY || errno == EIO || errno == ENOENT) { if (n < V4L2_CID_PRIVATE_BASE) { GST_DEBUG_OBJECT (e, "skipping control %08x", n); @@ -265,10 +287,17 @@ gst_v4l2_fill_lists (GstV4l2Object * v4l2object) continue; } } + n = control.id; if (control.flags & V4L2_CTRL_FLAG_DISABLED) { GST_DEBUG_OBJECT (e, "skipping disabled control"); continue; } +#ifdef V4L2_CTRL_TYPE_CTRL_CLASS + if (control.type == V4L2_CTRL_TYPE_CTRL_CLASS) { + GST_DEBUG_OBJECT (e, "starting control class '%s'", control.name); + continue; + } +#endif switch (control.type) { case V4L2_CTRL_TYPE_INTEGER: case V4L2_CTRL_TYPE_BOOLEAN: |