Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44061c05 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

V4L/DVB (10570): v4l2-framework: documments videobuf usage on drivers

parent 4b10d3b6
Loading
Loading
Loading
Loading
+91 −1
Original line number Diff line number Diff line
@@ -47,7 +47,9 @@ All drivers have the following structure:
3) Creating V4L2 device nodes (/dev/videoX, /dev/vbiX, /dev/radioX and
   /dev/vtxX) and keeping track of device-node specific data.

4) Filehandle-specific structs containing per-filehandle data.
4) Filehandle-specific structs containing per-filehandle data;

5) video buffer handling.

This is a rough schematic of how it all relates:

@@ -525,3 +527,91 @@ void *video_drvdata(struct file *file);
You can go from a video_device struct to the v4l2_device struct using:

struct v4l2_device *v4l2_dev = vdev->v4l2_dev;

video buffer helper functions
-----------------------------

The v4l2 core API provides a standard method for dealing with video
buffers. Those methods allow a driver to implement read(), mmap() and
overlay() on a consistent way.

There are currently methods for using video buffers on devices that
supports DMA with scatter/gather method (videobuf-dma-sg), DMA with
linear access (videobuf-dma-contig), and vmalloced buffers, mostly
used on USB drivers (videobuf-vmalloc).

Any driver using videobuf should provide operations (callbacks) for
four handlers:

ops->buf_setup   - calculates the size of the video buffers and avoid they
		   to waste more than some maximum limit of RAM;
ops->buf_prepare - fills the video buffer structs and calls
		   videobuf_iolock() to alloc and prepare mmaped memory;
ops->buf_queue   - advices the driver that another buffer were
		   requested (by read() or by QBUF);
ops->buf_release - frees any buffer that were allocated.

In order to use it, the driver need to have a code (generally called at
interrupt context) that will properly handle the buffer request lists,
announcing that a new buffer were filled.

The irq handling code should handle the videobuf task lists, in order
to advice videobuf that a new frame were filled, in order to honor to a
request. The code is generally like this one:
        if (list_empty(&dma_q->active))
		return;

        buf = list_entry(dma_q->active.next, struct vbuffer, vb.queue);

        if (!waitqueue_active(&buf->vb.done))
		return;

	/* Some logic to handle the buf may be needed here */

        list_del(&buf->vb.queue);
        do_gettimeofday(&buf->vb.ts);
        wake_up(&buf->vb.done);

Those are the videobuffer functions used on drivers, implemented on
videobuf-core:

- videobuf_queue_core_init()
  Initializes the videobuf infrastructure. This function should be
  called before any other videobuf function.

- videobuf_iolock()
  Prepares the videobuf memory for the proper method (read, mmap, overlay).

- videobuf_queue_is_busy()
  Checks if a videobuf is streaming.

- videobuf_queue_cancel()
  Stops video handling.

- videobuf_mmap_free()
  frees mmap buffers.

- videobuf_stop()
  Stops video handling, ends mmap and frees mmap and other buffers.

- V4L2 api functions. Those functions correspond to VIDIOC_foo ioctls:
   videobuf_reqbufs(), videobuf_querybuf(), videobuf_qbuf(),
   videobuf_dqbuf(), videobuf_streamon(), videobuf_streamoff().

- V4L1 api function (corresponds to VIDIOCMBUF ioctl):
   videobuf_cgmbuf()
      This function is used to provide backward compatibility with V4L1
      API.

- Some help functions for read()/poll() operations:
   videobuf_read_stream()
      For continuous stream read()
   videobuf_read_one()
      For snapshot read()
   videobuf_poll_stream()
      polling help function

The better way to understand it is to take a look at vivi driver. One
of the main reasons for vivi is to be a videobuf usage example. the
vivi_thread_tick() does the task that the IRQ callback would do on PCI
drivers (or the irq callback on USB).