|
@@ -34,6 +34,116 @@ flags are copied from the OUTPUT video buffer to the CAPTURE video
|
|
|
buffer.
|
|
|
|
|
|
|
|
|
+Interactions between formats, controls and buffers
|
|
|
+==================================================
|
|
|
+
|
|
|
+V4L2 exposes parameters that influence the buffer size, or the way data is
|
|
|
+laid out in the buffer. Those parameters are exposed through both formats and
|
|
|
+controls. One example of such a control is the ``V4L2_CID_ROTATE`` control
|
|
|
+that modifies the direction in which pixels are stored in the buffer, as well
|
|
|
+as the buffer size when the selected format includes padding at the end of
|
|
|
+lines.
|
|
|
+
|
|
|
+The set of information needed to interpret the content of a buffer (e.g. the
|
|
|
+pixel format, the line stride, the tiling orientation or the rotation) is
|
|
|
+collectively referred to in the rest of this section as the buffer layout.
|
|
|
+
|
|
|
+Modifying formats or controls that influence the buffer size or layout require
|
|
|
+the stream to be stopped. Any attempt at such a modification while the stream
|
|
|
+is active shall cause the ioctl setting the format or the control to return
|
|
|
+the ``EBUSY`` error code.
|
|
|
+
|
|
|
+.. note::
|
|
|
+
|
|
|
+ The :c:func:`VIDIOC_S_SELECTION` ioctl can, depending on the hardware (for
|
|
|
+ instance if the device doesn't include a scaler), modify the format in
|
|
|
+ addition to the selection rectangle. Similarly, the
|
|
|
+ :c:func:`VIDIOC_S_INPUT`, :c:func:`VIDIOC_S_OUTPUT`, :c:func:`VIDIOC_S_STD`
|
|
|
+ and :c:func:`VIDIOC_S_DV_TIMINGS` ioctls can also modify the format and
|
|
|
+ selection rectangles. When those ioctls result in a buffer size or layout
|
|
|
+ change, drivers shall handle that condition as they would handle it in the
|
|
|
+ :c:func:`VIDIOC_S_FMT` ioctl in all cases described in this section.
|
|
|
+
|
|
|
+Controls that only influence the buffer layout can be modified at any time
|
|
|
+when the stream is stopped. As they don't influence the buffer size, no
|
|
|
+special handling is needed to synchronize those controls with buffer
|
|
|
+allocation.
|
|
|
+
|
|
|
+Formats and controls that influence the buffer size interact with buffer
|
|
|
+allocation. The simplest way to handle this is for drivers to always require
|
|
|
+buffers to be reallocated in order to change those formats or controls. In
|
|
|
+that case, to perform such changes, userspace applications shall first stop
|
|
|
+the video stream with the :c:func:`VIDIOC_STREAMOFF` ioctl if it is running
|
|
|
+and free all buffers with the :c:func:`VIDIOC_REQBUFS` ioctl if they are
|
|
|
+allocated. The format or controls can then be modified, and buffers shall then
|
|
|
+be reallocated and the stream restarted. A typical ioctl sequence is
|
|
|
+
|
|
|
+ #. VIDIOC_STREAMOFF
|
|
|
+ #. VIDIOC_REQBUFS(0)
|
|
|
+ #. VIDIOC_S_EXT_CTRLS
|
|
|
+ #. VIDIOC_S_FMT
|
|
|
+ #. VIDIOC_REQBUFS(n)
|
|
|
+ #. VIDIOC_QBUF
|
|
|
+ #. VIDIOC_STREAMON
|
|
|
+
|
|
|
+The second :c:func:`VIDIOC_REQBUFS` call will take the new format and control
|
|
|
+value into account to compute the buffer size to allocate. Applications can
|
|
|
+also retrieve the size by calling the :c:func:`VIDIOC_G_FMT` ioctl if needed.
|
|
|
+
|
|
|
+.. note::
|
|
|
+
|
|
|
+ The API doesn't mandate the above order for control (3.) and format (4.)
|
|
|
+ changes. Format and controls can be set in a different order, or even
|
|
|
+ interleaved, depending on the device and use case. For instance some
|
|
|
+ controls might behave differently for different pixel formats, in which
|
|
|
+ case the format might need to be set first.
|
|
|
+
|
|
|
+When reallocation is required, any attempt to modify format or controls that
|
|
|
+influences the buffer size while buffers are allocated shall cause the format
|
|
|
+or control set ioctl to return the ``EBUSY`` error. Any attempt to queue a
|
|
|
+buffer too small for the current format or controls shall cause the
|
|
|
+:c:func:`VIDIOC_QBUF` ioctl to return a ``EINVAL`` error.
|
|
|
+
|
|
|
+Buffer reallocation is an expensive operation. To avoid that cost, drivers can
|
|
|
+(and are encouraged to) allow format or controls that influence the buffer
|
|
|
+size to be changed with buffers allocated. In that case, a typical ioctl
|
|
|
+sequence to modify format and controls is
|
|
|
+
|
|
|
+ #. VIDIOC_STREAMOFF
|
|
|
+ #. VIDIOC_S_EXT_CTRLS
|
|
|
+ #. VIDIOC_S_FMT
|
|
|
+ #. VIDIOC_QBUF
|
|
|
+ #. VIDIOC_STREAMON
|
|
|
+
|
|
|
+For this sequence to operate correctly, queued buffers need to be large enough
|
|
|
+for the new format or controls. Drivers shall return a ``ENOSPC`` error in
|
|
|
+response to format change (:c:func:`VIDIOC_S_FMT`) or control changes
|
|
|
+(:c:func:`VIDIOC_S_CTRL` or :c:func:`VIDIOC_S_EXT_CTRLS`) if buffers too small
|
|
|
+for the new format are currently queued. As a simplification, drivers are
|
|
|
+allowed to return a ``EBUSY`` error from these ioctls if any buffer is
|
|
|
+currently queued, without checking the queued buffers sizes.
|
|
|
+
|
|
|
+Additionally, drivers shall return a ``EINVAL`` error from the
|
|
|
+:c:func:`VIDIOC_QBUF` ioctl if the buffer being queued is too small for the
|
|
|
+current format or controls. Together, these requirements ensure that queued
|
|
|
+buffers will always be large enough for the configured format and controls.
|
|
|
+
|
|
|
+Userspace applications can query the buffer size required for a given format
|
|
|
+and controls by first setting the desired control values and then trying the
|
|
|
+desired format. The :c:func:`VIDIOC_TRY_FMT` ioctl will return the required
|
|
|
+buffer size.
|
|
|
+
|
|
|
+ #. VIDIOC_S_EXT_CTRLS(x)
|
|
|
+ #. VIDIOC_TRY_FMT()
|
|
|
+ #. VIDIOC_S_EXT_CTRLS(y)
|
|
|
+ #. VIDIOC_TRY_FMT()
|
|
|
+
|
|
|
+The :c:func:`VIDIOC_CREATE_BUFS` ioctl can then be used to allocate buffers
|
|
|
+based on the queried sizes (for instance by allocating a set of buffers large
|
|
|
+enough for all the desired formats and controls, or by allocating separate set
|
|
|
+of appropriately sized buffers for each use case).
|
|
|
+
|
|
|
+
|
|
|
.. c:type:: v4l2_buffer
|
|
|
|
|
|
struct v4l2_buffer
|