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