18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci.. _extended-controls:
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci*********************
68c2ecf20Sopenharmony_ciExtended Controls API
78c2ecf20Sopenharmony_ci*********************
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciIntroduction
118c2ecf20Sopenharmony_ci============
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ciThe control mechanism as originally designed was meant to be used for
148c2ecf20Sopenharmony_ciuser settings (brightness, saturation, etc). However, it turned out to
158c2ecf20Sopenharmony_cibe a very useful model for implementing more complicated driver APIs
168c2ecf20Sopenharmony_ciwhere each driver implements only a subset of a larger API.
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ciThe MPEG encoding API was the driving force behind designing and
198c2ecf20Sopenharmony_ciimplementing this extended control mechanism: the MPEG standard is quite
208c2ecf20Sopenharmony_cilarge and the currently supported hardware MPEG encoders each only
218c2ecf20Sopenharmony_ciimplement a subset of this standard. Further more, many parameters
228c2ecf20Sopenharmony_cirelating to how the video is encoded into an MPEG stream are specific to
238c2ecf20Sopenharmony_cithe MPEG encoding chip since the MPEG standard only defines the format
248c2ecf20Sopenharmony_ciof the resulting MPEG stream, not how the video is actually encoded into
258c2ecf20Sopenharmony_cithat format.
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ciUnfortunately, the original control API lacked some features needed for
288c2ecf20Sopenharmony_cithese new uses and so it was extended into the (not terribly originally
298c2ecf20Sopenharmony_cinamed) extended control API.
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ciEven though the MPEG encoding API was the first effort to use the
328c2ecf20Sopenharmony_ciExtended Control API, nowadays there are also other classes of Extended
338c2ecf20Sopenharmony_ciControls, such as Camera Controls and FM Transmitter Controls. The
348c2ecf20Sopenharmony_ciExtended Controls API as well as all Extended Controls classes are
358c2ecf20Sopenharmony_cidescribed in the following text.
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ciThe Extended Control API
398c2ecf20Sopenharmony_ci========================
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciThree new ioctls are available:
428c2ecf20Sopenharmony_ci:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
438c2ecf20Sopenharmony_ci:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
448c2ecf20Sopenharmony_ci:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`. These ioctls act
458c2ecf20Sopenharmony_cion arrays of controls (as opposed to the
468c2ecf20Sopenharmony_ci:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
478c2ecf20Sopenharmony_ci:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls that act on a single
488c2ecf20Sopenharmony_cicontrol). This is needed since it is often required to atomically change
498c2ecf20Sopenharmony_ciseveral controls at once.
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciEach of the new ioctls expects a pointer to a struct
528c2ecf20Sopenharmony_ci:c:type:`v4l2_ext_controls`. This structure
538c2ecf20Sopenharmony_cicontains a pointer to the control array, a count of the number of
548c2ecf20Sopenharmony_cicontrols in that array and a control class. Control classes are used to
558c2ecf20Sopenharmony_cigroup similar controls into a single class. For example, control class
568c2ecf20Sopenharmony_ci``V4L2_CTRL_CLASS_USER`` contains all user controls (i. e. all controls
578c2ecf20Sopenharmony_cithat can also be set using the old :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
588c2ecf20Sopenharmony_ciioctl). Control class ``V4L2_CTRL_CLASS_MPEG`` contains all controls
598c2ecf20Sopenharmony_cirelating to MPEG encoding, etc.
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ciAll controls in the control array must belong to the specified control
628c2ecf20Sopenharmony_ciclass. An error is returned if this is not the case.
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ciIt is also possible to use an empty control array (``count`` == 0) to check
658c2ecf20Sopenharmony_ciwhether the specified control class is supported.
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciThe control array is a struct
688c2ecf20Sopenharmony_ci:c:type:`v4l2_ext_control` array. The
698c2ecf20Sopenharmony_cistruct :c:type:`v4l2_ext_control` is very similar to
708c2ecf20Sopenharmony_cistruct :c:type:`v4l2_control`, except for the fact that
718c2ecf20Sopenharmony_ciit also allows for 64-bit values and pointers to be passed.
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ciSince the struct :c:type:`v4l2_ext_control` supports
748c2ecf20Sopenharmony_cipointers it is now also possible to have controls with compound types
758c2ecf20Sopenharmony_cisuch as N-dimensional arrays and/or structures. You need to specify the
768c2ecf20Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_COMPOUND`` when enumerating controls to actually
778c2ecf20Sopenharmony_cibe able to see such compound controls. In other words, these controls
788c2ecf20Sopenharmony_ciwith compound types should only be used programmatically.
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ciSince such compound controls need to expose more information about
818c2ecf20Sopenharmony_cithemselves than is possible with :ref:`VIDIOC_QUERYCTRL <VIDIOC_QUERYCTRL>`
828c2ecf20Sopenharmony_cithe :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
838c2ecf20Sopenharmony_ciparticular, this ioctl gives the dimensions of the N-dimensional array if
848c2ecf20Sopenharmony_cithis control consists of more than one element.
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci.. note::
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci   #. It is important to realize that due to the flexibility of controls it is
898c2ecf20Sopenharmony_ci      necessary to check whether the control you want to set actually is
908c2ecf20Sopenharmony_ci      supported in the driver and what the valid range of values is. So use
918c2ecf20Sopenharmony_ci      :ref:`VIDIOC_QUERYCTRL` to check this.
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci   #. It is possible that some of the menu indices in a control of
948c2ecf20Sopenharmony_ci      type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU``
958c2ecf20Sopenharmony_ci      will return an error). A good example is the list of supported MPEG
968c2ecf20Sopenharmony_ci      audio bitrates. Some drivers only support one or two bitrates, others
978c2ecf20Sopenharmony_ci      support a wider range.
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ciAll controls use machine endianness.
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ciEnumerating Extended Controls
1038c2ecf20Sopenharmony_ci=============================
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ciThe recommended way to enumerate over the extended controls is by using
1068c2ecf20Sopenharmony_ci:ref:`VIDIOC_QUERYCTRL` in combination with the
1078c2ecf20Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_CTRL`` flag:
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci.. code-block:: c
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci    struct v4l2_queryctrl qctrl;
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci    qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
1158c2ecf20Sopenharmony_ci    while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
1168c2ecf20Sopenharmony_ci	/* ... */
1178c2ecf20Sopenharmony_ci	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
1188c2ecf20Sopenharmony_ci    }
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ciThe initial control ID is set to 0 ORed with the
1218c2ecf20Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_CTRL`` flag. The ``VIDIOC_QUERYCTRL`` ioctl will
1228c2ecf20Sopenharmony_cireturn the first control with a higher ID than the specified one. When
1238c2ecf20Sopenharmony_cino such controls are found an error is returned.
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ciIf you want to get all controls within a specific control class, then
1268c2ecf20Sopenharmony_ciyou can set the initial ``qctrl.id`` value to the control class and add
1278c2ecf20Sopenharmony_cian extra check to break out of the loop when a control of another
1288c2ecf20Sopenharmony_cicontrol class is found:
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_ci.. code-block:: c
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_ci    qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
1348c2ecf20Sopenharmony_ci    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) {
1358c2ecf20Sopenharmony_ci	if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG)
1368c2ecf20Sopenharmony_ci	    break;
1378c2ecf20Sopenharmony_ci	/* ... */
1388c2ecf20Sopenharmony_ci	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
1398c2ecf20Sopenharmony_ci    }
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ciThe 32-bit ``qctrl.id`` value is subdivided into three bit ranges: the
1428c2ecf20Sopenharmony_citop 4 bits are reserved for flags (e. g. ``V4L2_CTRL_FLAG_NEXT_CTRL``)
1438c2ecf20Sopenharmony_ciand are not actually part of the ID. The remaining 28 bits form the
1448c2ecf20Sopenharmony_cicontrol ID, of which the most significant 12 bits define the control
1458c2ecf20Sopenharmony_ciclass and the least significant 16 bits identify the control within the
1468c2ecf20Sopenharmony_cicontrol class. It is guaranteed that these last 16 bits are always
1478c2ecf20Sopenharmony_cinon-zero for controls. The range of 0x1000 and up are reserved for
1488c2ecf20Sopenharmony_cidriver-specific controls. The macro ``V4L2_CTRL_ID2CLASS(id)`` returns
1498c2ecf20Sopenharmony_cithe control class ID based on a control ID.
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ciIf the driver does not support extended controls, then
1528c2ecf20Sopenharmony_ci``VIDIOC_QUERYCTRL`` will fail when used in combination with
1538c2ecf20Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_CTRL``. In that case the old method of enumerating
1548c2ecf20Sopenharmony_cicontrol should be used (see :ref:`enum_all_controls`). But if it is
1558c2ecf20Sopenharmony_cisupported, then it is guaranteed to enumerate over all controls,
1568c2ecf20Sopenharmony_ciincluding driver-private controls.
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ciCreating Control Panels
1608c2ecf20Sopenharmony_ci=======================
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ciIt is possible to create control panels for a graphical user interface
1638c2ecf20Sopenharmony_ciwhere the user can select the various controls. Basically you will have
1648c2ecf20Sopenharmony_cito iterate over all controls using the method described above. Each
1658c2ecf20Sopenharmony_cicontrol class starts with a control of type
1668c2ecf20Sopenharmony_ci``V4L2_CTRL_TYPE_CTRL_CLASS``. ``VIDIOC_QUERYCTRL`` will return the name
1678c2ecf20Sopenharmony_ciof this control class which can be used as the title of a tab page
1688c2ecf20Sopenharmony_ciwithin a control panel.
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ciThe flags field of struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` also
1718c2ecf20Sopenharmony_cicontains hints on the behavior of the control. See the
1728c2ecf20Sopenharmony_ci:ref:`VIDIOC_QUERYCTRL` documentation for more
1738c2ecf20Sopenharmony_cidetails.
174