1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Streaming I/O (User Pointers)</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="mmap.html" title="Streaming I/O (Memory Mapping)"><link rel="next" href="dmabuf.html" title="Streaming I/O (DMA buffer importing)"></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 (User Pointers)</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="mmap.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Input/Output</th><td width="20%" align="right"> <a accesskey="n" href="dmabuf.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="userp"></a>Streaming I/O (User Pointers)</h2></div></div></div><p>Input and output devices support this I/O method when the 2<code class="constant">V4L2_CAP_STREAMING</code> flag in the 3<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> 4returned by the <a class="link" href="vidioc-querycap.html" title="ioctl VIDIOC_QUERYCAP"><code class="constant">VIDIOC_QUERYCAP</code></a> ioctl is set. If the particular user 5pointer method (not only memory mapping) is supported must be 6determined by calling the <a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a> ioctl.</p><p>This I/O method combines advantages of the read/write and 7memory mapping methods. Buffers (planes) are allocated by the application 8itself, and can reside for example in virtual or shared memory. Only 9pointers to data are exchanged, these pointers and meta-information 10are passed in struct <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> (or in 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). 11The driver must be switched into user pointer I/O mode by calling the 12<a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a> with the desired buffer type. No buffers (planes) are allocated 13beforehand, consequently they are not indexed and cannot be queried like mapped 14buffers with the <code class="constant">VIDIOC_QUERYBUF</code> ioctl.</p><div class="example"><a name="idp1104634756"></a><p class="title"><b>Example 3.3. Initiating streaming I/O with user pointers</b></p><div class="example-contents"><pre class="programlisting"> 15struct <a class="link" href="vidioc-reqbufs.html#v4l2-requestbuffers" title="Table A.100. struct v4l2_requestbuffers">v4l2_requestbuffers</a> reqbuf; 16 17memset (&reqbuf, 0, sizeof (reqbuf)); 18reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 19reqbuf.memory = V4L2_MEMORY_USERPTR; 20 21if (ioctl (fd, <a class="link" href="vidioc-reqbufs.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a>, &reqbuf) == -1) { 22 if (errno == EINVAL) 23 printf ("Video capturing or user pointer streaming is not supported\n"); 24 else 25 perror ("VIDIOC_REQBUFS"); 26 27 exit (EXIT_FAILURE); 28} 29 </pre></div></div><br class="example-break"><p>Buffer (plane) addresses and sizes are passed on the fly with the 30<a class="link" href="vidioc-qbuf.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_QBUF</code></a> ioctl. Although buffers are commonly cycled, 31applications can pass different addresses and sizes at each 32<code class="constant">VIDIOC_QBUF</code> call. If required by the hardware the 33driver swaps memory pages within physical memory to create a 34continuous area of memory. This happens transparently to the 35application in the virtual memory subsystem of the kernel. When buffer 36pages have been swapped out to disk they are brought back and finally 37locked in physical memory for DMA.<a href="#ftn.idp1104638268" class="footnote" name="idp1104638268"><sup class="footnote">[13]</sup></a></p><p>Filled or displayed buffers are dequeued with the 38<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 memory pages at any 39time between the completion of the DMA and this ioctl. The memory is 40also 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 41when the device is closed. Applications must take care not to free 42buffers without dequeuing. For once, the buffers remain locked until 43further, wasting physical memory. Second the driver will not be 44notified when the memory is returned to the application's free list 45and subsequently reused for other purposes, possibly completing the 46requested DMA and overwriting valuable data.</p><p>For capturing applications it is customary to enqueue a 47number of empty buffers, to start capturing and enter the read loop. 48Here the application waits until a filled buffer can be dequeued, and 49re-enqueues the buffer when the data is no longer needed. Output 50applications fill and enqueue buffers, when enough buffers are stacked 51up output is started. In the write loop, when the application 52runs out of free buffers it must wait until an empty buffer can be 53dequeued and reused. Two methods exist to suspend execution of the 54application until one or more buffers can be dequeued. By default 55<code class="constant">VIDIOC_DQBUF</code> blocks when no buffer is in the 56outgoing queue. When the <code class="constant">O_NONBLOCK</code> flag was 57given 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> 58returns immediately with an <span class="errorcode">EAGAIN</span> error code when no buffer is available. The 59<a class="link" href="func-select.html" title="V4L2 select()"><code class="function">select()</code></a> or <a class="link" href="func-poll.html" title="V4L2 poll()"><code class="function">poll()</code></a> function are always available.</p><p>To start and stop capturing or output applications call the 60<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> ioctl. Note 61<code class="constant">VIDIOC_STREAMOFF</code> removes all buffers from both 62queues and unlocks all buffers as a side effect. Since there is no 63notion of doing anything "now" on a multitasking system, if an 64application needs to synchronize with another event it should examine 65the struct <a class="link" href="buffer.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> <em class="structfield"><code>timestamp</code></em> of captured 66or outputted buffers.</p><p>Drivers implementing user pointer I/O must 67support the <code class="constant">VIDIOC_REQBUFS</code>, 68<code class="constant">VIDIOC_QBUF</code>, <code class="constant">VIDIOC_DQBUF</code>, 69<code class="constant">VIDIOC_STREAMON</code> and 70<code class="constant">VIDIOC_STREAMOFF</code> ioctl, the 71<code class="function">select()</code> and <code class="function">poll()</code> function.<a href="#ftn.idp1104649148" class="footnote" name="idp1104649148"><sup class="footnote">[14]</sup></a></p><div class="footnotes"><br><hr style="width:100; text-align:left;margin-left: 0"><div id="ftn.idp1104638268" class="footnote"><p><a href="#idp1104638268" class="para"><sup class="para">[13] </sup></a>We expect that frequently used buffers are typically not 72swapped out. Anyway, the process of swapping, locking or generating 73scatter-gather lists may be time consuming. The delay can be masked by 74the depth of the incoming buffer queue, and perhaps by maintaining 75caches assuming a buffer will be soon enqueued again. On the other 76hand, to optimize memory usage drivers can limit the number of buffers 77locked in advance and recycle the most recently used buffers first. Of 78course, the pages of empty buffers in the incoming queue need not be 79saved to disk. Output buffers must be saved on the incoming and 80outgoing queue because an application may share them with other 81processes.</p></div><div id="ftn.idp1104649148" class="footnote"><p><a href="#idp1104649148" class="para"><sup class="para">[14] </sup></a>At the driver level <code class="function">select()</code> and 82<code class="function">poll()</code> are the same, and 83<code class="function">select()</code> is too important to be optional. The 84rest should be evident.</p></div></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="mmap.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="dmabuf.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Streaming I/O (Memory Mapping) </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Streaming I/O (DMA buffer importing)</td></tr></table></div></body></html> 85