extended-controls.rst 7.0 KB

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