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 3. 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> </td><th width="60%" align="center">Chapter 3. Input/Output</th><td width="20%" align="right"> <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 <a class="link" href="vidioc-querycap.html#v4l2-capability" title="Table A.93. 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 <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> (or 20in struct <a class="link" href="buffer.html#v4l2-plane" title="Table 3.2. 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 3.4. Initiating streaming I/O with DMABUF file descriptors</b></p><div class="example-contents"><pre class="programlisting"> 23struct <a class="link" href="vidioc-reqbufs.html#v4l2-requestbuffers" title="Table A.100. struct v4l2_requestbuffers">v4l2_requestbuffers</a> reqbuf; 24 25memset(&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>, &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 3.5. 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 <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> buf; 46 47 memset(&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>, &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 3.6. 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 <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> buf; 64 struct <a class="link" href="buffer.html#v4l2-plane" title="Table 3.2. struct v4l2_plane">v4l2_plane</a> planes[VIDEO_MAX_PLANES]; 65 int i; 66 67 memset(&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(&planes, 0, sizeof planes); 75 76 for (i = 0; i < 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>, &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 <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. 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> </td><td width="20%" align="center"><a accesskey="u" href="io.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="async.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Streaming I/O (User Pointers) </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Asynchronous I/O</td></tr></table></div></body></html> 114