summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2013-06-03 09:17:43 +0200
committerMichael Olbrich <m.olbrich@pengutronix.de>2013-09-13 16:29:48 +0200
commit6301914bc5eb89878255495b206caa04251bef33 (patch)
tree381b5a6f01f49b07f00c1afd796312d2d755d421
parent5290e247a8bdabc6de075fd5fe0c2007ff04f25f (diff)
downloadgst-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.c37
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: