1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Streaming I/O (DMA buffer importing)</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="LINUX MEDIA INFRASTRUCTURE API"><link rel="up" href="io.html" title="Chapter&#160;3.&#160;Input/Output"><link rel="prev" href="userp.html" title="Streaming I/O (User Pointers)"><link rel="next" href="async.html" title="Asynchronous I/O"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Streaming I/O (DMA buffer importing)</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="userp.html">Prev</a>&#160;</td><th width="60%" align="center">Chapter&#160;3.&#160;Input/Output</th><td width="20%" align="right">&#160;<a accesskey="n" href="async.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="dmabuf"></a>Streaming I/O (DMA buffer importing)</h2></div></div></div><div class="note" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Experimental</h3><p>This is an <a class="link" href="hist-v4l2.html#experimental" title="Experimental API Elements">experimental</a>
2      interface and may change in the future.</p></div><p>The DMABUF framework provides a generic method for sharing buffers
3between multiple devices. Device drivers that support DMABUF can export a DMA
4buffer to userspace as a file descriptor (known as the exporter role), import a
5DMA buffer from userspace using a file descriptor previously exported for a
6different or the same device (known as the importer role), or both. This
7section describes the DMABUF importer role API in V4L2.</p><p>Refer to <a class="link" href="vidioc-expbuf.html" title="ioctl VIDIOC_EXPBUF">DMABUF exporting</a> for
8details about exporting V4L2 buffers as DMABUF file descriptors.</p><p>Input and output devices support the streaming I/O method when the
9<code class="constant">V4L2_CAP_STREAMING</code> flag in the
10<em class="structfield"><code>capabilities</code></em> field of struct&#160;<a class="link" href="vidioc-querycap.html#v4l2-capability" title="Table&#160;A.93.&#160;struct v4l2_capability">v4l2_capability</a> returned by
11the <a class="link" href="vidioc-querycap.html" title="ioctl VIDIOC_QUERYCAP"><code class="constant">VIDIOC_QUERYCAP</code></a> ioctl is set. Whether importing DMA buffers through
12DMABUF file descriptors is supported is determined by calling the
13<a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a> ioctl with the memory type set to
14<code class="constant">V4L2_MEMORY_DMABUF</code>.</p><p>This I/O method is dedicated to sharing DMA buffers between different
15devices, which may be V4L devices or other video-related devices (e.g. DRM).
16Buffers (planes) are allocated by a driver on behalf of an application. Next,
17these buffers are exported to the application as file descriptors using an API
18which is specific for an allocator driver.  Only such file descriptor are
19exchanged. The descriptors and meta-information are passed in struct&#160;<a class="link" href="buffer.html#v4l2-buffer" title="Table&#160;3.1.&#160;struct v4l2_buffer">v4l2_buffer</a> (or
20in struct&#160;<a class="link" href="buffer.html#v4l2-plane" title="Table&#160;3.2.&#160;struct v4l2_plane">v4l2_plane</a> in the multi-planar API case).  The driver must be switched
21into DMABUF I/O mode by calling the <a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a> with the desired buffer
22type.</p><div class="example"><a name="idp1104658132"></a><p class="title"><b>Example&#160;3.4.&#160;Initiating streaming I/O with DMABUF file descriptors</b></p><div class="example-contents"><pre class="programlisting">
23struct&#160;<a class="link" href="vidioc-reqbufs.html#v4l2-requestbuffers" title="Table&#160;A.100.&#160;struct v4l2_requestbuffers">v4l2_requestbuffers</a> reqbuf;
24
25memset(&amp;reqbuf, 0, sizeof (reqbuf));
26reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
27reqbuf.memory = V4L2_MEMORY_DMABUF;
28reqbuf.count = 1;
29
30if (ioctl(fd, <a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a>, &amp;reqbuf) == -1) {
31	if (errno == EINVAL)
32		printf("Video capturing or DMABUF streaming is not supported\n");
33	else
34		perror("VIDIOC_REQBUFS");
35
36	exit(EXIT_FAILURE);
37}
38      </pre></div></div><br class="example-break"><p>The buffer (plane) file descriptor is passed on the fly with the
39<a class="link" href="vidioc-qbuf.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_QBUF</code></a> ioctl. In case of multiplanar buffers, every plane can be
40associated with a different DMABUF descriptor. Although buffers are commonly
41cycled, applications can pass a different DMABUF descriptor at each
42<code class="constant">VIDIOC_QBUF</code> call.</p><div class="example"><a name="idp1104661564"></a><p class="title"><b>Example&#160;3.5.&#160;Queueing DMABUF using single plane API</b></p><div class="example-contents"><pre class="programlisting">
43int buffer_queue(int v4lfd, int index, int dmafd)
44{
45	struct&#160;<a class="link" href="buffer.html#v4l2-buffer" title="Table&#160;3.1.&#160;struct v4l2_buffer">v4l2_buffer</a> buf;
46
47	memset(&amp;buf, 0, sizeof buf);
48	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
49	buf.memory = V4L2_MEMORY_DMABUF;
50	buf.index = index;
51	buf.m.fd = dmafd;
52
53	if (ioctl(v4lfd, <a class="link" href="vidioc-qbuf.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_QBUF</code></a>, &amp;buf) == -1) {
54		perror("VIDIOC_QBUF");
55		return -1;
56	}
57
58	return 0;
59}
60      </pre></div></div><br class="example-break"><div class="example"><a name="idp1104663716"></a><p class="title"><b>Example&#160;3.6.&#160;Queueing DMABUF using multi plane API</b></p><div class="example-contents"><pre class="programlisting">
61int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
62{
63	struct&#160;<a class="link" href="buffer.html#v4l2-buffer" title="Table&#160;3.1.&#160;struct v4l2_buffer">v4l2_buffer</a> buf;
64	struct&#160;<a class="link" href="buffer.html#v4l2-plane" title="Table&#160;3.2.&#160;struct v4l2_plane">v4l2_plane</a> planes[VIDEO_MAX_PLANES];
65	int i;
66
67	memset(&amp;buf, 0, sizeof buf);
68	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
69	buf.memory = V4L2_MEMORY_DMABUF;
70	buf.index = index;
71	buf.m.planes = planes;
72	buf.length = n_planes;
73
74	memset(&amp;planes, 0, sizeof planes);
75
76	for (i = 0; i &lt; n_planes; ++i)
77		buf.m.planes[i].m.fd = dmafd[i];
78
79	if (ioctl(v4lfd, <a class="link" href="vidioc-qbuf.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_QBUF</code></a>, &amp;buf) == -1) {
80		perror("VIDIOC_QBUF");
81		return -1;
82	}
83
84	return 0;
85}
86      </pre></div></div><br class="example-break"><p>Captured or displayed buffers are dequeued with the
87<a class="link" href="vidioc-qbuf.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_DQBUF</code></a> ioctl. The driver can unlock the buffer at any
88time between the completion of the DMA and this ioctl. The memory is
89also unlocked when <a class="link" href="vidioc-streamon.html" title="ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF"><code class="constant">VIDIOC_STREAMOFF</code></a> is called, <a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a>, or
90when the device is closed.</p><p>For capturing applications it is customary to enqueue a
91number of empty buffers, to start capturing and enter the read loop.
92Here the application waits until a filled buffer can be dequeued, and
93re-enqueues the buffer when the data is no longer needed. Output
94applications fill and enqueue buffers, when enough buffers are stacked
95up output is started. In the write loop, when the application
96runs out of free buffers it must wait until an empty buffer can be
97dequeued and reused. Two methods exist to suspend execution of the
98application until one or more buffers can be dequeued. By default
99<code class="constant">VIDIOC_DQBUF</code> blocks when no buffer is in the
100outgoing queue. When the <code class="constant">O_NONBLOCK</code> flag was
101given to the <a class="link" href="func-open.html" title="V4L2 open()"><code class="function">open()</code></a> function, <code class="constant">VIDIOC_DQBUF</code>
102returns immediately with an <span class="errorcode">EAGAIN</span> error code when no buffer is available. The
103<a class="link" href="func-select.html" title="V4L2 select()"><code class="function">select()</code></a> and <a class="link" href="func-poll.html" title="V4L2 poll()"><code class="function">poll()</code></a> functions are always available.</p><p>To start and stop capturing or displaying applications call the
104<a class="link" href="vidioc-streamon.html" title="ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF"><code class="constant">VIDIOC_STREAMON</code></a> and <a class="link" href="vidioc-streamon.html" title="ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF"><code class="constant">VIDIOC_STREAMOFF</code></a> ioctls. Note that
105<code class="constant">VIDIOC_STREAMOFF</code> removes all buffers from both queues and
106unlocks all buffers as a side effect. Since there is no notion of doing
107anything "now" on a multitasking system, if an application needs to synchronize
108with another event it should examine the struct&#160;<a class="link" href="buffer.html#v4l2-buffer" title="Table&#160;3.1.&#160;struct v4l2_buffer">v4l2_buffer</a>
109<em class="structfield"><code>timestamp</code></em> of captured or outputted buffers.</p><p>Drivers implementing DMABUF importing I/O must support the
110<code class="constant">VIDIOC_REQBUFS</code>, <code class="constant">VIDIOC_QBUF</code>,
111<code class="constant">VIDIOC_DQBUF</code>, <code class="constant">VIDIOC_STREAMON</code> and
112<code class="constant">VIDIOC_STREAMOFF</code> ioctls, and the
113<code class="function">select()</code> and <code class="function">poll()</code> functions.</p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="userp.html">Prev</a>&#160;</td><td width="20%" align="center"><a accesskey="u" href="io.html">Up</a></td><td width="40%" align="right">&#160;<a accesskey="n" href="async.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Streaming I/O (User Pointers)&#160;</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">&#160;Asynchronous I/O</td></tr></table></div></body></html>
114