162306a36Sopenharmony_ci.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci.. _extended-controls:
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci*********************
662306a36Sopenharmony_ciExtended Controls API
762306a36Sopenharmony_ci*********************
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciIntroduction
1162306a36Sopenharmony_ci============
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ciThe control mechanism as originally designed was meant to be used for
1462306a36Sopenharmony_ciuser settings (brightness, saturation, etc). However, it turned out to
1562306a36Sopenharmony_cibe a very useful model for implementing more complicated driver APIs
1662306a36Sopenharmony_ciwhere each driver implements only a subset of a larger API.
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ciThe MPEG encoding API was the driving force behind designing and
1962306a36Sopenharmony_ciimplementing this extended control mechanism: the MPEG standard is quite
2062306a36Sopenharmony_cilarge and the currently supported hardware MPEG encoders each only
2162306a36Sopenharmony_ciimplement a subset of this standard. Further more, many parameters
2262306a36Sopenharmony_cirelating to how the video is encoded into an MPEG stream are specific to
2362306a36Sopenharmony_cithe MPEG encoding chip since the MPEG standard only defines the format
2462306a36Sopenharmony_ciof the resulting MPEG stream, not how the video is actually encoded into
2562306a36Sopenharmony_cithat format.
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ciUnfortunately, the original control API lacked some features needed for
2862306a36Sopenharmony_cithese new uses and so it was extended into the (not terribly originally
2962306a36Sopenharmony_cinamed) extended control API.
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ciEven though the MPEG encoding API was the first effort to use the
3262306a36Sopenharmony_ciExtended Control API, nowadays there are also other classes of Extended
3362306a36Sopenharmony_ciControls, such as Camera Controls and FM Transmitter Controls. The
3462306a36Sopenharmony_ciExtended Controls API as well as all Extended Controls classes are
3562306a36Sopenharmony_cidescribed in the following text.
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ciThe Extended Control API
3962306a36Sopenharmony_ci========================
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciThree new ioctls are available:
4262306a36Sopenharmony_ci:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
4362306a36Sopenharmony_ci:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
4462306a36Sopenharmony_ci:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`. These ioctls act
4562306a36Sopenharmony_cion arrays of controls (as opposed to the
4662306a36Sopenharmony_ci:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
4762306a36Sopenharmony_ci:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls that act on a single
4862306a36Sopenharmony_cicontrol). This is needed since it is often required to atomically change
4962306a36Sopenharmony_ciseveral controls at once.
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciEach of the new ioctls expects a pointer to a struct
5262306a36Sopenharmony_ci:c:type:`v4l2_ext_controls`. This structure
5362306a36Sopenharmony_cicontains a pointer to the control array, a count of the number of
5462306a36Sopenharmony_cicontrols in that array and a control class. Control classes are used to
5562306a36Sopenharmony_cigroup similar controls into a single class. For example, control class
5662306a36Sopenharmony_ci``V4L2_CTRL_CLASS_USER`` contains all user controls (i. e. all controls
5762306a36Sopenharmony_cithat can also be set using the old :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
5862306a36Sopenharmony_ciioctl). Control class ``V4L2_CTRL_CLASS_CODEC`` contains controls
5962306a36Sopenharmony_cirelating to codecs.
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciAll controls in the control array must belong to the specified control
6262306a36Sopenharmony_ciclass. An error is returned if this is not the case.
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ciIt is also possible to use an empty control array (``count`` == 0) to check
6562306a36Sopenharmony_ciwhether the specified control class is supported.
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ciThe control array is a struct
6862306a36Sopenharmony_ci:c:type:`v4l2_ext_control` array. The
6962306a36Sopenharmony_cistruct :c:type:`v4l2_ext_control` is very similar to
7062306a36Sopenharmony_cistruct :c:type:`v4l2_control`, except for the fact that
7162306a36Sopenharmony_ciit also allows for 64-bit values and pointers to be passed.
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciSince the struct :c:type:`v4l2_ext_control` supports
7462306a36Sopenharmony_cipointers it is now also possible to have controls with compound types
7562306a36Sopenharmony_cisuch as N-dimensional arrays and/or structures. You need to specify the
7662306a36Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_COMPOUND`` when enumerating controls to actually
7762306a36Sopenharmony_cibe able to see such compound controls. In other words, these controls
7862306a36Sopenharmony_ciwith compound types should only be used programmatically.
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ciSince such compound controls need to expose more information about
8162306a36Sopenharmony_cithemselves than is possible with :ref:`VIDIOC_QUERYCTRL <VIDIOC_QUERYCTRL>`
8262306a36Sopenharmony_cithe :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
8362306a36Sopenharmony_ciparticular, this ioctl gives the dimensions of the N-dimensional array if
8462306a36Sopenharmony_cithis control consists of more than one element.
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci.. note::
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci   #. It is important to realize that due to the flexibility of controls it is
8962306a36Sopenharmony_ci      necessary to check whether the control you want to set actually is
9062306a36Sopenharmony_ci      supported in the driver and what the valid range of values is. So use
9162306a36Sopenharmony_ci      :ref:`VIDIOC_QUERYCTRL` to check this.
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci   #. It is possible that some of the menu indices in a control of
9462306a36Sopenharmony_ci      type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU``
9562306a36Sopenharmony_ci      will return an error). A good example is the list of supported MPEG
9662306a36Sopenharmony_ci      audio bitrates. Some drivers only support one or two bitrates, others
9762306a36Sopenharmony_ci      support a wider range.
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ciAll controls use machine endianness.
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ciEnumerating Extended Controls
10362306a36Sopenharmony_ci=============================
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_ciThe recommended way to enumerate over the extended controls is by using
10662306a36Sopenharmony_ci:ref:`VIDIOC_QUERYCTRL` in combination with the
10762306a36Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_CTRL`` flag:
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci.. code-block:: c
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci    struct v4l2_queryctrl qctrl;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci    qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
11562306a36Sopenharmony_ci    while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
11662306a36Sopenharmony_ci	/* ... */
11762306a36Sopenharmony_ci	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
11862306a36Sopenharmony_ci    }
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ciThe initial control ID is set to 0 ORed with the
12162306a36Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_CTRL`` flag. The ``VIDIOC_QUERYCTRL`` ioctl will
12262306a36Sopenharmony_cireturn the first control with a higher ID than the specified one. When
12362306a36Sopenharmony_cino such controls are found an error is returned.
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ciIf you want to get all controls within a specific control class, then
12662306a36Sopenharmony_ciyou can set the initial ``qctrl.id`` value to the control class and add
12762306a36Sopenharmony_cian extra check to break out of the loop when a control of another
12862306a36Sopenharmony_cicontrol class is found:
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci.. code-block:: c
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci    qctrl.id = V4L2_CTRL_CLASS_CODEC | V4L2_CTRL_FLAG_NEXT_CTRL;
13462306a36Sopenharmony_ci    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) {
13562306a36Sopenharmony_ci	if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_CODEC)
13662306a36Sopenharmony_ci	    break;
13762306a36Sopenharmony_ci	/* ... */
13862306a36Sopenharmony_ci	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
13962306a36Sopenharmony_ci    }
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ciThe 32-bit ``qctrl.id`` value is subdivided into three bit ranges: the
14262306a36Sopenharmony_citop 4 bits are reserved for flags (e. g. ``V4L2_CTRL_FLAG_NEXT_CTRL``)
14362306a36Sopenharmony_ciand are not actually part of the ID. The remaining 28 bits form the
14462306a36Sopenharmony_cicontrol ID, of which the most significant 12 bits define the control
14562306a36Sopenharmony_ciclass and the least significant 16 bits identify the control within the
14662306a36Sopenharmony_cicontrol class. It is guaranteed that these last 16 bits are always
14762306a36Sopenharmony_cinon-zero for controls. The range of 0x1000 and up are reserved for
14862306a36Sopenharmony_cidriver-specific controls. The macro ``V4L2_CTRL_ID2CLASS(id)`` returns
14962306a36Sopenharmony_cithe control class ID based on a control ID.
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ciIf the driver does not support extended controls, then
15262306a36Sopenharmony_ci``VIDIOC_QUERYCTRL`` will fail when used in combination with
15362306a36Sopenharmony_ci``V4L2_CTRL_FLAG_NEXT_CTRL``. In that case the old method of enumerating
15462306a36Sopenharmony_cicontrol should be used (see :ref:`enum_all_controls`). But if it is
15562306a36Sopenharmony_cisupported, then it is guaranteed to enumerate over all controls,
15662306a36Sopenharmony_ciincluding driver-private controls.
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ciCreating Control Panels
16062306a36Sopenharmony_ci=======================
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ciIt is possible to create control panels for a graphical user interface
16362306a36Sopenharmony_ciwhere the user can select the various controls. Basically you will have
16462306a36Sopenharmony_cito iterate over all controls using the method described above. Each
16562306a36Sopenharmony_cicontrol class starts with a control of type
16662306a36Sopenharmony_ci``V4L2_CTRL_TYPE_CTRL_CLASS``. ``VIDIOC_QUERYCTRL`` will return the name
16762306a36Sopenharmony_ciof this control class which can be used as the title of a tab page
16862306a36Sopenharmony_ciwithin a control panel.
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ciThe flags field of struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` also
17162306a36Sopenharmony_cicontains hints on the behavior of the control. See the
17262306a36Sopenharmony_ci:ref:`VIDIOC_QUERYCTRL` documentation for more
17362306a36Sopenharmony_cidetails.
174