From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mailout1.w1.samsung.com ([210.118.77.11]:12666 "EHLO mailout1.w1.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751185AbaAWPet (ORCPT ); Thu, 23 Jan 2014 10:34:49 -0500 Received: from eucpsbgm2.samsung.com (unknown [203.254.199.245]) by mailout1.w1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MZV0022V1XZMB40@mailout1.w1.samsung.com> for linux-media@vger.kernel.org; Thu, 23 Jan 2014 15:34:47 +0000 (GMT) Message-id: <52E13694.80002@samsung.com> Date: Thu, 23 Jan 2014 16:34:44 +0100 From: Sylwester Nawrocki MIME-version: 1.0 To: Hans Verkuil , linux-media@vger.kernel.org Cc: m.chehab@samsung.com, laurent.pinchart@ideasonboard.com, t.stanislaws@samsung.com, Hans Verkuil Subject: Re: [RFCv2 PATCH 20/21] DocBook media: update control section. References: <1390221974-28194-1-git-send-email-hverkuil@xs4all.nl> <1390221974-28194-21-git-send-email-hverkuil@xs4all.nl> In-reply-to: <1390221974-28194-21-git-send-email-hverkuil@xs4all.nl> Content-type: text/plain; charset=ISO-8859-1 Content-transfer-encoding: 7bit Sender: linux-media-owner@vger.kernel.org List-ID: On 20/01/14 13:46, Hans Verkuil wrote: > From: Hans Verkuil > > Document the support for complex types in controls. > > Signed-off-by: Hans Verkuil > --- > Documentation/DocBook/media/v4l/controls.xml | 185 +++++++++++++++++---------- > 1 file changed, 118 insertions(+), 67 deletions(-) > > diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml > index a5a3188..85d78d4 100644 > --- a/Documentation/DocBook/media/v4l/controls.xml > +++ b/Documentation/DocBook/media/v4l/controls.xml > @@ -13,6 +13,19 @@ correctly with any device. > All controls are accessed using an ID value. V4L2 defines > several IDs for specific purposes. Drivers can also implement their > own custom controls using V4L2_CID_PRIVATE_BASE > +The use of V4L2_CID_PRIVATE_BASE > +is problematic because different drivers may use the same > +V4L2_CID_PRIVATE_BASE ID for different controls. > +This makes it hard to programatically set such controls since the meaning > +of the control with that ID is driver dependent. In order to resolve this > +drivers use unique IDs and the V4L2_CID_PRIVATE_BASE > +IDs are mapped to those unique IDs by the kernel. Consider these > +V4L2_CID_PRIVATE_BASE IDs as aliases to the real > +IDs. > +Many applications today still use the V4L2_CID_PRIVATE_BASE > +IDs instead of using &VIDIOC-QUERYCTRL; with the V4L2_CTRL_FLAG_NEXT_CTRL > +flag to enumerate all IDs, so support for V4L2_CID_PRIVATE_BASE > +is still around. > and higher values. The pre-defined control IDs have the prefix > V4L2_CID_, and are listed in linkend="control-id" />. The ID is used when querying the attributes of > @@ -31,25 +44,22 @@ the current video input or output, tuner or modulator, or audio input > or output. Different in the sense of other bounds, another default and > current value, step size or other menu items. A control with a certain > custom ID can also change name and > -type. > - It will be more convenient for applications if drivers > -make use of the V4L2_CTRL_FLAG_DISABLED flag, but > -that was never required. > - Control values are stored globally, they do not > +type. > + > + If a control is not applicable to the current configuration > +of the device (for example, it doesn't apply to the current video input) > +drivers set the V4L2_CTRL_FLAG_INACTIVE flag. > + > + Control values are stored globally, they do not > change when switching except to stay within the reported bounds. They > also do not change ⪚ when the device is opened or closed, when the > tuner radio frequency is changed or generally never without > -application request. Since V4L2 specifies no event mechanism, panel > -applications intended to cooperate with other panel applications (be > -they built into a larger application, as a TV viewer) may need to > -regularly poll control values to update their user > -interface. > - Applications could call an ioctl to request events. > -After another process called &VIDIOC-S-CTRL; or another ioctl changing > -shared properties the &func-select; function would indicate > -readability until any ioctl (querying the properties) is > -called. > - > +application request. > + > + V4L2 specifies an event mechanism to notify applications > +when controls change value (see &VIDIOC-SUBSCRIBE-EVENT;, event > +V4L2_EVENT_CTRL), panel applications might want to make > +use of that in order to always reflect the correct control value. > > > All controls use machine endianness. > @@ -434,127 +444,152 @@ Drivers must implement VIDIOC_QUERYCTRL, > controls, VIDIOC_QUERYMENU when it has one or > more menu type controls. > > - > - Enumerating all controls > + > + Enumerating all user controls > > > &v4l2-queryctrl; queryctrl; > &v4l2-querymenu; querymenu; > > -static void > -enumerate_menu (void) > +static void enumerate_menu(void) > { > - printf (" Menu items:\n"); > + printf(" Menu items:\n"); > > - memset (&querymenu, 0, sizeof (querymenu)); > + memset(&querymenu, 0, sizeof(querymenu)); > querymenu.id = queryctrl.id; > > for (querymenu.index = queryctrl.minimum; > querymenu.index <= queryctrl.maximum; > - querymenu.index++) { > - if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &querymenu)) { > - printf (" %s\n", querymenu.name); > + querymenu.index++) { > + if (0 == ioctl(fd, &VIDIOC-QUERYMENU;, &querymenu)) { > + printf(" %s\n", querymenu.name); > } > } > } > > -memset (&queryctrl, 0, sizeof (queryctrl)); > +memset(&queryctrl, 0, sizeof(queryctrl)); > > for (queryctrl.id = V4L2_CID_BASE; > queryctrl.id < V4L2_CID_LASTP1; > queryctrl.id++) { > - if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > + if (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) > continue; > > - printf ("Control %s\n", queryctrl.name); > + printf("Control %s\n", queryctrl.name); > > if (queryctrl.type == V4L2_CTRL_TYPE_MENU) > - enumerate_menu (); > + enumerate_menu(); > } else { > if (errno == EINVAL) > continue; > > - perror ("VIDIOC_QUERYCTRL"); > - exit (EXIT_FAILURE); > + perror("VIDIOC_QUERYCTRL"); > + exit(EXIT_FAILURE); > } > } > > for (queryctrl.id = V4L2_CID_PRIVATE_BASE;; > queryctrl.id++) { > - if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > + if (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) > continue; > > - printf ("Control %s\n", queryctrl.name); > + printf("Control %s\n", queryctrl.name); > > if (queryctrl.type == V4L2_CTRL_TYPE_MENU) > - enumerate_menu (); > + enumerate_menu(); > } else { > if (errno == EINVAL) > break; > > - perror ("VIDIOC_QUERYCTRL"); > - exit (EXIT_FAILURE); > + perror("VIDIOC_QUERYCTRL"); > + exit(EXIT_FAILURE); > } > } > > > > > + Enumerating all user controls (alternative) > + > +memset(&queryctrl, 0, sizeof(queryctrl)); > + > +queryctrl.id = V4L2_CTRL_CLASS_USER | V4L2_CTRL_FLAG_NEXT_CTRL; > +while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > + if (V4L2_CTRL_ID2CLASS(queryctrl.id) != V4L2_CTRL_CLASS_USER) > + break; > + if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) > + continue; > + > + printf("Control %s\n", queryctrl.name); > + > + if (queryctrl.type == V4L2_CTRL_TYPE_MENU) > + enumerate_menu(); > + > + queryctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; > +} > +if (errno != EINVAL) { > + perror("VIDIOC_QUERYCTRL"); > + exit(EXIT_FAILURE); > +} > + > + > + > + > Changing controls > > > &v4l2-queryctrl; queryctrl; > &v4l2-control; control; > > -memset (&queryctrl, 0, sizeof (queryctrl)); > +memset(&queryctrl, 0, sizeof(queryctrl)); > queryctrl.id = V4L2_CID_BRIGHTNESS; > > -if (-1 == ioctl (fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > +if (-1 == ioctl(fd, &VIDIOC-QUERYCTRL;, &queryctrl)) { > if (errno != EINVAL) { > - perror ("VIDIOC_QUERYCTRL"); > - exit (EXIT_FAILURE); > + perror("VIDIOC_QUERYCTRL"); > + exit(EXIT_FAILURE); > } else { > - printf ("V4L2_CID_BRIGHTNESS is not supported\n"); > + printf("V4L2_CID_BRIGHTNESS is not supported\n"); > } > } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) { > - printf ("V4L2_CID_BRIGHTNESS is not supported\n"); > + printf("V4L2_CID_BRIGHTNESS is not supported\n"); > } else { > - memset (&control, 0, sizeof (control)); > + memset(&control, 0, sizeof (control)); > control.id = V4L2_CID_BRIGHTNESS; > control.value = queryctrl.default_value; > > - if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &control)) { > - perror ("VIDIOC_S_CTRL"); > - exit (EXIT_FAILURE); > + if (-1 == ioctl(fd, &VIDIOC-S-CTRL;, &control)) { > + perror("VIDIOC_S_CTRL"); > + exit(EXIT_FAILURE); > } > } > > -memset (&control, 0, sizeof (control)); > +memset(&control, 0, sizeof(control)); > control.id = V4L2_CID_CONTRAST; > > -if (0 == ioctl (fd, &VIDIOC-G-CTRL;, &control)) { > +if (0 == ioctl(fd, &VIDIOC-G-CTRL;, &control)) { > control.value += 1; > > /* The driver may clamp the value or return ERANGE, ignored here */ > > - if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &control) > + if (-1 == ioctl(fd, &VIDIOC-S-CTRL;, &control) > && errno != ERANGE) { > - perror ("VIDIOC_S_CTRL"); > - exit (EXIT_FAILURE); > + perror("VIDIOC_S_CTRL"); > + exit(EXIT_FAILURE); > } > /* Ignore if V4L2_CID_CONTRAST is unsupported */ > } else if (errno != EINVAL) { > - perror ("VIDIOC_G_CTRL"); > - exit (EXIT_FAILURE); > + perror("VIDIOC_G_CTRL"); > + exit(EXIT_FAILURE); > } > > control.id = V4L2_CID_AUDIO_MUTE; > -control.value = TRUE; /* silence */ > +control.value = 1; /* silence */ > > /* Errors ignored */ > -ioctl (fd, VIDIOC_S_CTRL, &control); > +ioctl(fd, VIDIOC_S_CTRL, &control); > > > > @@ -625,16 +660,32 @@ supported. > &v4l2-control;, except for the fact that it also allows for 64-bit > values and pointers to be passed. > > + Since the &v4l2-ext-control; supports pointers it is now > +also possible to have controls with complex types such as arrays/matrices > +and/or structures. All such complex controls will have the > +V4L2_CTRL_FLAG_HIDDEN set since such controls cannot > +be displayed in control panel applications. Nor can they be used in the > +user class (for backwards compatibility reasons), and you need to specify > +the V4L2_CTRL_FLAG_NEXT_HIDDEN when enumerating controls > +to actually be able to see such hidden controls. In other words, these > +controls with complex types should only be used programmatically. > + > + Since such complex controls need to expose more information > +about themselves than is possible with &VIDIOC-QUERYCTRL; the > +&VIDIOC-QUERY-EXT-CTRL; ioctl was added. In particular, this ioctl gives > +the size of the matrix if this control consists of more than > +one element. > + > It is important to realize that due to the flexibility of > controls it is necessary to check whether the control you want to set > actually is supported in the driver and what the valid range of values > -is. So use the &VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls to > -check this. Also note that it is possible that some of the menu > -indices in a control of type V4L2_CTRL_TYPE_MENU > -may not be supported (VIDIOC_QUERYMENU will > -return an error). A good example is the list of supported MPEG audio > -bitrates. Some drivers only support one or two bitrates, others > -support a wider range. > +is. So use the &VIDIOC-QUERYCTRL; (or &VIDIOC-QUERY-EXT-CTRL;) and > +&VIDIOC-QUERYMENU; ioctls to check this. Also note that it is possible > +that some of the menu indices in a control of type > +V4L2_CTRL_TYPE_MENU may not be supported > +(VIDIOC_QUERYMENU will return an error). A good > +example is the list of supported MPEG audio bitrates. Some drivers only > +support one or two bitrates, others support a wider range. > > > All controls use machine endianness. > @@ -675,12 +726,12 @@ control class is found: > > > qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL; > -while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &qctrl)) { > - if (V4L2_CTRL_ID2CLASS (qctrl.id) != V4L2_CTRL_CLASS_MPEG) > +while (0 == ioctl(fd, &VIDIOC-QUERYCTRL;, &qctrl)) { > + if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG) > break; > /* ... */ > - qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; > - } > + qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; > +} > > > > @@ -700,7 +751,7 @@ ID based on a control ID. > VIDIOC_QUERYCTRL will fail when used in > combination with V4L2_CTRL_FLAG_NEXT_CTRL. In > that case the old method of enumerating control should be used (see > -1.8). But if it is supported, then it is guaranteed to enumerate over > +). But if it is supported, then it is guaranteed to enumerate over > all controls, including driver-private controls. > It would have been easier to review if the whitespace changes were in a separate patch. Reviewed-by: Sylwester Nawrocki I guess we want a note somewhere the V4L2_CTRL_FLAG_DISABLED flag is deprecated ? It seems to be used in very few drivers. -- Regards, Sylwester