<?xml version="1.0" encoding="ANSI_X3.4-1968" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><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.75.2" /><link rel="home" href="index.html" title="LINUX MEDIA INFRASTRUCTURE API" /><link rel="up" href="ch03.html" title="Chapter 3. Input/Output" /><link rel="prev" href="ch03s02.html" title="Streaming I/O (Memory Mapping)" /><link rel="next" href="ch03s04.html" title="Asynchronous I/O" /></head><body><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="ch03s02.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Input/Output</th><td width="20%" align="right"> <a accesskey="n" href="ch03s04.html">Next</a></td></tr></table><hr /></div><div class="section" title="Streaming I/O (User Pointers)"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="userp"></a>Streaming I/O (User Pointers)</h2></div></div></div><p>Input and output devices support this I/O method when the <code class="constant">V4L2_CAP_STREAMING</code> flag in the <em class="structfield"><code>capabilities</code></em> field of struct <a class="link" href="re56.html#v4l2-capability" title="Table A.66. struct v4l2_capability">v4l2_capability</a> returned by the <a class="link" href="re56.html" title="ioctl VIDIOC_QUERYCAP"><code class="constant">VIDIOC_QUERYCAP</code></a> ioctl is set. If the particular user pointer method (not only memory mapping) is supported must be determined by calling the <a class="link" href="re59.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 memory mapping methods. Buffers are allocated by the application itself, and can reside for example in virtual or shared memory. Only pointers to data are exchanged, these pointers and meta-information are passed in struct <a class="link" href="ch03s05.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a>. The driver must be switched into user pointer I/O mode by calling the <a class="link" href="re59.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a> with the desired buffer type. No buffers are allocated beforehands, consequently they are not indexed and cannot be queried like mapped buffers with the <code class="constant">VIDIOC_QUERYBUF</code> ioctl.</p><div class="example"><a id="id2645667"></a><p class="title"><b>Example 3.2. Initiating streaming I/O with user pointers</b></p><div class="example-contents"><pre class="programlisting"> struct <a class="link" href="re59.html#v4l2-requestbuffers" title="Table A.72. struct v4l2_requestbuffers">v4l2_requestbuffers</a> reqbuf; memset (&reqbuf, 0, sizeof (reqbuf)); reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_USERPTR; if (ioctl (fd, <a class="link" href="re59.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a>, &reqbuf) == -1) { if (errno == EINVAL) printf ("Video capturing or user pointer streaming is not supported\n"); else perror ("VIDIOC_REQBUFS"); exit (EXIT_FAILURE); } </pre></div></div><br class="example-break" /><p>Buffer addresses and sizes are passed on the fly with the <a class="link" href="re54.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_QBUF</code></a> ioctl. Although buffers are commonly cycled, applications can pass different addresses and sizes at each <code class="constant">VIDIOC_QBUF</code> call. If required by the hardware the driver swaps memory pages within physical memory to create a continuous area of memory. This happens transparently to the application in the virtual memory subsystem of the kernel. When buffer pages have been swapped out to disk they are brought back and finally locked in physical memory for DMA.<sup>[<a id="id2645728" href="#ftn.id2645728" class="footnote">17</a>]</sup></p><p>Filled or displayed buffers are dequeued with the <a class="link" href="re54.html" title="ioctl VIDIOC_QBUF, VIDIOC_DQBUF"><code class="constant">VIDIOC_DQBUF</code></a> ioctl. The driver can unlock the memory pages at any time between the completion of the DMA and this ioctl. The memory is also unlocked when <a class="link" href="re61.html" title="ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF"><code class="constant">VIDIOC_STREAMOFF</code></a> is called, <a class="link" href="re59.html" title="ioctl VIDIOC_REQBUFS"><code class="constant">VIDIOC_REQBUFS</code></a>, or when the device is closed. Applications must take care not to free buffers without dequeuing. For once, the buffers remain locked until further, wasting physical memory. Second the driver will not be notified when the memory is returned to the application's free list and subsequently reused for other purposes, possibly completing the requested DMA and overwriting valuable data.</p><p>For capturing applications it is customary to enqueue a number of empty buffers, to start capturing and enter the read loop. Here the application waits until a filled buffer can be dequeued, and re-enqueues the buffer when the data is no longer needed. Output applications fill and enqueue buffers, when enough buffers are stacked up output is started. In the write loop, when the application runs out of free buffers it must wait until an empty buffer can be dequeued and reused. Two methods exist to suspend execution of the application until one or more buffers can be dequeued. By default <code class="constant">VIDIOC_DQBUF</code> blocks when no buffer is in the outgoing queue. When the <code class="constant">O_NONBLOCK</code> flag was given to the <a class="link" href="re64.html" title="V4L2 open()"><code class="function">open()</code></a> function, <code class="constant">VIDIOC_DQBUF</code> returns immediately with an <span class="errorcode">EAGAIN</span> error code when no buffer is available. The <a class="link" href="re67.html" title="V4L2 select()"><code class="function">select()</code></a> or <a class="link" href="re65.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 <a class="link" href="re61.html" title="ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF"><code class="constant">VIDIOC_STREAMON</code></a> and <a class="link" href="re61.html" title="ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF"><code class="constant">VIDIOC_STREAMOFF</code></a> ioctl. Note <code class="constant">VIDIOC_STREAMOFF</code> removes all buffers from both queues and unlocks all buffers as a side effect. Since there is no notion of doing anything "now" on a multitasking system, if an application needs to synchronize with another event it should examine the struct <a class="link" href="ch03s05.html#v4l2-buffer" title="Table 3.1. struct v4l2_buffer">v4l2_buffer</a> <em class="structfield"><code>timestamp</code></em> of captured buffers, or set the field before enqueuing buffers for output.</p><p>Drivers implementing user pointer I/O must support the <code class="constant">VIDIOC_REQBUFS</code>, <code class="constant">VIDIOC_QBUF</code>, <code class="constant">VIDIOC_DQBUF</code>, <code class="constant">VIDIOC_STREAMON</code> and <code class="constant">VIDIOC_STREAMOFF</code> ioctl, the <code class="function">select()</code> and <code class="function">poll()</code> function.<sup>[<a id="id2645923" href="#ftn.id2645923" class="footnote">18</a>]</sup></p><div class="footnotes"><br /><hr width="100" align="left" /><div class="footnote"><p><sup>[<a id="ftn.id2645728" href="#id2645728" class="para">17</a>] </sup>We expect that frequently used buffers are typically not swapped out. Anyway, the process of swapping, locking or generating scatter-gather lists may be time consuming. The delay can be masked by the depth of the incoming buffer queue, and perhaps by maintaining caches assuming a buffer will be soon enqueued again. On the other hand, to optimize memory usage drivers can limit the number of buffers locked in advance and recycle the most recently used buffers first. Of course, the pages of empty buffers in the incoming queue need not be saved to disk. Output buffers must be saved on the incoming and outgoing queue because an application may share them with other processes.</p></div><div class="footnote"><p><sup>[<a id="ftn.id2645923" href="#id2645923" class="para">18</a>] </sup>At the driver level <code class="function">select()</code> and <code class="function">poll()</code> are the same, and <code class="function">select()</code> is too important to be optional. The rest 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="ch03s02.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="ch03.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="ch03s04.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"> Asynchronous I/O</td></tr></table></div></body></html>