extended-controls.rst 7.4 KB
Newer Older
1 2 3 4 5 6 7 8 9
.. Permission is granted to copy, distribute and/or modify this
.. document under the terms of the GNU Free Documentation License,
.. Version 1.1 or any later version published by the Free Software
.. Foundation, with no Invariant Sections, no Front-Cover Texts
.. and no Back-Cover Texts. A copy of the license is included at
.. Documentation/media/uapi/fdl-appendix.rst.
..
.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections

10 11
.. _extended-controls:

12 13 14
*********************
Extended Controls API
*********************
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48


Introduction
============

The control mechanism as originally designed was meant to be used for
user settings (brightness, saturation, etc). However, it turned out to
be a very useful model for implementing more complicated driver APIs
where each driver implements only a subset of a larger API.

The MPEG encoding API was the driving force behind designing and
implementing this extended control mechanism: the MPEG standard is quite
large and the currently supported hardware MPEG encoders each only
implement a subset of this standard. Further more, many parameters
relating to how the video is encoded into an MPEG stream are specific to
the MPEG encoding chip since the MPEG standard only defines the format
of the resulting MPEG stream, not how the video is actually encoded into
that format.

Unfortunately, the original control API lacked some features needed for
these new uses and so it was extended into the (not terribly originally
named) extended control API.

Even though the MPEG encoding API was the first effort to use the
Extended Control API, nowadays there are also other classes of Extended
Controls, such as Camera Controls and FM Transmitter Controls. The
Extended Controls API as well as all Extended Controls classes are
described in the following text.


The Extended Control API
========================

Three new ioctls are available:
49
:ref:`VIDIOC_G_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`,
50 51
:ref:`VIDIOC_S_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>` and
:ref:`VIDIOC_TRY_EXT_CTRLS <VIDIOC_G_EXT_CTRLS>`. These ioctls act
52
on arrays of controls (as opposed to the
53
:ref:`VIDIOC_G_CTRL <VIDIOC_G_CTRL>` and
54
:ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>` ioctls that act on a single
55 56 57 58
control). This is needed since it is often required to atomically change
several controls at once.

Each of the new ioctls expects a pointer to a struct
59
:c:type:`v4l2_ext_controls`. This structure
60 61 62 63
contains a pointer to the control array, a count of the number of
controls in that array and a control class. Control classes are used to
group similar controls into a single class. For example, control class
``V4L2_CTRL_CLASS_USER`` contains all user controls (i. e. all controls
64 65 66
that can also be set using the old :ref:`VIDIOC_S_CTRL <VIDIOC_G_CTRL>`
ioctl). Control class ``V4L2_CTRL_CLASS_MPEG`` contains all controls
relating to MPEG encoding, etc.
67 68 69 70

All controls in the control array must belong to the specified control
class. An error is returned if this is not the case.

71
It is also possible to use an empty control array (``count`` == 0) to check
72 73 74
whether the specified control class is supported.

The control array is a struct
75
:c:type:`v4l2_ext_control` array. The
76
struct :c:type:`v4l2_ext_control` is very similar to
77
struct :c:type:`v4l2_control`, except for the fact that
78 79
it also allows for 64-bit values and pointers to be passed.

80
Since the struct :c:type:`v4l2_ext_control` supports
81 82 83 84 85 86 87 88
pointers it is now also possible to have controls with compound types
such as N-dimensional arrays and/or structures. You need to specify the
``V4L2_CTRL_FLAG_NEXT_COMPOUND`` when enumerating controls to actually
be able to see such compound controls. In other words, these controls
with compound types should only be used programmatically.

Since such compound controls need to expose more information about
themselves than is possible with
89
:ref:`VIDIOC_QUERYCTRL` the
90
:ref:`VIDIOC_QUERY_EXT_CTRL <VIDIOC_QUERYCTRL>` ioctl was added. In
91 92 93
particular, this ioctl gives the dimensions of the N-dimensional array
if this control consists of more than one element.

94 95 96 97 98 99 100 101 102 103 104 105 106 107
.. note::

   #. It is important to realize that due to the flexibility of controls it is
      necessary to check whether the control you want to set actually is
      supported in the driver and what the valid range of values is. So use
      the :ref:`VIDIOC_QUERYCTRL` (or :ref:`VIDIOC_QUERY_EXT_CTRL
      <VIDIOC_QUERYCTRL>`) and :ref:`VIDIOC_QUERYMENU <VIDIOC_QUERYCTRL>`
      ioctls to check this.

   #. It is possible that some of the menu indices in a control of
      type ``V4L2_CTRL_TYPE_MENU`` may not be supported (``VIDIOC_QUERYMENU``
      will return an error). A good example is the list of supported MPEG
      audio bitrates. Some drivers only support one or two bitrates, others
      support a wider range.
108 109 110 111 112 113 114 115

All controls use machine endianness.


Enumerating Extended Controls
=============================

The recommended way to enumerate over the extended controls is by using
116
:ref:`VIDIOC_QUERYCTRL` in combination with the
117 118 119 120 121 122 123 124 125
``V4L2_CTRL_FLAG_NEXT_CTRL`` flag:


.. code-block:: c

    struct v4l2_queryctrl qctrl;

    qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
    while (0 == ioctl (fd, VIDIOC_QUERYCTRL, &qctrl)) {
126 127
	/* ... */
	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    }

The initial control ID is set to 0 ORed with the
``V4L2_CTRL_FLAG_NEXT_CTRL`` flag. The ``VIDIOC_QUERYCTRL`` ioctl will
return the first control with a higher ID than the specified one. When
no such controls are found an error is returned.

If you want to get all controls within a specific control class, then
you can set the initial ``qctrl.id`` value to the control class and add
an extra check to break out of the loop when a control of another
control class is found:


.. code-block:: c

    qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
    while (0 == ioctl(fd, VIDIOC_QUERYCTRL, &qctrl)) {
145 146 147 148
	if (V4L2_CTRL_ID2CLASS(qctrl.id) != V4L2_CTRL_CLASS_MPEG)
	    break;
	    /* ... */
	qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
    }

The 32-bit ``qctrl.id`` value is subdivided into three bit ranges: the
top 4 bits are reserved for flags (e. g. ``V4L2_CTRL_FLAG_NEXT_CTRL``)
and are not actually part of the ID. The remaining 28 bits form the
control ID, of which the most significant 12 bits define the control
class and the least significant 16 bits identify the control within the
control class. It is guaranteed that these last 16 bits are always
non-zero for controls. The range of 0x1000 and up are reserved for
driver-specific controls. The macro ``V4L2_CTRL_ID2CLASS(id)`` returns
the control class ID based on a control ID.

If the driver does not support extended controls, then
``VIDIOC_QUERYCTRL`` will fail when used in combination with
``V4L2_CTRL_FLAG_NEXT_CTRL``. In that case the old method of enumerating
control should be used (see :ref:`enum_all_controls`). But if it is
supported, then it is guaranteed to enumerate over all controls,
including driver-private controls.


Creating Control Panels
=======================

It is possible to create control panels for a graphical user interface
where the user can select the various controls. Basically you will have
to iterate over all controls using the method described above. Each
control class starts with a control of type
``V4L2_CTRL_TYPE_CTRL_CLASS``. ``VIDIOC_QUERYCTRL`` will return the name
of this control class which can be used as the title of a tab page
within a control panel.

The flags field of struct :ref:`v4l2_queryctrl <v4l2-queryctrl>` also
contains hints on the behavior of the control. See the
182
:ref:`VIDIOC_QUERYCTRL` documentation for more
183
details.