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