[RFCv2 PATCH 15/15] Documentation: add v4l2-requests.txt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Hans Verkuil <hans.verkuil@xxxxxxxxx>

Add documentation about requests.

Signed-off-by: Hans Verkuil <hans.verkuil@xxxxxxxxx>
---
 Documentation/video4linux/v4l2-requests.txt | 233 ++++++++++++++++++++++++++++
 1 file changed, 233 insertions(+)
 create mode 100644 Documentation/video4linux/v4l2-requests.txt

diff --git a/Documentation/video4linux/v4l2-requests.txt b/Documentation/video4linux/v4l2-requests.txt
new file mode 100644
index 0000000..324a840
--- /dev/null
+++ b/Documentation/video4linux/v4l2-requests.txt
@@ -0,0 +1,233 @@
+Introduction
+============
+
+It is often useful to apply certain settings when a buffer is about to be
+filled by the DMA capture of a video capture device, ensuring that those
+settings are applied in time for them to be used with that buffer.
+
+One of the prime use-cases of this is Android's CameraHAL v3 which requires
+per-frame configuration support.
+
+But other use-cases are possible as well: changing codec settings (bit rate,
+etc.) starting with a specific buffer, preparing a configuration to be applied
+at a certain time, etc.
+
+The request API is the way V4L2 solved this problem.
+
+
+Basic Mechanism
+===============
+
+Requests are implemented by building on top of the control framework, adding
+new 'request' fields to various v4l2 structs and by adding a new ioctl:
+VIDIOC_REQUEST_CMD.
+
+The core are the additions to the control framework: normally when a control
+is set the control's value is applied immediately in the hardware. But the
+request API allows you to specify the control value for a specific request
+ID (from 1-0xffff). The control value is validated and stored for that request,
+but it won't be applied until later.
+
+Each control can support up to N requests where N is expected to be a multiple
+of VIDEO_MAX_FRAME. If N is 0, then it cannot be used with requests. Many
+controls (e.g. V4L2_CID_POWER_LINE_FREQUENCY) just make no sense in a request
+context.
+
+How many requests each control supports can be queried with VIDIOC_QUERY_EXT_CTRL
+and by checking the max_reqs field.
+
+Getting/setting/trying controls for a request can be done in two ways: one
+is to use the VIDIOC_REQUEST_CMD ioctl (more about that later), the other is
+to use VIDIOC_G/S/TRY_EXT/CTRLS and fill in a non-zero request ID. If the
+request ID is 0, then the normal behavior applies: so controls are set immediately.
+
+Request IDs are in the range of 1-65535. Applications can freely choose them,
+but controls won't support more than a fixed number of different requests.
+Requests can be deleted, see the section on VIDIOC_REQUEST_CMD.
+
+The expected usage is that request IDs are some base value + the buffer index.
+Request lookup is optimized for that scheme inside the control framework: there
+is a hash table of size VIDEO_MAX_FRAME, each element being a linked list.
+The hash function used is 'request % VIDEO_MAX_FRAME', and then the linked list
+is walked to find whether the request is in there. The expectation is that
+having more than VIDEO_MAX_FRAME requests will be very unusual, and certainly
+that the maximum number of possible requests in flight at the same time won't
+be more than a small multiple of VIDEO_MAX_FRAME.
+
+Associating a buffer with a specific request can be done by setting the new
+'request' field in struct v4l2_buffer to the request ID.
+
+Once a buffer is queued with a non-zero request ID, then it is up to the
+driver to apply the control values for that request at the right time ensuring
+that when the buffer is DMAed those values are in effect.
+
+This is entirely hardware specific, so it is the driver's responsibility. It
+will know the request ID of a buffer as soon as the vb2 buf_queue op is called.
+
+For simple cases a helper function v4l2_ctrl_apply_request() is available that
+will just apply any controls for the given request immediately. The driver can
+call that when the buffer is about to be filled. This is likely to be too crude
+for the more complex devices, in particular when dealing with settings that can
+take some time before that will take effect (e.g. focussing).
+
+
+Complex Devices
+===============
+
+For complex devices with lots of video and v4l-subdev device nodes you want to
+be able to synchronize buffers and controls for multiple nodes and apply them
+all as a single request.
+
+The way to do that is to:
+
+1) use the same request ID for all device nodes when setting controls for that
+   request.
+2) instead of using VIDIOC_QBUF use VIDIOC_PREPARE_BUF with the request field
+   set everywhere you need to have a buffer associated with the request.
+3) when all is done, call VIDIOC_REQUEST_CMD(V4L2_REQ_CMD_QUEUE) with the
+   request ID on any video or v4l-subdev node.
+
+The V4L2_REQ_CMD_QUEUE command will call a top-level 'req_queue' callback in
+the driver, at which point it is the responsibility of the driver to pull
+everything together and ensure that all prepared buffers are queued up at the
+right time to the DMA queues and all controls for that request will be applied
+at the right moment.
+
+Two helper functions were created to aid with with: vb2_qbuf_request() will
+queue up a prepared buffer with the given request ID. And v4l2_device_req_queue()
+will walk all video_device structs and do just that for each of them. The last
+function only works for simple devices, complex devices will almost certainly
+need to create their own function.
+
+
+Feedback
+========
+
+After a buffer is dequeued you can get the control values that were actually
+used when filling in that buffer by calling VIDIOC_G_EXT_CTRLS with the request
+field set to buffer->request. This can also be used to obtain additional meta
+information by creating read-only controls that are filled in by the driver
+for that specific buffer.
+
+Currently there is no event that is triggered when someone sets a new control
+value for a specific request. This can be added, but I suspect it will make
+more sense to have driver-specific events (e.g. 'EVENT_METADATA_AVAILABLE')
+that applications can use.
+
+A new control flag was added: V4L2_CTRL_FLAG_REQ_APPLIED. If set, then the
+control value for the request was applied.
+
+Note: once the control value for a request has been applied it will never be
+applied again. Only after it has been set again (using VIDIOC_S_EXT_CTRLS)
+will the control value for that request be applied.
+
+Using VIDIOC_REQUEST_CMD it is possible to keep applied values and reapply
+them, but that is not the standard behavior and is experimental since it
+is not clear whether this is actually needed (or even wanted).
+
+
+VIDIOC_REQUEST_CMD
+==================
+
+#define V4L2_REQ_CMD_BEGIN      (0)
+#define V4L2_REQ_CMD_END        (1)
+#define V4L2_REQ_CMD_DELETE     (2)
+#define V4L2_REQ_CMD_APPLY      (3)
+#define V4L2_REQ_CMD_QUEUE      (4)
+
+/* Flag for V4L2_REQ_CMD_BEGIN */
+#define V4L2_REQ_CMD_BEGIN_FL_KEEP      (1 << 0)
+
+struct v4l2_request_cmd {
+        __u32 cmd;
+        __u16 request;
+        __u16 flags;
+        union {
+                struct {
+                        __u32 data[8];
+                } raw;
+        };
+};
+
+The VIDIOC_REQUEST_CMD ioctl is used for a variety of request-related
+purposes. These will be explained in more detail below.
+
+V4L2_REQ_CMD_BEGIN/END
+----------------------
+
+While it is easy to use VIDIOC_S_EXT_CTRLS to set control values for a specific
+request, you cannot do that with VIDIOC_S_CTRL since there is no request field
+in the v4l2_control struct. And in fact it is desirable to be able to use other
+ioctls with requests as well (e.g. VIDIOC_S_SELECTION).
+
+In order to allow other ioctls to be used as part of a request you can use the
+BEGIN/END commands to bracket a bunch of other ioctls, all of which (where
+appropriate) will be stored as part of the request.
+
+Currently this is only implemented for the control ioctls. But VIDIOC_S_SELECTION
+is a prime candidate for the future. Internally however, the selection data
+would have to be stored as a control since all request data are always controls.
+
+Whether ioctls apply to a request is per-filehandle: calling VIDIOC_REQUEST_CMD
+with V4L2_REQ_CMD_BEGIN will mark the filehandle that future ioctls need to be
+applied to the specified request. V4L2_REQ_CMD_END will 'unmark' the filehandle
+and everything will be back to normal.
+
+Calling V4L2_REQ_CMD_BEGIN with the V4L2_REQ_CMD_BEGIN_FL_KEEP flag will prevent
+request control values to be discarded after they are applied. Instead they will
+be kept and re-applied the next time controls for that request need to be set.
+
+V4L2_REQ_CMD_DELETE
+-------------------
+
+Delete all control values for the given request (if non-zero) or delete all
+control request values for all requests (if zero).
+
+This is recommended at the beginning of the application to discard any old
+request control values from the driver.
+
+V4L2_REQ_CMD_APPLY
+------------------
+
+Explicitly apply the control values for the given request. This takes effect
+immediately.
+
+V4L2_REQ_CMD_QUEUE
+------------------
+
+Queue all buffers for the given request for all device nodes. This may not be
+supported by the driver. Test this by calling it with request 0: if ENOSYS is
+returned, then this functionality is not supported.
+
+
+Miscellaneous
+=============
+
+The vivid driver has support for all this: the brightness, contrast, saturation
+and hue controls all support up to VIDEO_MAX_FRAME requests.
+
+Git tree for these patches:
+
+http://git.linuxtv.org/cgit.cgi/hverkuil/media_tree.git/log/?h=requests
+
+Utilities with support for requests are available here:
+
+http://git.linuxtv.org/cgit.cgi/hverkuil/v4l-utils.git/log/?h=requests
+
+Remaining questions:
+
+- Should we keep the V4L2_REQ_CMD_BEGIN_FL_KEEP flag?
+- Do we need request-related events? And if so, which events are needed?
+- Anything missing?
+
+Known TODOs:
+
+- DocBook patches: have to wait until this is ready to be merged, which will
+  require an actual driver that wants to use it.
+- Almost certainly: add support for VIDIOC_G/S_SELECTION and requests. An
+  older version of this work exists, but it needs to be reworked quite a
+  bit. Contact me if this is needed.
+
+In case of questions contact me:
+
+Hans Verkuil <hverkuil@xxxxxxxxx>
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux