1.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later 2 3.. _extended-controls: 4 5********************* 6Extended Controls API 7********************* 8 9 10Introduction 11============ 12 13The control mechanism as originally designed was meant to be used for 14user settings (brightness, saturation, etc). However, it turned out to 15be a very useful model for implementing more complicated driver APIs 16where each driver implements only a subset of a larger API. 17 18The MPEG encoding API was the driving force behind designing and 19implementing this extended control mechanism: the MPEG standard is quite 20large and the currently supported hardware MPEG encoders each only 21implement a subset of this standard. Further more, many parameters 22relating to how the video is encoded into an MPEG stream are specific to 23the MPEG encoding chip since the MPEG standard only defines the format 24of the resulting MPEG stream, not how the video is actually encoded into 25that format. 26 27Unfortunately, the original control API lacked some features needed for 28these new uses and so it was extended into the (not terribly originally 29named) extended control API. 30 31Even though the MPEG encoding API was the first effort to use the 32Extended Control API, nowadays there are also other classes of Extended 33Controls, such as Camera Controls and FM Transmitter Controls. The 34Extended Controls API as well as all Extended Controls classes are 35described in the following text. 36 37 38The Extended Control API 39======================== 40 41Three new ioctls are available: 42:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`, 43:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and 44:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`. These ioctls act 45on arrays of controls (as opposed to the 46:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and 47:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls that act on a single 48control). This is needed since it is often required to atomically change 49several controls at once. 50 51Each of the new ioctls expects a pointer to a struct 52:c:type:`v4l2_ext_controls`. This structure 53contains a pointer to the control array, a count of the number of 54controls in that array and a control class. Control classes are used to 55group similar controls into a single class. For example, control class 56``V4L2_CTRL_CLASS_USER`` contains all user controls (i. e. all controls 57that can also be set using the old :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` 58ioctl). Control class ``V4L2_CTRL_CLASS_CODEC`` contains controls 59relating to codecs. 60 61All controls in the control array must belong to the specified control 62class. An error is returned if this is not the case. 63 64It is also possible to use an empty control array (``count`` == 0) to check 65whether the specified control class is supported. 66 67The control array is a struct 68:c:type:`v4l2_ext_control` array. The 69struct :c:type:`v4l2_ext_control` is very similar to 70struct :c:type:`v4l2_control`, except for the fact that 71it also allows for 64-bit values and pointers to be passed. 72 73Since the struct :c:type:`v4l2_ext_control` supports 74pointers it is now also possible to have controls with compound types 75such as N-dimensional arrays and/or structures. You need to specify the 76``V4L2_CTRL_FLAG_NEXT_COMPOUND`` when enumerating controls to actually 77be able to see such compound controls. In other words, these controls 78with compound types should only be used programmatically. 79 80Since such compound controls need to expose more information about 81themselves than is possible with :ref:`VIDIOC_QUERYCTRL <VIDIOC_QUERYCTRL>` 82the :ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In 83particular, this ioctl gives the dimensions of the N-dimensional array if 84this control consists of more than one element. 85 86.. note:: 87 88 #. It is important to realize that due to the flexibility of controls it is 89 necessary to check whether the control you want to set actually is 90 supported in the driver and what the valid range of values is. So use 91 :ref:`VIDIOC_QUERYCTRL` to check this. 92 93 #. It is possible that some of the menu indices in a control of 94 type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU`` 95 will return an error). A good example is the list of supported MPEG 96 audio bitrates. Some drivers only support one or two bitrates, others 97 support a wider range. 98 99All controls use machine endianness. 100 101 102Enumerating Extended Controls 103============================= 104 105The recommended way to enumerate over the extended controls is by using 106:ref:`VIDIOC_QUERYCTRL` in combination with the 107``V4L2_CTRL_FLAG_NEXT_CTRL`` flag: 108 109 110.. code-block:: c 111 112 struct v4l2_queryctrl qctrl; 113 114 qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL; 115 while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) { 116 /* ... */ 117 qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; 118 } 119 120The initial control ID is set to 0 ORed with the 121``V4L2_CTRL_FLAG_NEXT_CTRL`` flag. The ``VIDIOC_QUERYCTRL`` ioctl will 122return the first control with a higher ID than the specified one. When 123no such controls are found an error is returned. 124 125If you want to get all controls within a specific control class, then 126you can set the initial ``qctrl.id`` value to the control class and add 127an extra check to break out of the loop when a control of another 128control class is found: 129 130 131.. code-block:: c 132 133 qctrl.id = V4L2_CTRL_CLASS_CODEC | V4L2_CTRL_FLAG_NEXT_CTRL; 134 while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) { 135 if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_CODEC) 136 break; 137 /* ... */ 138 qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL; 139 } 140 141The 32-bit ``qctrl.id`` value is subdivided into three bit ranges: the 142top 4 bits are reserved for flags (e. g. ``V4L2_CTRL_FLAG_NEXT_CTRL``) 143and are not actually part of the ID. The remaining 28 bits form the 144control ID, of which the most significant 12 bits define the control 145class and the least significant 16 bits identify the control within the 146control class. It is guaranteed that these last 16 bits are always 147non-zero for controls. The range of 0x1000 and up are reserved for 148driver-specific controls. The macro ``V4L2_CTRL_ID2CLASS(id)`` returns 149the control class ID based on a control ID. 150 151If the driver does not support extended controls, then 152``VIDIOC_QUERYCTRL`` will fail when used in combination with 153``V4L2_CTRL_FLAG_NEXT_CTRL``. In that case the old method of enumerating 154control should be used (see :ref:`enum_all_controls`). But if it is 155supported, then it is guaranteed to enumerate over all controls, 156including driver-private controls. 157 158 159Creating Control Panels 160======================= 161 162It is possible to create control panels for a graphical user interface 163where the user can select the various controls. Basically you will have 164to iterate over all controls using the method described above. Each 165control class starts with a control of type 166``V4L2_CTRL_TYPE_CTRL_CLASS``. ``VIDIOC_QUERYCTRL`` will return the name 167of this control class which can be used as the title of a tab page 168within a control panel. 169 170The flags field of struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` also 171contains hints on the behavior of the control. See the 172:ref:`VIDIOC_QUERYCTRL` documentation for more 173details. 174