-An introduction to the videobuf layer
-Jonathan Corbet <corbet@lwn.net>
+Videobuf Framework
+==================
+
+Author: Jonathan Corbet <corbet@lwn.net>
+
Current as of 2.6.33
+.. note::
+
+ The videobuf framework was deprecated in favor of videobuf2. Shouldn't
+ be used on new drivers.
+
+Introduction
+------------
+
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
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:
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:
+.. code-block:: none
+
<media/videobuf-dma-sg.h> /* Physically scattered */
<media/videobuf-vmalloc.h> /* vmalloc() buffers */
<media/videobuf-dma-contig.h> /* Physically contiguous */
The next step is to write four simple callbacks to help videobuf deal with
the management of buffers:
+.. code-block:: none
+
struct videobuf_queue_ops {
int (*buf_setup)(struct videobuf_queue *q,
unsigned int *count, unsigned int *size);
and field fields properly. If the buffer's state field is
VIDEOBUF_NEEDS_INIT, the driver should pass it to:
+.. code-block:: none
+
int videobuf_iolock(struct videobuf_queue* q, struct videobuf_buffer *vb,
struct v4l2_framebuffer *fbuf);
used. The driver should ensure that there is no I/O active on the buffer,
then pass it to the appropriate free routine(s):
+.. code-block:: none
+
/* Scatter/gather drivers */
int videobuf_dma_unmap(struct videobuf_queue *q,
struct videobuf_dmabuf *dma);
One way to ensure that a buffer is no longer under I/O is to pass it to:
+.. code-block:: none
+
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
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:
+.. code-block:: none
+
void videobuf_queue_sg_init(struct videobuf_queue *q,
struct videobuf_queue_ops *ops,
struct device *dev,
easy to do that with the same code. To implement read(), the driver need
only make a call to one of:
+.. code-block:: none
+
ssize_t videobuf_read_one(struct videobuf_queue *q,
char __user *data, size_t count,
loff_t *ppos, int nonblocking);
The poll() function can usually be implemented with a direct call to:
+.. code-block:: none
+
unsigned int videobuf_poll_stream(struct file *file,
struct videobuf_queue *q,
poll_table *wait);
V4L2 drivers, the often-complex mmap() implementation simplifies to a
single call to:
+.. code-block:: none
+
int videobuf_mmap_mapper(struct videobuf_queue *q,
struct vm_area_struct *vma);
The release() function requires two separate videobuf calls:
+.. code-block:: none
+
void videobuf_stop(struct videobuf_queue *q);
int videobuf_mmap_free(struct videobuf_queue *q);
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:
+.. code-block:: none
+
int videobuf_reqbufs(struct videobuf_queue *q,
struct v4l2_requestbuffers *req);
int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b);
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
the vidioc_reqbufs() function, *after* calling videobuf_reqbufs(). The
first step is a call to:
+.. code-block:: none
+
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:
+.. code-block:: none
+
struct scatterlist *sglist;
int sglen;
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,
scatterlist structure described above. Drivers using the vmalloc() method
can get a memory pointer with:
+.. code-block:: none
+
void *videobuf_to_vmalloc(struct videobuf_buffer *buf);
For contiguous DMA drivers, the function to use is:
+.. code-block:: none
+
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