V4L2 - RFC: DMA to userspace API

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



Hi everybody, I have been taking a look at adding DMA to userspace to
the V4L2 API.  My ideas are discussed below. Any comments/criticisms are
welcome.

1) Exisiting mechanism:
The existing streaming capture mechanism can be summarised as follows:
  1 - Set capture format (S_FMT)
  2 - Request buffers (REQBUFS)
  3 - Map buffers into userspace (QUERYBUF and mmap)
  4 - do streaming capture here.
  5 - unmap buffers (implicity unrequests buffers).

This should be changed to include an explicit "unrequest buffers"
operation (as userspace buffers can not be munmapped).  This would be
done via a REQBUFS ioctl with a count of 0.  A REQBUFS ioctl performed
while not streaming will unmap and deallocate all allocated buffers, and
allocate the requested count.  If the requested count is 0, no new
buffers are allocated.

Since munmapping buffers would still be an implicit unrequest buffers,
this will not require any change to existing user applications.  All
drivers should be modified to include this functionality (This is the
one incompatibility - can anyone see a way around this?).

2) Identification:
A driver supporting DMA to userspace will set the V4L2_FLAG_DMA flag, as
returned by QUERYCAP.

3) Requesting userspace buffers:
This is handled by the REQBUFS ioctl as before, except the user
application must set a V4L2_BUF_REQ_DMA flag in requestbuffers.

4) Mapping userspace buffers:
This is performed via the QUERYBUF ioctl.  The v4l2_buffer structure is
modified as follows:

struct v4l2_buffer
{
        int                     index;
        __u32                   type;
        __u32                   offset;
        __u32                   length;
        __u32                   bytesused;
        __u32                   flags;
        stamp_t                 timestamp;
        struct v4l2_timecode    timecode;
        __u32                   sequence;
	struct v4l2_dmabuffer	*dmabuf;
/* need some #ifdef magic here to waste 4 bytes on a 32 bit architecture
*/
        __u32                   reserved;
};

where struct v4l2_dmabuffer is:

struct v4l2_dmabuffer
{
	void			*start;
	unsigned long		size;
	unsigned long		stride;
        unsigned long           reserved[2];
};

The dmabuf pointer passed by the application is a pointer to an array of
struct v4l2_dmabuffer, with one element for each plane in the color
format (for the current formats, that would be one plane for the packed
formats, and 3 for the planar formats).

*start is the start address of the buffer.
size is the size in bytes of the buffer.
stride is the length in bytes of a line in the buffer.

5) DMA to userspace example:
  1 - set capture format (S_FMT)
  2 - request buffers (REQBUFS with V4L2_BUF_REQ_DMA set)
  3 - allocate userspace memory for the number of granted buffers.
  4 - call QUERYBUF on each buffer, filling in dmabuf with a pointer to
the struct v4l2_dmabuffer describing each buffer (note that dmabuf is
ignored if V4L2_BUF_REQ_DMA was not set when the buffers were
requested).
  5 - perform streaming capture.
  6 - unmap requested buffers (REQBUFS with count set to 0).

6) Conclusion

This is a first draft, and probably has a number of nasty flaws in it. 
Please look at it closely, and see if it looks OK to you.

As far as I can see, this API extension would give the maximum
flexibility, with a minimum of incompatibilities.

Thanks

-justin





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux