diff options
author | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-07-17 15:49:56 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-07-17 16:30:36 -0300 |
commit | 9488fed623eff249273b83503abfc8a20409f6b1 (patch) | |
tree | 3c71050ce059e20db63662d4b8d25f487d451cf2 /Documentation/media/kapi | |
parent | 4c21d4fb1b16eaaa6462e76a0eb6b70235a966ea (diff) | |
download | op-kernel-dev-9488fed623eff249273b83503abfc8a20409f6b1.zip op-kernel-dev-9488fed623eff249273b83503abfc8a20409f6b1.tar.gz |
[media] doc-rst: move videobuf documentation to media/kapi
This document describes a kapi framework. Move it to the right
place.
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
Diffstat (limited to 'Documentation/media/kapi')
-rw-r--r-- | Documentation/media/kapi/v4l2-controls.rst | 169 | ||||
-rw-r--r-- | Documentation/media/kapi/videobuf.rst | 355 |
2 files changed, 477 insertions, 47 deletions
diff --git a/Documentation/media/kapi/v4l2-controls.rst b/Documentation/media/kapi/v4l2-controls.rst index 5e759ca..8ff9ee8 100644 --- a/Documentation/media/kapi/v4l2-controls.rst +++ b/Documentation/media/kapi/v4l2-controls.rst @@ -1,5 +1,8 @@ +V4L2 Controls +============= + Introduction -============ +------------ The V4L2 control API seems simple enough, but quickly becomes very hard to implement correctly in drivers. But much of the code needed to handle controls @@ -26,7 +29,7 @@ for V4L2 drivers and struct v4l2_subdev for sub-device drivers. Objects in the framework -======================== +------------------------ There are two main objects: @@ -39,12 +42,14 @@ controls, possibly to controls owned by other handlers. Basic usage for V4L2 and sub-device drivers -=========================================== +------------------------------------------- 1) Prepare the driver: 1.1) Add the handler to your driver's top-level struct: +.. code-block:: none + struct foo_dev { ... struct v4l2_ctrl_handler ctrl_handler; @@ -55,16 +60,20 @@ Basic usage for V4L2 and sub-device drivers 1.2) Initialize the handler: +.. code-block:: none + v4l2_ctrl_handler_init(&foo->ctrl_handler, nr_of_controls); - The second argument is a hint telling the function how many controls this - handler is expected to handle. It will allocate a hashtable based on this - information. It is a hint only. +The second argument is a hint telling the function how many controls this +handler is expected to handle. It will allocate a hashtable based on this +information. It is a hint only. 1.3) Hook the control handler into the driver: 1.3.1) For V4L2 drivers do this: +.. code-block:: none + struct foo_dev { ... struct v4l2_device v4l2_dev; @@ -75,15 +84,17 @@ Basic usage for V4L2 and sub-device drivers foo->v4l2_dev.ctrl_handler = &foo->ctrl_handler; - Where foo->v4l2_dev is of type struct v4l2_device. +Where foo->v4l2_dev is of type struct v4l2_device. - Finally, remove all control functions from your v4l2_ioctl_ops (if any): - vidioc_queryctrl, vidioc_query_ext_ctrl, vidioc_querymenu, vidioc_g_ctrl, - vidioc_s_ctrl, vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls. - Those are now no longer needed. +Finally, remove all control functions from your v4l2_ioctl_ops (if any): +vidioc_queryctrl, vidioc_query_ext_ctrl, vidioc_querymenu, vidioc_g_ctrl, +vidioc_s_ctrl, vidioc_g_ext_ctrls, vidioc_try_ext_ctrls and vidioc_s_ext_ctrls. +Those are now no longer needed. 1.3.2) For sub-device drivers do this: +.. code-block:: none + struct foo_dev { ... struct v4l2_subdev sd; @@ -94,10 +105,12 @@ Basic usage for V4L2 and sub-device drivers foo->sd.ctrl_handler = &foo->ctrl_handler; - Where foo->sd is of type struct v4l2_subdev. +Where foo->sd is of type struct v4l2_subdev. - And set all core control ops in your struct v4l2_subdev_core_ops to these - helpers: +And set all core control ops in your struct v4l2_subdev_core_ops to these +helpers: + +.. code-block:: none .queryctrl = v4l2_subdev_queryctrl, .querymenu = v4l2_subdev_querymenu, @@ -107,12 +120,14 @@ Basic usage for V4L2 and sub-device drivers .try_ext_ctrls = v4l2_subdev_try_ext_ctrls, .s_ext_ctrls = v4l2_subdev_s_ext_ctrls, - Note: this is a temporary solution only. Once all V4L2 drivers that depend - on subdev drivers are converted to the control framework these helpers will - no longer be needed. +Note: this is a temporary solution only. Once all V4L2 drivers that depend +on subdev drivers are converted to the control framework these helpers will +no longer be needed. 1.4) Clean up the handler at the end: +.. code-block:: none + v4l2_ctrl_handler_free(&foo->ctrl_handler); @@ -120,12 +135,16 @@ Basic usage for V4L2 and sub-device drivers You add non-menu controls by calling v4l2_ctrl_new_std: +.. code-block:: none + struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, s32 min, s32 max, u32 step, s32 def); Menu and integer menu controls are added by calling v4l2_ctrl_new_std_menu: +.. code-block:: none + struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, s32 max, s32 skip_mask, s32 def); @@ -133,6 +152,8 @@ Menu and integer menu controls are added by calling v4l2_ctrl_new_std_menu: Menu controls with a driver specific menu are added by calling v4l2_ctrl_new_std_menu_items: +.. code-block:: none + struct v4l2_ctrl *v4l2_ctrl_new_std_menu_items( struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, s32 max, @@ -141,12 +162,16 @@ v4l2_ctrl_new_std_menu_items: Integer menu controls with a driver specific menu can be added by calling v4l2_ctrl_new_int_menu: +.. code-block:: none + struct v4l2_ctrl *v4l2_ctrl_new_int_menu(struct v4l2_ctrl_handler *hdl, const struct v4l2_ctrl_ops *ops, u32 id, s32 max, s32 def, const s64 *qmenu_int); These functions are typically called right after the v4l2_ctrl_handler_init: +.. code-block:: none + static const s64 exp_bias_qmenu[] = { -2, -1, 0, 1, 2 }; @@ -223,6 +248,8 @@ a bit faster that way. 3) Optionally force initial control setup: +.. code-block:: none + v4l2_ctrl_handler_setup(&foo->ctrl_handler); This will call s_ctrl for all controls unconditionally. Effectively this @@ -232,12 +259,16 @@ the hardware are in sync. 4) Finally: implement the v4l2_ctrl_ops +.. code-block:: none + static const struct v4l2_ctrl_ops foo_ctrl_ops = { .s_ctrl = foo_s_ctrl, }; Usually all you need is s_ctrl: +.. code-block:: none + static int foo_s_ctrl(struct v4l2_ctrl *ctrl) { struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler); @@ -262,16 +293,14 @@ to do any validation of control values, or implement QUERYCTRL, QUERY_EXT_CTRL and QUERYMENU. And G/S_CTRL as well as G/TRY/S_EXT_CTRLS are automatically supported. -============================================================================== +.. note:: -The remainder of this document deals with more advanced topics and scenarios. -In practice the basic usage as described above is sufficient for most drivers. - -=============================================================================== + The remainder sections deal with more advanced controls topics and scenarios. + In practice the basic usage as described above is sufficient for most drivers. Inheriting Controls -=================== +------------------- When a sub-device is registered with a V4L2 driver by calling v4l2_device_register_subdev() and the ctrl_handler fields of both v4l2_subdev @@ -286,21 +315,25 @@ of v4l2_device. Accessing Control Values -======================== +------------------------ The following union is used inside the control framework to access control values: -union v4l2_ctrl_ptr { - s32 *p_s32; - s64 *p_s64; - char *p_char; - void *p; -}; +.. code-block:: none + + union v4l2_ctrl_ptr { + s32 *p_s32; + s64 *p_s64; + char *p_char; + void *p; + }; The v4l2_ctrl struct contains these fields that can be used to access both current and new values: +.. code-block:: none + s32 val; struct { s32 val; @@ -312,6 +345,8 @@ current and new values: If the control has a simple s32 type type, then: +.. code-block:: none + &ctrl->val == ctrl->p_new.p_s32 &ctrl->cur.val == ctrl->p_cur.p_s32 @@ -334,6 +369,8 @@ exception is for controls that return a volatile register such as a signal strength read-out that changes continuously. In that case you will need to implement g_volatile_ctrl like this: +.. code-block:: none + static int foo_g_volatile_ctrl(struct v4l2_ctrl *ctrl) { switch (ctrl->id) { @@ -350,6 +387,8 @@ changes. To mark a control as volatile you have to set V4L2_CTRL_FLAG_VOLATILE: +.. code-block:: none + ctrl = v4l2_ctrl_new_std(&sd->ctrl_handler, ...); if (ctrl) ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; @@ -369,6 +408,8 @@ not to introduce deadlocks. Outside of the control ops you have to go through to helper functions to get or set a single control value safely in your driver: +.. code-block:: none + s32 v4l2_ctrl_g_ctrl(struct v4l2_ctrl *ctrl); int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val); @@ -378,6 +419,8 @@ will result in a deadlock since these helpers lock the handler as well. You can also take the handler lock yourself: +.. code-block:: none + mutex_lock(&state->ctrl_handler.lock); pr_info("String value is '%s'\n", ctrl1->p_cur.p_char); pr_info("Integer value is '%s'\n", ctrl2->cur.val); @@ -385,10 +428,12 @@ You can also take the handler lock yourself: Menu Controls -============= +------------- The v4l2_ctrl struct contains this union: +.. code-block:: none + union { u32 step; u32 menu_skip_mask; @@ -411,10 +456,12 @@ control, or by calling v4l2_ctrl_new_std_menu(). Custom Controls -=============== +--------------- Driver specific controls can be created using v4l2_ctrl_new_custom(): +.. code-block:: none + static const struct v4l2_ctrl_config ctrl_filter = { .ops = &ctrl_custom_ops, .id = V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER, @@ -437,7 +484,7 @@ control and will fill in the name, type and flags fields accordingly. Active and Grabbed Controls -=========================== +--------------------------- If you get more complex relationships between controls, then you may have to activate and deactivate controls. For example, if the Chroma AGC control is @@ -461,16 +508,18 @@ starts or stops streaming. Control Clusters -================ +---------------- By default all controls are independent from the others. But in more complex scenarios you can get dependencies from one control to another. In that case you need to 'cluster' them: +.. code-block:: none + struct foo { struct v4l2_ctrl_handler ctrl_handler; -#define AUDIO_CL_VOLUME (0) -#define AUDIO_CL_MUTE (1) + #define AUDIO_CL_VOLUME (0) + #define AUDIO_CL_MUTE (1) struct v4l2_ctrl *audio_cluster[2]; ... }; @@ -489,6 +538,8 @@ composite control. Similar to how a 'struct' works in C. So when s_ctrl is called with V4L2_CID_AUDIO_VOLUME as argument, you should set all two controls belonging to the audio_cluster: +.. code-block:: none + static int foo_s_ctrl(struct v4l2_ctrl *ctrl) { struct foo *state = container_of(ctrl->handler, struct foo, ctrl_handler); @@ -509,12 +560,16 @@ all two controls belonging to the audio_cluster: In the example above the following are equivalent for the VOLUME case: +.. code-block:: none + ctrl == ctrl->cluster[AUDIO_CL_VOLUME] == state->audio_cluster[AUDIO_CL_VOLUME] ctrl->cluster[AUDIO_CL_MUTE] == state->audio_cluster[AUDIO_CL_MUTE] In practice using cluster arrays like this becomes very tiresome. So instead the following equivalent method is used: +.. code-block:: none + struct { /* audio cluster */ struct v4l2_ctrl *volume; @@ -525,6 +580,8 @@ The anonymous struct is used to clearly 'cluster' these two control pointers, but it serves no other purpose. The effect is the same as creating an array with two control pointers. So you can just do: +.. code-block:: none + state->volume = v4l2_ctrl_new_std(&state->ctrl_handler, ...); state->mute = v4l2_ctrl_new_std(&state->ctrl_handler, ...); v4l2_ctrl_cluster(2, &state->volume); @@ -554,7 +611,7 @@ The 'is_new' flag is always 1 when called from v4l2_ctrl_handler_setup(). Handling autogain/gain-type Controls with Auto Clusters -======================================================= +------------------------------------------------------- A common type of control cluster is one that handles 'auto-foo/foo'-type controls. Typical examples are autogain/gain, autoexposure/exposure, @@ -579,8 +636,10 @@ changing that control affects the control flags of the manual controls. In order to simplify this a special variation of v4l2_ctrl_cluster was introduced: -void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, - u8 manual_val, bool set_volatile); +.. code-block:: none + + void v4l2_ctrl_auto_cluster(unsigned ncontrols, struct v4l2_ctrl **controls, + u8 manual_val, bool set_volatile); The first two arguments are identical to v4l2_ctrl_cluster. The third argument tells the framework which value switches the cluster into manual mode. The @@ -597,7 +656,7 @@ flag and volatile handling. VIDIOC_LOG_STATUS Support -========================= +------------------------- This ioctl allow you to dump the current status of a driver to the kernel log. The v4l2_ctrl_handler_log_status(ctrl_handler, prefix) can be used to dump the @@ -607,7 +666,7 @@ for you. Different Handlers for Different Video Nodes -============================================ +-------------------------------------------- Usually the V4L2 driver has just one control handler that is global for all video nodes. But you can also specify different control handlers for @@ -632,6 +691,8 @@ of another handler (e.g. for a video device node), then you should first add the controls to the first handler, add the other controls to the second handler and finally add the first handler to the second. For example: +.. code-block:: none + v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_VOLUME, ...); v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...); v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...); @@ -644,6 +705,8 @@ all controls. Or you can add specific controls to a handler: +.. code-block:: none + volume = v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_AUDIO_VOLUME, ...); v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_BRIGHTNESS, ...); v4l2_ctrl_new_std(&video_ctrl_handler, &ops, V4L2_CID_CONTRAST, ...); @@ -651,6 +714,8 @@ Or you can add specific controls to a handler: What you should not do is make two identical controls for two handlers. For example: +.. code-block:: none + v4l2_ctrl_new_std(&radio_ctrl_handler, &radio_ops, V4L2_CID_AUDIO_MUTE, ...); v4l2_ctrl_new_std(&video_ctrl_handler, &video_ops, V4L2_CID_AUDIO_MUTE, ...); @@ -660,7 +725,7 @@ can twiddle. Finding Controls -================ +---------------- Normally you have created the controls yourself and you can store the struct v4l2_ctrl pointer into your own struct. @@ -670,6 +735,8 @@ not own. For example, if you have to find a volume control from a subdev. You can do that by calling v4l2_ctrl_find: +.. code-block:: none + struct v4l2_ctrl *volume; volume = v4l2_ctrl_find(sd->ctrl_handler, V4L2_CID_AUDIO_VOLUME); @@ -677,6 +744,8 @@ You can do that by calling v4l2_ctrl_find: Since v4l2_ctrl_find will lock the handler you have to be careful where you use it. For example, this is not a good idea: +.. code-block:: none + struct v4l2_ctrl_handler ctrl_handler; v4l2_ctrl_new_std(&ctrl_handler, &video_ops, V4L2_CID_BRIGHTNESS, ...); @@ -684,6 +753,8 @@ use it. For example, this is not a good idea: ...and in video_ops.s_ctrl: +.. code-block:: none + case V4L2_CID_BRIGHTNESS: contrast = v4l2_find_ctrl(&ctrl_handler, V4L2_CID_CONTRAST); ... @@ -695,7 +766,7 @@ It is recommended not to use this function from inside the control ops. Inheriting Controls -=================== +------------------- When one control handler is added to another using v4l2_ctrl_add_handler, then by default all controls from one are merged to the other. But a subdev might @@ -704,6 +775,8 @@ not when it is used in consumer-level hardware. In that case you want to keep those low-level controls local to the subdev. You can do this by simply setting the 'is_private' flag of the control to 1: +.. code-block:: none + static const struct v4l2_ctrl_config ctrl_private = { .ops = &ctrl_custom_ops, .id = V4L2_CID_..., @@ -720,7 +793,7 @@ These controls will now be skipped when v4l2_ctrl_add_handler is called. V4L2_CTRL_TYPE_CTRL_CLASS Controls -================================== +---------------------------------- Controls of this type can be used by GUIs to get the name of the control class. A fully featured GUI can make a dialog with multiple tabs with each tab @@ -733,14 +806,16 @@ class is added. Adding Notify Callbacks -======================= +----------------------- Sometimes the platform or bridge driver needs to be notified when a control from a sub-device driver changes. You can set a notify callback by calling this function: -void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, - void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv); +.. code-block:: none + + void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, + void (*notify)(struct v4l2_ctrl *ctrl, void *priv), void *priv); Whenever the give control changes value the notify callback will be called with a pointer to the control and the priv pointer that was passed with diff --git a/Documentation/media/kapi/videobuf.rst b/Documentation/media/kapi/videobuf.rst new file mode 100644 index 0000000..3ffe9e9 --- /dev/null +++ b/Documentation/media/kapi/videobuf.rst @@ -0,0 +1,355 @@ +An introduction to the videobuf layer +Jonathan Corbet <corbet@lwn.net> +Current as of 2.6.33 + +The videobuf layer functions as a sort of glue layer between a V4L2 driver +and user space. It handles the allocation and management of buffers for +the storage of video frames. There is a set of functions which can be used +to implement many of the standard POSIX I/O system calls, including read(), +poll(), and, happily, mmap(). Another set of functions can be used to +implement the bulk of the V4L2 ioctl() calls related to streaming I/O, +including buffer allocation, queueing and dequeueing, and streaming +control. Using videobuf imposes a few design decisions on the driver +author, but the payback comes in the form of reduced code in the driver and +a consistent implementation of the V4L2 user-space API. + +Buffer types + +Not all video devices use the same kind of buffers. In fact, there are (at +least) three common variations: + + - Buffers which are scattered in both the physical and (kernel) virtual + address spaces. (Almost) all user-space buffers are like this, but it + makes great sense to allocate kernel-space buffers this way as well when + it is possible. Unfortunately, it is not always possible; working with + this kind of buffer normally requires hardware which can do + scatter/gather DMA operations. + + - Buffers which are physically scattered, but which are virtually + contiguous; buffers allocated with vmalloc(), in other words. These + buffers are just as hard to use for DMA operations, but they can be + useful in situations where DMA is not available but virtually-contiguous + buffers are convenient. + + - Buffers which are physically contiguous. Allocation of this kind of + buffer can be unreliable on fragmented systems, but simpler DMA + controllers cannot deal with anything else. + +Videobuf can work with all three types of buffers, but the driver author +must pick one at the outset and design the driver around that decision. + +[It's worth noting that there's a fourth kind of buffer: "overlay" buffers +which are located within the system's video memory. The overlay +functionality is considered to be deprecated for most use, but it still +shows up occasionally in system-on-chip drivers where the performance +benefits merit the use of this technique. Overlay buffers can be handled +as a form of scattered buffer, but there are very few implementations in +the kernel and a description of this technique is currently beyond the +scope of this document.] + +Data structures, callbacks, and initialization + +Depending on which type of buffers are being used, the driver should +include one of the following files: + + <media/videobuf-dma-sg.h> /* Physically scattered */ + <media/videobuf-vmalloc.h> /* vmalloc() buffers */ + <media/videobuf-dma-contig.h> /* Physically contiguous */ + +The driver's data structure describing a V4L2 device should include a +struct videobuf_queue instance for the management of the buffer queue, +along with a list_head for the queue of available buffers. There will also +need to be an interrupt-safe spinlock which is used to protect (at least) +the queue. + +The next step is to write four simple callbacks to help videobuf deal with +the management of buffers: + + struct videobuf_queue_ops { + int (*buf_setup)(struct videobuf_queue *q, + unsigned int *count, unsigned int *size); + int (*buf_prepare)(struct videobuf_queue *q, + struct videobuf_buffer *vb, + enum v4l2_field field); + void (*buf_queue)(struct videobuf_queue *q, + struct videobuf_buffer *vb); + void (*buf_release)(struct videobuf_queue *q, + struct videobuf_buffer *vb); + }; + +buf_setup() is called early in the I/O process, when streaming is being +initiated; its purpose is to tell videobuf about the I/O stream. The count +parameter will be a suggested number of buffers to use; the driver should +check it for rationality and adjust it if need be. As a practical rule, a +minimum of two buffers are needed for proper streaming, and there is +usually a maximum (which cannot exceed 32) which makes sense for each +device. The size parameter should be set to the expected (maximum) size +for each frame of data. + +Each buffer (in the form of a struct videobuf_buffer pointer) will be +passed to buf_prepare(), which should set the buffer's size, width, height, +and field fields properly. If the buffer's state field is +VIDEOBUF_NEEDS_INIT, the driver should pass it to: + + int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb, + struct v4l2_framebuffer *fbuf); + +Among other things, this call will usually allocate memory for the buffer. +Finally, the buf_prepare() function should set the buffer's state to +VIDEOBUF_PREPARED. + +When a buffer is queued for I/O, it is passed to buf_queue(), which should +put it onto the driver's list of available buffers and set its state to +VIDEOBUF_QUEUED. Note that this function is called with the queue spinlock +held; if it tries to acquire it as well things will come to a screeching +halt. Yes, this is the voice of experience. Note also that videobuf may +wait on the first buffer in the queue; placing other buffers in front of it +could again gum up the works. So use list_add_tail() to enqueue buffers. + +Finally, buf_release() is called when a buffer is no longer intended to be +used. The driver should ensure that there is no I/O active on the buffer, +then pass it to the appropriate free routine(s): + + /* Scatter/gather drivers */ + int videobuf_dma_unmap(struct videobuf_queue *q, + struct videobuf_dmabuf *dma); + int videobuf_dma_free(struct videobuf_dmabuf *dma); + + /* vmalloc drivers */ + void videobuf_vmalloc_free (struct videobuf_buffer *buf); + + /* Contiguous drivers */ + void videobuf_dma_contig_free(struct videobuf_queue *q, + struct videobuf_buffer *buf); + +One way to ensure that a buffer is no longer under I/O is to pass it to: + + int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr); + +Here, vb is the buffer, non_blocking indicates whether non-blocking I/O +should be used (it should be zero in the buf_release() case), and intr +controls whether an interruptible wait is used. + +File operations + +At this point, much of the work is done; much of the rest is slipping +videobuf calls into the implementation of the other driver callbacks. The +first step is in the open() function, which must initialize the +videobuf queue. The function to use depends on the type of buffer used: + + void videobuf_queue_sg_init(struct videobuf_queue *q, + struct videobuf_queue_ops *ops, + struct device *dev, + spinlock_t *irqlock, + enum v4l2_buf_type type, + enum v4l2_field field, + unsigned int msize, + void *priv); + + void videobuf_queue_vmalloc_init(struct videobuf_queue *q, + struct videobuf_queue_ops *ops, + struct device *dev, + spinlock_t *irqlock, + enum v4l2_buf_type type, + enum v4l2_field field, + unsigned int msize, + void *priv); + + void videobuf_queue_dma_contig_init(struct videobuf_queue *q, + struct videobuf_queue_ops *ops, + struct device *dev, + spinlock_t *irqlock, + enum v4l2_buf_type type, + enum v4l2_field field, + unsigned int msize, + void *priv); + +In each case, the parameters are the same: q is the queue structure for the +device, ops is the set of callbacks as described above, dev is the device +structure for this video device, irqlock is an interrupt-safe spinlock to +protect access to the data structures, type is the buffer type used by the +device (cameras will use V4L2_BUF_TYPE_VIDEO_CAPTURE, for example), field +describes which field is being captured (often V4L2_FIELD_NONE for +progressive devices), msize is the size of any containing structure used +around struct videobuf_buffer, and priv is a private data pointer which +shows up in the priv_data field of struct videobuf_queue. Note that these +are void functions which, evidently, are immune to failure. + +V4L2 capture drivers can be written to support either of two APIs: the +read() system call and the rather more complicated streaming mechanism. As +a general rule, it is necessary to support both to ensure that all +applications have a chance of working with the device. Videobuf makes it +easy to do that with the same code. To implement read(), the driver need +only make a call to one of: + + ssize_t videobuf_read_one(struct videobuf_queue *q, + char __user *data, size_t count, + loff_t *ppos, int nonblocking); + + ssize_t videobuf_read_stream(struct videobuf_queue *q, + char __user *data, size_t count, + loff_t *ppos, int vbihack, int nonblocking); + +Either one of these functions will read frame data into data, returning the +amount actually read; the difference is that videobuf_read_one() will only +read a single frame, while videobuf_read_stream() will read multiple frames +if they are needed to satisfy the count requested by the application. A +typical driver read() implementation will start the capture engine, call +one of the above functions, then stop the engine before returning (though a +smarter implementation might leave the engine running for a little while in +anticipation of another read() call happening in the near future). + +The poll() function can usually be implemented with a direct call to: + + unsigned int videobuf_poll_stream(struct file *file, + struct videobuf_queue *q, + poll_table *wait); + +Note that the actual wait queue eventually used will be the one associated +with the first available buffer. + +When streaming I/O is done to kernel-space buffers, the driver must support +the mmap() system call to enable user space to access the data. In many +V4L2 drivers, the often-complex mmap() implementation simplifies to a +single call to: + + int videobuf_mmap_mapper(struct videobuf_queue *q, + struct vm_area_struct *vma); + +Everything else is handled by the videobuf code. + +The release() function requires two separate videobuf calls: + + void videobuf_stop(struct videobuf_queue *q); + int videobuf_mmap_free(struct videobuf_queue *q); + +The call to videobuf_stop() terminates any I/O in progress - though it is +still up to the driver to stop the capture engine. The call to +videobuf_mmap_free() will ensure that all buffers have been unmapped; if +so, they will all be passed to the buf_release() callback. If buffers +remain mapped, videobuf_mmap_free() returns an error code instead. The +purpose is clearly to cause the closing of the file descriptor to fail if +buffers are still mapped, but every driver in the 2.6.32 kernel cheerfully +ignores its return value. + +ioctl() operations + +The V4L2 API includes a very long list of driver callbacks to respond to +the many ioctl() commands made available to user space. A number of these +- those associated with streaming I/O - turn almost directly into videobuf +calls. The relevant helper functions are: + + int videobuf_reqbufs(struct videobuf_queue *q, + struct v4l2_requestbuffers *req); + int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b); + int videobuf_qbuf(struct videobuf_queue *q, struct v4l2_buffer *b); + int videobuf_dqbuf(struct videobuf_queue *q, struct v4l2_buffer *b, + int nonblocking); + int videobuf_streamon(struct videobuf_queue *q); + int videobuf_streamoff(struct videobuf_queue *q); + +So, for example, a VIDIOC_REQBUFS call turns into a call to the driver's +vidioc_reqbufs() callback which, in turn, usually only needs to locate the +proper struct videobuf_queue pointer and pass it to videobuf_reqbufs(). +These support functions can replace a great deal of buffer management +boilerplate in a lot of V4L2 drivers. + +The vidioc_streamon() and vidioc_streamoff() functions will be a bit more +complex, of course, since they will also need to deal with starting and +stopping the capture engine. + +Buffer allocation + +Thus far, we have talked about buffers, but have not looked at how they are +allocated. The scatter/gather case is the most complex on this front. For +allocation, the driver can leave buffer allocation entirely up to the +videobuf layer; in this case, buffers will be allocated as anonymous +user-space pages and will be very scattered indeed. If the application is +using user-space buffers, no allocation is needed; the videobuf layer will +take care of calling get_user_pages() and filling in the scatterlist array. + +If the driver needs to do its own memory allocation, it should be done in +the vidioc_reqbufs() function, *after* calling videobuf_reqbufs(). The +first step is a call to: + + struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf); + +The returned videobuf_dmabuf structure (defined in +<media/videobuf-dma-sg.h>) includes a couple of relevant fields: + + struct scatterlist *sglist; + int sglen; + +The driver must allocate an appropriately-sized scatterlist array and +populate it with pointers to the pieces of the allocated buffer; sglen +should be set to the length of the array. + +Drivers using the vmalloc() method need not (and cannot) concern themselves +with buffer allocation at all; videobuf will handle those details. The +same is normally true of contiguous-DMA drivers as well; videobuf will +allocate the buffers (with dma_alloc_coherent()) when it sees fit. That +means that these drivers may be trying to do high-order allocations at any +time, an operation which is not always guaranteed to work. Some drivers +play tricks by allocating DMA space at system boot time; videobuf does not +currently play well with those drivers. + +As of 2.6.31, contiguous-DMA drivers can work with a user-supplied buffer, +as long as that buffer is physically contiguous. Normal user-space +allocations will not meet that criterion, but buffers obtained from other +kernel drivers, or those contained within huge pages, will work with these +drivers. + +Filling the buffers + +The final part of a videobuf implementation has no direct callback - it's +the portion of the code which actually puts frame data into the buffers, +usually in response to interrupts from the device. For all types of +drivers, this process works approximately as follows: + + - Obtain the next available buffer and make sure that somebody is actually + waiting for it. + + - Get a pointer to the memory and put video data there. + + - Mark the buffer as done and wake up the process waiting for it. + +Step (1) above is done by looking at the driver-managed list_head structure +- the one which is filled in the buf_queue() callback. Because starting +the engine and enqueueing buffers are done in separate steps, it's possible +for the engine to be running without any buffers available - in the +vmalloc() case especially. So the driver should be prepared for the list +to be empty. It is equally possible that nobody is yet interested in the +buffer; the driver should not remove it from the list or fill it until a +process is waiting on it. That test can be done by examining the buffer's +done field (a wait_queue_head_t structure) with waitqueue_active(). + +A buffer's state should be set to VIDEOBUF_ACTIVE before being mapped for +DMA; that ensures that the videobuf layer will not try to do anything with +it while the device is transferring data. + +For scatter/gather drivers, the needed memory pointers will be found in the +scatterlist structure described above. Drivers using the vmalloc() method +can get a memory pointer with: + + void *videobuf_to_vmalloc(struct videobuf_buffer *buf); + +For contiguous DMA drivers, the function to use is: + + dma_addr_t videobuf_to_dma_contig(struct videobuf_buffer *buf); + +The contiguous DMA API goes out of its way to hide the kernel-space address +of the DMA buffer from drivers. + +The final step is to set the size field of the relevant videobuf_buffer +structure to the actual size of the captured image, set state to +VIDEOBUF_DONE, then call wake_up() on the done queue. At this point, the +buffer is owned by the videobuf layer and the driver should not touch it +again. + +Developers who are interested in more information can go into the relevant +header files; there are a few low-level functions declared there which have +not been talked about here. Also worthwhile is the vivi driver +(drivers/media/platform/vivi.c), which is maintained as an example of how V4L2 +drivers should be written. Vivi only uses the vmalloc() API, but it's good +enough to get started with. Note also that all of these calls are exported +GPL-only, so they will not be available to non-GPL kernel modules. |