Changes between Initial Version and Version 1 of linux/v4l2


Ignore:
Timestamp:
10/22/2017 05:28:45 AM (7 years ago)
Author:
trac
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • linux/v4l2

    v1 v1  
     1{{{#!html
     2          <div id="wikipage" class="trac-content"><p>
     3</p><div class="wiki-toc">
     4<ol>
     5  <li>
     6    <a href="#LinuxVideo4Linux2APIv4l2">Linux Video4Linux2 API (v4l2)</a>
     7    <ol>
     8      <li>
     9        <a href="#v4l2-ctlutility">v4l2-ctl utility</a>
     10        <ol>
     11          <li>
     12            <a href="#videostandards">video standards</a>
     13          </li>
     14          <li>
     15            <a href="#videoinputs">video inputs</a>
     16          </li>
     17          <li>
     18            <a href="#pixelformatsframesizesandframerates">pixel formats, framesizes, and framerates</a>
     19          </li>
     20          <li>
     21            <a href="#capturingvideoframes">capturing video frames</a>
     22          </li>
     23        </ol>
     24      </li>
     25      <li>
     26        <a href="#v4l2applicationcode">v4l2 application code</a>
     27      </li>
     28      <li>
     29        <a href="#IMX6Ventanamxc_v4l2_capturedriver">IMX6 Ventana mxc_v4l2_capture driver</a>
     30      </li>
     31    </ol>
     32  </li>
     33</ol>
     34</div><p>
     35</p>
     36<h1 id="LinuxVideo4Linux2APIv4l2">Linux Video4Linux2 API (v4l2)</h1>
     37<p>
     38The Linux Video4Linux2 (v4l2) API is the kernel's video input and output interface.
     39</p>
     40<p>
     41<span class="wikianchor" id="v4l2-ctl"></span>
     42</p>
     43<h2 id="v4l2-ctlutility">v4l2-ctl utility</h2>
     44<p>
     45The <tt>v4l2-ctl</tt> userspace application can be used to query or configure a v4l2 device.  For complete information, including output resolutions etc , use the following:
     46</p>
     47<div class="code"><pre>root@ventana:~# v4l2-ctl --device /dev/video3 --all <span class="c"># query all details about /dev/video3
     48</span></pre></div><p>
     49See Also:
     50</p>
     51<ul><li><a class="wiki" href="/wiki/Yocto/gstreamer">GStreamer</a>
     52</li></ul><p>
     53<span class="wikianchor" id="standard"></span>
     54</p>
     55<h3 id="videostandards">video standards</h3>
     56<p>
     57Analog video v4l2 capture devices will support one or more of the various analog video standards used throughout the world. For example the ADV7180 supports NTSC, PAL, and SECAM standards.
     58</p>
     59<p>
     60You can use the Video4Linux API to determine if an input is detected and what mode by using the <tt>v4l2-ctl --get-standard</tt> command which reports one of the following:
     61</p>
     62<ul><li>No supported input detected - Video Standard = 0x00ffffff
     63</li><li>NTSC - Video Standard = 0x000000ff
     64</li><li>PAL - Video Standard = 0x000000ff
     65</li></ul><p>
     66Example:
     67</p>
     68<ul><li>Show Analog Video status on GW51xx/GW52xx/GW53xx (/dev/video0):
     69<div class="code"><pre>v4l2-ctl --device /dev/video0 --get-standard
     70</pre></div></li><li>Show Analog Video status on GW54xx (/dev/video1)
     71<div class="code"><pre>v4l2-ctl --device /devivideo0 --get-standard
     72</pre></div></li></ul><p>
     73<span class="wikianchor" id="input"></span>
     74</p>
     75<h3 id="videoinputs">video inputs</h3>
     76<p>
     77Some capture devices have multiple video inputs. The <tt>v4l2-ctl</tt> application can be used to get or set the current input.
     78</p>
     79<p>
     80Examples:
     81</p>
     82<ul><li>show current inputs that <tt>/dev/video3</tt> supports:
     83<div class="code"><pre>v4l2-ctl --device /dev/video3 --get-input
     84</pre></div></li><li>select input1:
     85<div class="code"><pre>v4l2-ctl --device /dev/video3 --set-input<span class="o">=</span>1
     86</pre></div></li></ul><p>
     87<span class="wikianchor" id="format"></span>
     88</p>
     89<h3 id="pixelformatsframesizesandframerates">pixel formats, framesizes, and framerates</h3>
     90<p>
     91You can use <tt>v4l2-ctl</tt> to show what pixel formats a video device supports and select a desired format. Note that v4l2 devices support one or more pixel formats, and various resolutions and framerates for each format. You must ask what resolutions are supported for a particular format, and what framerates are supported for a particular resolution/format.
     92</p>
     93<p>
     94Examples:
     95</p>
     96<ul><li>show formats that <tt>/dev/video3</tt> supports:
     97<div class="code"><pre>v4l2-ctl --device /dev/video3 --list-formats-ext
     98</pre></div></li><li>show what resolutions <tt>/dev/video3</tt> supports for the UYVY pixel format:
     99<div class="code"><pre>v4l2-ctl --device /dev/video3 --list-framesizes<span class="o">=</span>UYVY
     100</pre></div></li><li>show what framerates <tt>/dev/video3</tt> supports for UYVY at 640x480:
     101<div class="code"><pre>v4l2-ctl --device /dev/video3 --list-frameintervals<span class="o">=</span><span class="nv">width</span><span class="o">=</span>640,height<span class="o">=</span>480,pixelformat<span class="o">=</span>UYVY
     102</pre></div></li><li>set format for <tt>/dev/video0</tt> to 1280x720 UYVY:
     103<div class="code"><pre>v4l2-ctl --device /dev/video0 --set-fmt-video<span class="o">=</span><span class="nv">width</span><span class="o">=</span>1280,height<span class="o">=</span>720,pixelformat<span class="o">=</span>UYVY
     104</pre></div></li></ul><p>
     105It is not uncommon for a v4l2 driver to not properly support the enumeration of various formats, resolutions, and framerates. If you find that a device is not returning anything useful for <tt>--list-formats</tt> <tt>--list-formats-ext</tt> <tt>--list-framesizes</tt> <tt>--list-framerates</tt> then you can try <tt>--all</tt> to get the default configuration of the device.
     106</p>
     107<p>
     108Examples:
     109</p>
     110<ul><li>the TDA1997x HDMI receiver on a GW54xx
     111<div class="code"><pre>root@ventana:~# v4l2-ctl --device /dev/video0 --all
     112Driver Info <span class="o">(</span>not using libv4l2<span class="o">)</span>:
     113        Driver name   : mxc_v4l2
     114        Card <span class="nb">type</span>     :
     115        Bus info      :
     116        Driver version: 0.1.11
     117        Capabilities  : 0x05000005
     118                Video Capture
     119                Video Overlay
     120                Read/Write
     121                Streaming
     122Video input : 0 <span class="o">(</span>CSI IC MEM: ok<span class="o">)</span>
     123Video output: 0 <span class="o">(</span>DISP3 BG<span class="o">)</span>
     124Video <span class="nv">Standard</span> <span class="o">=</span> 0x00000000
     125Format Video Capture:
     126        Width/Height  : 288/352
     127        Pixel Format  : <span class="s1">'UYVY'</span>
     128        Field         : Any
     129        Bytes per Line: 432
     130        Size Image    : 152064
     131        Colorspace    : Unknown <span class="o">(</span>00000000<span class="o">)</span>
     132Format Video Overlay:
     133        Left/Top    : 0/0
     134        Width/Height: 160/160
     135        Field       : Any
     136        Chroma Key  : 0x00000000
     137        Global Alpha: 0x00
     138        Clip Count  : 0
     139        Clip Bitmap : No
     140Framebuffer Format:
     141        Capability    : Extern Overlay
     142        Flags         : Overlay Matches Capture/Output Size
     143        Width         : 0
     144        Height        : 0
     145        Pixel Format  : <span class="s1">''</span>
     146Crop Capability Video Capture:
     147        Bounds      : Left 0, Top 0, Width 1920, Height 1080
     148        Default     : Left 0, Top 0, Width 1920, Height 1080
     149        Pixel Aspect: 0/0
     150Crop: Left 0, Top 0, Width 1920, Height 1080
     151Streaming Parameters Video Capture:
     152        Frames per second: 60.000 <span class="o">(</span>60/1<span class="o">)</span>
     153        Read buffers     : 0
     154Streaming Parameters Video Output:
     155        Frames per second: invalid <span class="o">(</span>0/0<span class="o">)</span>
     156        Write buffers    : 0
     157
     158</pre></div><ul><li>Note that the width/height does not reflect the resolution of the current video input source. In the above case a 1080p@60Hz input is attached. You can determine the source resolution via the crop parameters.
     159</li></ul></li><li>the ADV7180 Analog Video Decoder on a GW5400:
     160<div class="code"><pre>root@ventana:~# v4l2-ctl --device /dev/video1 --all
     161Driver Info <span class="o">(</span>not using libv4l2<span class="o">)</span>:<span class="o">[</span> 1863.994275<span class="o">]</span> ERROR: unrecognized std! ffffff <span class="o">(</span><span class="nv">PAL</span><span class="o">=</span>ff, <span class="nv">NTSC</span><span class="o">=</span>b000
     162
     163        Driver name   : mxc_v4l2
     164        Card <span class="nb">type</span>     :
     165        Bus info      :
     166        Driver version: 0.1.11
     167        Capabilities  : 0x05000005
     168                Video Capture
     169                Video Overlay
     170                Read/Write
     171                Streaming
     172Video input : 0 <span class="o">(</span>CSI IC MEM: ok<span class="o">)</span>
     173Video output: 0 <span class="o">(</span>DISP3 BG<span class="o">)</span>
     174Video <span class="nv">Standard</span> <span class="o">=</span> 0x00ffffff
     175        PAL-B/B1/G/H/I/D/D1/K/M/N/Nc/60
     176        NTSC-M/M-JP/443/M-KR
     177        SECAM-B/D/G/H/K/K1/L/Lc
     178Format Video Capture:
     179        Width/Height  : 288/352
     180        Pixel Format  : <span class="s1">'YU12'</span>
     181        Field         : Any
     182        Bytes per Line: 432
     183        Size Image    : 152064
     184        Colorspace    : Unknown <span class="o">(</span>00000000<span class="o">)</span>
     185Format Video Overlay:
     186        Left/Top    : 0/0
     187        Width/Height: 160/160
     188        Field       : Any
     189        Chroma Key  : 0x00000000
     190        Global Alpha: 0x00
     191        Clip Count  : 0
     192        Clip Bitmap : No
     193Framebuffer Format:
     194        Capability    : Extern Overlay
     195        Flags         : Overlay Matches Capture/Output Size
     196        Width         : 0
     197        Height        : 0
     198        Pixel Format  : <span class="s1">''</span>
     199Crop Capability Video Capture:
     200        Bounds      : Left 0, Top 0, Width 720, Height 625
     201        Default     : Left 0, Top 0, Width 720, Height 625
     202        Pixel Aspect: 0/0
     203Crop: Left 0, Top 0, Width 720, Height 576
     204Streaming Parameters Video Capture:
     205        Frames per second: 30.000 <span class="o">(</span>30/1<span class="o">)</span>
     206        Read buffers     : 0
     207Streaming Parameters Video Output:
     208        Frames per second: invalid <span class="o">(</span>0/0<span class="o">)</span>
     209        Write buffers    : 0
     210</pre></div></li></ul><p>
     211<span class="wikianchor" id="capture"></span>
     212</p>
     213<h3 id="capturingvideoframes">capturing video frames</h3>
     214<p>
     215You can use <tt>v4l2-ctl</tt> to capture frames as well.
     216</p>
     217<p>
     218Examples:
     219</p>
     220<ul><li>capture a single raw frame using mmap method:
     221<div class="code"><pre>v4l2-ctl --device /dev/video0 --stream-mmap --stream-to<span class="o">=</span>frame.raw --stream-count<span class="o">=</span>1
     222</pre></div></li></ul><p>
     223Note that the <tt>convert</tt> tool from the <a class="ext-link" href="http://www.imagemagick.org/"><span class="icon">​</span>ImageMagick</a> package is useful for image format conversions as long as you know the specific details of the raw image.
     224</p>
     225<p>
     226Examples:
     227</p>
     228<ul><li>convert a raw 640x480 16bit UYVY to png:
     229<div class="code"><pre>convert -size 640x480 -depth 16 uyvy:frame.raw frame.png
     230</pre></div></li></ul><p>
     231For an example v4l2 application for capturing frames see <a class="ext-link" href="https://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html"><span class="icon">​</span>here</a>
     232</p>
     233<p>
     234For capturing video we recommend using more full-featured applications such as <a class="wiki" href="/wiki/Yocto/gstreamer">GStreamer</a>
     235</p>
     236<p>
     237<span class="wikianchor" id="code"></span>
     238</p>
     239<h2 id="v4l2applicationcode">v4l2 application code</h2>
     240<p>
     241If you are coding an application that uses the v4l2 API the best examples are the v4l2-util application. You can find its source at <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/"><span class="icon">​</span>https://git.linuxtv.org/v4l-utils.git/tree/</a>
     242</p>
     243<p>
     244The API documentation can be found at:
     245</p>
     246<ul><li><a class="ext-link" href="http://www.linuxtv.org/downloads/v4l-dvb-apis/"><span class="icon">​</span>http://www.linuxtv.org/downloads/v4l-dvb-apis/</a>
     247<ul><li>Note that there are many references online to what is considered the 'legacy' API used prior to the 3.0 kernel. Be sure to use the documentation above for the current version of the v4l2 API.
     248</li></ul></li></ul><p>
     249Examples:
     250</p>
     251<ul><li>get/set/list video standard - <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-stds.cpp"><span class="icon">​</span>v4l2-ctl-stds.cpp</a>
     252</li><li>get/set/list video input - <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-io.cpp"><span class="icon">​</span>v4l2-ctl-io.cpp</a>
     253</li><li>get/set/list video pixel format - <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp"><span class="icon">​</span>v4l2-ctl-vidcap.cpp</a>
     254</li><li>get/set/list video framesizes - <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp"><span class="icon">​</span>v4l2-ctl-vidcap.cpp</a>
     255</li><li>get/set/list video framerates - <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-vidcap.cpp"><span class="icon">​</span>v4l2-ctl-vidcap.cpp</a>
     256</li><li>video capture - <a class="ext-link" href="https://git.linuxtv.org/v4l-utils.git/tree/utils/v4l2-ctl/v4l2-ctl-streaming.cpp"><span class="icon">​</span>v4l2-ctl-streaming.cpp</a>
     257</li></ul><p>
     258As a rule of thumb it is best to configure all aspects of a device within your code to eliminate any dependence on the initial state of a video device and/or requiring configuring a device outside of your application with something like <tt>v4l2-ctl</tt>. For completeness set the following:
     259</p>
     260<ul><li>input (VIDIOC_S_INPUT)
     261</li><li>standard (VIDIOC_S_STD)
     262</li><li>format (VIDIOC_S_FMT) including width, height, pixel format, fields
     263</li><li>framerate (VIDIOC_S_PARM)
     264</li></ul><p>
     265Be aware that the <tt>ioctl</tt> syscall can return a -1 result with errno = EINTR to indicate the syscall was interrupted in which case it should be tried again. Because of this you should consider providing a wrapper for ioctl such as:
     266</p>
     267<div class="code"><pre><span class="k">static</span> <span class="kt">int</span> <span class="nf">xioctl</span><span class="p">(</span><span class="kt">int</span> fh<span class="p">,</span> <span class="kt">int</span> request<span class="p">,</span> <span class="kt">void</span> <span class="o">*</span>arg<span class="p">)</span>
     268<span class="p">{</span>
     269        <span class="kt">int</span> r<span class="p">;</span>
     270
     271        <span class="k">do</span> <span class="p">{</span>
     272                r <span class="o">=</span> ioctl<span class="p">(</span>fh<span class="p">,</span> request<span class="p">,</span> arg<span class="p">);</span>
     273        <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> r <span class="o">&amp;&amp;</span> EINTR <span class="o">==</span> errno<span class="p">);</span>
     274
     275        <span class="k">return</span> r<span class="p">;</span>
     276<span class="p">}</span>
     277</pre></div><p>
     278<span class="wikianchor" id="ventana"></span>
     279</p>
     280<h2 id="IMX6Ventanamxc_v4l2_capturedriver">IMX6 Ventana mxc_v4l2_capture driver</h2>
     281<p>
     282The Ventana product family based on the Freescale IMX6 System On Chip (SoC) has a Freescale provided capture driver (mxc_v4l2_capture) that is present in the Gateworks downstream vendor kernel used for the Yocto BSP.
     283</p>
     284<p>
     285This capture device driver implements two video inputs which represent different pipelines in the SoC:
     286</p>
     287<ul><li>input0 (default) - CSI -&gt; IC -&gt; MEM: useful if you want to perform image manipulation using the IMX6 hardware blocks
     288</li><li>input1 - CSI -&gt; MEM: raw image capture
     289</li></ul><p>
     290If capturing frames be sure to skip the first frame as the CSI has not fully synchronized on its capture input.
     291</p>
     292<p>
     293To demonstrate a capture of a raw frame you can use the <tt>v4l2_ctl</tt> application:
     294</p>
     295<div class="code"><pre><span class="c"># configure input 1 for CSI -&gt; MEM (raw image capture)
     296</span>v4l2-ctl --device /dev/video0 --set-input<span class="o">=</span>1
     297<span class="c"># configure format
     298</span>v4l2-ctl --device /dev/video0 --set-fmt-video<span class="o">=</span><span class="nv">width</span><span class="o">=</span>1920,height<span class="o">=</span>1080,pixelformat<span class="o">=</span>UYVY
     299<span class="c"># capture 2nd frame
     300</span>v4l2-ctl --device /dev/video0 --stream-mmap --stream-skip<span class="o">=</span>1 --stream-to<span class="o">=</span>frame.raw --stream-count<span class="o">=</span>1
     301<span class="c"># Use ImageMagick to convert it from raw 16-bit UYVY to PNG
     302</span>convert -size 1920x1080 -depth 16 uyvy:frame.raw frame.png
     303</pre></div><p>
     304Notes:
     305</p>
     306<ul><li>The mxc_v4l2_capture driver does not support the enumeration ioctls necessary to query device capabilities (VIDIOC_ENUM_FMT, VIDIOC_ENUM_FRAMESIZES, VIDIOC_ENUM_FRAMEINTERVALS). The following format details show what is supported:
     307<ul><li>HDMI In via tda1997x (GW54xx/GW551x): V4L2_PIX_FMT_UYVY non-interlaced frames (even when using the yuv422bt656 capture mode the bt656 is converted to non-interlaced frames by the IMX IC) with a resolution, framerate and colorspace dictated by the HDMI source.
     308</li><li>CVBS In via adv7180: V4L2_PIX_FMT_UYVY non-interlaced frames (bt656 output is converted to non-interlaced frames by the IMX IC) with a resolution of either 720x480 (NTSC) or 720x576 (PAL) depending on the input source
     309</li></ul></li></ul><p>
     310Code Example:
     311</p>
     312<ul><li>This example code will capture raw frames from the onboard video capture devices on the Ventana boards using the IMX6 CSI. It shows how to save the raw frame, process pixels (by counting the number of red pixels in the image), and convert it to a png via imagemagick
     313<div class="code"><pre><span class="cm">/*
     314 *  V4L2 video capture example
     315 *
     316 *  This program can be used and distributed without restrictions.
     317 *
     318 *      This program is provided with the V4L2 API
     319 * see http://linuxtv.org/docs.php for more information
     320 */</span>
     321<span class="cp">
     322#include &lt;byteswap.h&gt;
     323#include &lt;stdio.h&gt;
     324#include &lt;stdlib.h&gt;
     325#include &lt;stdint.h&gt;
     326#include &lt;string.h&gt;
     327#include &lt;assert.h&gt;
     328#include &lt;fcntl.h&gt;              </span><span class="cm">/* low-level i/o */</span><span class="cp">
     329#include &lt;unistd.h&gt;
     330#include &lt;errno.h&gt;
     331#include &lt;sys/types.h&gt;
     332#include &lt;sys/mman.h&gt;
     333#include &lt;sys/ioctl.h&gt;
     334
     335#include &lt;linux/videodev2.h&gt;
     336
     337#define CLEAR(x) memset(&amp;(x), 0, sizeof(x))
     338</span>
     339<span class="k">struct</span> buffer <span class="p">{</span>
     340        <span class="kt">void</span>   <span class="o">*</span>start<span class="p">;</span>
     341        <span class="kt">size_t</span>  length<span class="p">;</span>
     342<span class="p">};</span>
     343
     344<span class="k">static</span> <span class="kt">void</span> <span class="nf">errno_exit</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span>s<span class="p">)</span>
     345<span class="p">{</span>
     346        fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"%s error %d, %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> s<span class="p">,</span> errno<span class="p">,</span> strerror<span class="p">(</span>errno<span class="p">));</span>
     347        exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     348<span class="p">}</span>
     349
     350<span class="k">static</span> <span class="kt">int</span> <span class="nf">xioctl</span><span class="p">(</span><span class="kt">int</span> fh<span class="p">,</span> <span class="kt">int</span> request<span class="p">,</span> <span class="kt">void</span> <span class="o">*</span>arg<span class="p">)</span>
     351<span class="p">{</span>
     352        <span class="kt">int</span> r<span class="p">;</span>
     353
     354        <span class="k">do</span> <span class="p">{</span>
     355                r <span class="o">=</span> ioctl<span class="p">(</span>fh<span class="p">,</span> request<span class="p">,</span> arg<span class="p">);</span>
     356        <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> r <span class="o">&amp;&amp;</span> EINTR <span class="o">==</span> errno<span class="p">);</span>
     357
     358        <span class="k">return</span> r<span class="p">;</span>
     359<span class="p">}</span>
     360
     361<span class="cm">/* 16bit/pixel interleaved YUV */</span>
     362<span class="k">static</span> <span class="kt">void</span> <span class="nf">process_image</span><span class="p">(</span><span class="k">const</span> <span class="kt">void</span> <span class="o">*</span>_p<span class="p">,</span> <span class="k">struct</span> v4l2_pix_format <span class="o">*</span>fmt<span class="p">)</span>
     363<span class="p">{</span>
     364        <span class="k">const</span> <span class="kt">uint8_t</span> <span class="o">*</span>p <span class="o">=</span> _p<span class="p">;</span>
     365        <span class="kt">int8_t</span> u<span class="p">;</span>
     366        <span class="kt">uint8_t</span> y1<span class="p">;</span>
     367        <span class="kt">int8_t</span> v<span class="p">;</span>
     368        <span class="kt">uint8_t</span> y2<span class="p">;</span>
     369        <span class="kt">int</span> r<span class="p">,</span> g<span class="p">,</span> b<span class="p">,</span> c<span class="p">,</span> d <span class="p">,</span>e<span class="p">;</span>
     370        <span class="kt">int</span> red<span class="p">,</span> i<span class="p">,</span> x<span class="p">,</span> y<span class="p">;</span>
     371        <span class="kt">int</span> size <span class="o">=</span> fmt<span class="o">-&gt;</span>sizeimage<span class="p">;</span>
     372
     373        printf<span class="p">(</span><span class="s">"Processing Frame: %dx%d %c%c%c%c</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     374                fmt<span class="o">-&gt;</span>width<span class="p">,</span> fmt<span class="o">-&gt;</span>height<span class="p">,</span>
     375                <span class="p">(</span>fmt<span class="o">-&gt;</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     376                <span class="p">(</span>fmt<span class="o">-&gt;</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     377                <span class="p">(</span>fmt<span class="o">-&gt;</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     378                <span class="p">(</span>fmt<span class="o">-&gt;</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">24</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">);</span>
     379
     380        red <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
     381        <span class="k">for</span> <span class="p">(</span>i <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> i <span class="o">&lt;</span> size<span class="p">;</span> i <span class="o">+=</span> <span class="mi">4</span><span class="p">)</span> <span class="p">{</span>
     382                u <span class="o">=</span> p<span class="p">[</span>i<span class="o">+</span><span class="mi">0</span><span class="p">];</span>
     383                y1 <span class="o">=</span> p<span class="p">[</span>i<span class="o">+</span><span class="mi">1</span><span class="p">];</span>
     384                v <span class="o">=</span> p<span class="p">[</span>i<span class="o">+</span><span class="mi">2</span><span class="p">];</span>
     385                y2 <span class="o">=</span> p<span class="p">[</span>i<span class="o">+</span><span class="mi">3</span><span class="p">];</span>
     386
     387                u <span class="o">-=</span> <span class="mi">128</span><span class="p">;</span>
     388                v <span class="o">-=</span> <span class="mi">128</span><span class="p">;</span>
     389
     390                r <span class="o">=</span> y1 <span class="o">+</span> v <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">5</span><span class="p">);</span>
     391                g <span class="o">=</span> y1 <span class="o">-</span> <span class="p">((</span>u<span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">5</span><span class="p">))</span>
     392                       <span class="o">-</span> <span class="p">((</span>v<span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">5</span><span class="p">));</span>
     393                b <span class="o">=</span> y1 <span class="o">+</span> u <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">6</span><span class="p">);</span>
     394                <span class="k">if</span> <span class="p">(</span>r <span class="o">&gt;</span> <span class="mi">100</span> <span class="o">&amp;&amp;</span> g <span class="o">&lt;</span> <span class="mi">60</span> <span class="o">&amp;&amp;</span> b <span class="o">&lt;</span> <span class="mi">60</span><span class="p">)</span> red<span class="o">++</span><span class="p">;</span>
     395
     396                r <span class="o">=</span> y2 <span class="o">+</span> v <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">5</span><span class="p">);</span>
     397                g <span class="o">=</span> y2 <span class="o">-</span> <span class="p">((</span>u<span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">5</span><span class="p">))</span>
     398                       <span class="o">-</span> <span class="p">((</span>v<span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>v<span class="o">&gt;&gt;</span><span class="mi">5</span><span class="p">));</span>
     399                b <span class="o">=</span> y2 <span class="o">+</span> u <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span>u<span class="o">&gt;&gt;</span><span class="mi">6</span><span class="p">);</span>
     400                <span class="k">if</span> <span class="p">(</span>r <span class="o">&gt;</span> <span class="mi">100</span> <span class="o">&amp;&amp;</span> g <span class="o">&lt;</span> <span class="mi">60</span> <span class="o">&amp;&amp;</span> b <span class="o">&lt;</span> <span class="mi">60</span><span class="p">)</span> red<span class="o">++</span><span class="p">;</span>
     401
     402                <span class="cm">/* describe pixels on first line every 250 pixels
     403                 * (colorbars)
     404                 */</span>
     405                x <span class="o">=</span> <span class="p">(</span>i<span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">)</span> <span class="o">%</span> fmt<span class="o">-&gt;</span>width<span class="p">;</span>
     406                y <span class="o">=</span> <span class="p">(</span>i<span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">)</span> <span class="o">/</span> fmt<span class="o">-&gt;</span>height<span class="p">;</span>
     407                <span class="k">if</span> <span class="p">(</span>y <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="p">(</span>x <span class="o">%</span> <span class="mi">250</span><span class="p">))</span> <span class="p">{</span>
     408                        printf<span class="p">(</span><span class="s">"[%4d,%4d] YUYV:0x%02x%02x%02x%02x "</span><span class="p">,</span>
     409                                        x<span class="p">,</span>y<span class="p">,</span>y1<span class="p">,(</span><span class="kt">uint8_t</span><span class="p">)</span>u<span class="p">,</span>y2<span class="p">,(</span><span class="kt">uint8_t</span><span class="p">)</span>v<span class="p">);</span>
     410                        printf<span class="p">(</span><span class="s">"RGB:0x%02x%02x%02x</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> r<span class="p">,</span>g<span class="p">,</span>b<span class="p">);</span>
     411                <span class="p">}</span>
     412        <span class="p">}</span>
     413        printf<span class="p">(</span><span class="s">"red pixel count=%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> red<span class="p">);</span>
     414<span class="p">}</span>
     415
     416<span class="k">static</span> <span class="kt">void</span> <span class="nf">save_frame</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span>path<span class="p">,</span> <span class="k">const</span> <span class="kt">void</span> <span class="o">*</span>p<span class="p">,</span> <span class="kt">int</span> size<span class="p">)</span>
     417<span class="p">{</span>
     418        <span class="kt">int</span> fd<span class="p">,</span> rz<span class="p">;</span>
     419
     420        fd <span class="o">=</span> open<span class="p">(</span>path<span class="p">,</span> O_WRONLY <span class="o">|</span> O_CREAT <span class="o">|</span> O_TRUNC<span class="p">,</span> <span class="mo">0755</span><span class="p">);</span>
     421        <span class="k">if</span> <span class="p">(</span>fd <span class="o">&lt;</span> <span class="mi">0</span><span class="p">)</span>
     422                perror<span class="p">(</span><span class="s">"open"</span><span class="p">);</span>
     423        <span class="k">else</span> <span class="p">{</span>
     424                rz <span class="o">=</span> write<span class="p">(</span>fd<span class="p">,</span> p<span class="p">,</span> size<span class="p">);</span>
     425                printf<span class="p">(</span><span class="s">"Wrote %d of %d bytes to %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> rz<span class="p">,</span> size<span class="p">,</span> path<span class="p">);</span>
     426                close<span class="p">(</span>fd<span class="p">);</span>
     427        <span class="p">}</span>
     428<span class="p">}</span>
     429
     430<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> argc<span class="p">,</span> <span class="kt">char</span> <span class="o">**</span>argv<span class="p">)</span>
     431<span class="p">{</span>
     432        <span class="k">static</span> <span class="kt">char</span> <span class="o">*</span>dev_name<span class="p">;</span>
     433        <span class="kt">int</span> width<span class="p">,</span> height<span class="p">;</span>
     434        <span class="k">static</span> <span class="kt">int</span> fd <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
     435        <span class="k">struct</span> stat st<span class="p">;</span>
     436        <span class="k">struct</span> buffer <span class="o">*</span>buffers<span class="p">;</span>
     437        <span class="k">static</span> <span class="kt">unsigned</span> <span class="kt">int</span> n_buffers<span class="p">;</span>
     438        <span class="k">enum</span> v4l2_buf_type type<span class="p">;</span>
     439        <span class="k">struct</span> v4l2_capability cap<span class="p">;</span>
     440        <span class="k">struct</span> v4l2_format fmt<span class="p">;</span>
     441        <span class="k">struct</span> v4l2_requestbuffers req<span class="p">;</span>
     442        <span class="k">struct</span> v4l2_streamparm parm<span class="p">;</span>
     443        <span class="k">struct</span> v4l2_input input<span class="p">;</span>
     444        v4l2_std_id std_id<span class="p">;</span>
     445        <span class="k">struct</span> v4l2_buffer buf<span class="p">;</span>
     446        <span class="kt">unsigned</span> <span class="kt">int</span> count<span class="p">;</span>
     447        <span class="kt">unsigned</span> <span class="kt">int</span> i<span class="p">;</span>
     448        <span class="kt">char</span> filename<span class="p">[</span><span class="mi">32</span><span class="p">];</span>
     449
     450        <span class="cm">/* parse args */</span>
     451        <span class="k">if</span> <span class="p">(</span>argc <span class="o">&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
     452                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"usage: %s &lt;device&gt; &lt;width&gt; &lt;height&gt; &lt;count&gt;</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     453                        argv<span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
     454                exit<span class="p">(</span><span class="mi">1</span><span class="p">);</span>
     455        <span class="p">}</span>
     456        dev_name <span class="o">=</span> argv<span class="p">[</span><span class="mi">1</span><span class="p">];</span>
     457        width <span class="o">=</span> atoi<span class="p">(</span>argv<span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
     458        height <span class="o">=</span> atoi<span class="p">(</span>argv<span class="p">[</span><span class="mi">3</span><span class="p">]);</span>
     459        count <span class="o">=</span> atoi<span class="p">(</span>argv<span class="p">[</span><span class="mi">4</span><span class="p">]);</span>
     460
     461        <span class="cm">/* open device */</span>
     462        fd <span class="o">=</span> open<span class="p">(</span>dev_name<span class="p">,</span> O_RDWR <span class="o">|</span> O_NONBLOCK<span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
     463        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> fd<span class="p">)</span> <span class="p">{</span>
     464                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"Cannot open '%s': %d, %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     465                                dev_name<span class="p">,</span> errno<span class="p">,</span> strerror<span class="p">(</span>errno<span class="p">));</span>
     466                exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     467        <span class="p">}</span>
     468
     469        <span class="cm">/* get standard (wait for it to be locked onto a signal) */</span>
     470        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_G_STD<span class="p">,</span> <span class="o">&amp;</span>std_id<span class="p">))</span>
     471                perror<span class="p">(</span><span class="s">"VIDIOC_G_STD"</span><span class="p">);</span>
     472        <span class="k">for</span> <span class="p">(</span>i <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> std_id <span class="o">==</span> V4L2_STD_ALL <span class="o">&amp;&amp;</span> i <span class="o">&lt;</span> <span class="mi">10</span><span class="p">;</span> i<span class="o">++</span><span class="p">)</span> <span class="p">{</span>
     473                usleep<span class="p">(</span><span class="mi">100000</span><span class="p">);</span>
     474                xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_G_STD<span class="p">,</span> <span class="o">&amp;</span>std_id<span class="p">);</span>
     475        <span class="p">}</span>
     476        <span class="cm">/* set the standard to the detected standard (this is critical for autodetect) */</span>
     477        <span class="k">if</span> <span class="p">(</span>std_id <span class="o">!=</span> V4L2_STD_UNKNOWN<span class="p">)</span> <span class="p">{</span>
     478                <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_S_STD<span class="p">,</span> <span class="o">&amp;</span>std_id<span class="p">))</span>
     479                        perror<span class="p">(</span><span class="s">"VIDIOC_S_STD"</span><span class="p">);</span>
     480                <span class="k">if</span> <span class="p">(</span>std_id <span class="o">&amp;</span> V4L2_STD_NTSC<span class="p">)</span>
     481                        printf<span class="p">(</span><span class="s">"found NTSC TV decoder</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
     482                <span class="k">if</span> <span class="p">(</span>std_id <span class="o">&amp;</span> V4L2_STD_SECAM<span class="p">)</span>
     483                        printf<span class="p">(</span><span class="s">"found SECAM TV decoder</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
     484                <span class="k">if</span> <span class="p">(</span>std_id <span class="o">&amp;</span> V4L2_STD_PAL<span class="p">)</span>
     485                        printf<span class="p">(</span><span class="s">"found PAL TV decoder</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
     486        <span class="p">}</span>
     487
     488        <span class="cm">/* ensure device has video capture capability */</span>
     489        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_QUERYCAP<span class="p">,</span> <span class="o">&amp;</span>cap<span class="p">))</span> <span class="p">{</span>
     490                <span class="k">if</span> <span class="p">(</span>EINVAL <span class="o">==</span> errno<span class="p">)</span> <span class="p">{</span>
     491                        fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"%s is no V4L2 device</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     492                                        dev_name<span class="p">);</span>
     493                        exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     494                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
     495                        errno_exit<span class="p">(</span><span class="s">"VIDIOC_QUERYCAP"</span><span class="p">);</span>
     496                <span class="p">}</span>
     497        <span class="p">}</span>
     498        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span>cap<span class="p">.</span>capabilities <span class="o">&amp;</span> V4L2_CAP_VIDEO_CAPTURE<span class="p">))</span> <span class="p">{</span>
     499                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"%s is no video capture device</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     500                                dev_name<span class="p">);</span>
     501                exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     502        <span class="p">}</span>
     503        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="p">(</span>cap<span class="p">.</span>capabilities <span class="o">&amp;</span> V4L2_CAP_STREAMING<span class="p">))</span> <span class="p">{</span>
     504                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"%s does not support streaming i/o</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     505                                dev_name<span class="p">);</span>
     506                exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     507        <span class="p">}</span>
     508
     509        <span class="cm">/* set video input */</span>
     510        CLEAR<span class="p">(</span>input<span class="p">);</span>
     511        input<span class="p">.</span>index <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="cm">/* IMX6 v4l2 driver: input1 is CSI&lt;-&gt;MEM */</span>
     512        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_S_INPUT<span class="p">,</span> <span class="o">&amp;</span>input<span class="p">))</span>
     513                perror<span class="p">(</span><span class="s">"VIDIOC_S_INPUT"</span><span class="p">);</span>
     514
     515        <span class="cm">/* set framerate */</span>
     516        CLEAR<span class="p">(</span>parm<span class="p">);</span>
     517        parm<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     518        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_S_PARM<span class="p">,</span> <span class="o">&amp;</span>parm<span class="p">))</span>
     519                perror<span class="p">(</span><span class="s">"VIDIOC_S_PARM"</span><span class="p">);</span>
     520
     521        <span class="cm">/* get framerate */</span>
     522        CLEAR<span class="p">(</span>parm<span class="p">);</span>
     523        parm<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     524        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_G_PARM<span class="p">,</span> <span class="o">&amp;</span>parm<span class="p">))</span>
     525                perror<span class="p">(</span><span class="s">"VIDIOC_G_PARM"</span><span class="p">);</span>
     526
     527        <span class="cm">/* set format */</span>
     528        CLEAR<span class="p">(</span>fmt<span class="p">);</span>
     529        fmt<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     530        fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>width       <span class="o">=</span> width<span class="p">;</span>
     531        fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>height      <span class="o">=</span> height<span class="p">;</span>
     532        fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>pixelformat <span class="o">=</span> V4L2_PIX_FMT_UYVY<span class="p">;</span>
     533        fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>field       <span class="o">=</span> V4L2_FIELD_ANY<span class="p">;</span>
     534        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_S_FMT<span class="p">,</span> <span class="o">&amp;</span>fmt<span class="p">))</span>
     535                errno_exit<span class="p">(</span><span class="s">"VIDIOC_S_FMT"</span><span class="p">);</span>
     536
     537        <span class="cm">/* get and display format */</span>
     538        CLEAR<span class="p">(</span>fmt<span class="p">);</span>
     539        fmt<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     540        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_G_FMT<span class="p">,</span> <span class="o">&amp;</span>fmt<span class="p">))</span>
     541                errno_exit<span class="p">(</span><span class="s">"VIDIOC_G_FMT"</span><span class="p">);</span>
     542        printf<span class="p">(</span><span class="s">"%s: %dx%d %c%c%c%c %2.2ffps</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> dev_name<span class="p">,</span>
     543                fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>width<span class="p">,</span> fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>height<span class="p">,</span>
     544                <span class="p">(</span>fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     545                <span class="p">(</span>fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">8</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     546                <span class="p">(</span>fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     547                <span class="p">(</span>fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">.</span>pixelformat <span class="o">&gt;&gt;</span> <span class="mi">24</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xff</span><span class="p">,</span>
     548                <span class="p">(</span><span class="kt">float</span><span class="p">)</span>parm<span class="p">.</span>parm<span class="p">.</span>capture<span class="p">.</span>timeperframe<span class="p">.</span>denominator <span class="o">/</span>
     549                <span class="p">(</span><span class="kt">float</span><span class="p">)</span>parm<span class="p">.</span>parm<span class="p">.</span>capture<span class="p">.</span>timeperframe<span class="p">.</span>numerator
     550                <span class="p">);</span>
     551
     552        <span class="cm">/* request buffers */</span>
     553        CLEAR<span class="p">(</span>req<span class="p">);</span>
     554        req<span class="p">.</span>count <span class="o">=</span> <span class="mi">4</span><span class="p">;</span>
     555        req<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     556        req<span class="p">.</span>memory <span class="o">=</span> V4L2_MEMORY_MMAP<span class="p">;</span>
     557        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_REQBUFS<span class="p">,</span> <span class="o">&amp;</span>req<span class="p">))</span> <span class="p">{</span>
     558                <span class="k">if</span> <span class="p">(</span>EINVAL <span class="o">==</span> errno<span class="p">)</span> <span class="p">{</span>
     559                        fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"%s does not support "</span>
     560                                 <span class="s">"memory mapping</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> dev_name<span class="p">);</span>
     561                        exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     562                <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
     563                        errno_exit<span class="p">(</span><span class="s">"VIDIOC_REQBUFS"</span><span class="p">);</span>
     564                <span class="p">}</span>
     565        <span class="p">}</span>
     566        <span class="k">if</span> <span class="p">(</span>req<span class="p">.</span>count <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
     567                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"Insufficient buffer memory on %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
     568                         dev_name<span class="p">);</span>
     569                exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     570        <span class="p">}</span>
     571
     572        <span class="cm">/* allocate buffers */</span>
     573        buffers <span class="o">=</span> calloc<span class="p">(</span>req<span class="p">.</span>count<span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="o">*</span>buffers<span class="p">));</span>
     574        <span class="k">if</span> <span class="p">(</span><span class="o">!</span>buffers<span class="p">)</span> <span class="p">{</span>
     575                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"Out of memory</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
     576                exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     577        <span class="p">}</span>
     578
     579        <span class="cm">/* mmap buffers */</span>
     580        <span class="k">for</span> <span class="p">(</span>n_buffers <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> n_buffers <span class="o">&lt;</span> req<span class="p">.</span>count<span class="p">;</span> <span class="o">++</span>n_buffers<span class="p">)</span> <span class="p">{</span>
     581                <span class="k">struct</span> v4l2_buffer buf<span class="p">;</span>
     582
     583                CLEAR<span class="p">(</span>buf<span class="p">);</span>
     584
     585                buf<span class="p">.</span>type        <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     586                buf<span class="p">.</span>memory      <span class="o">=</span> V4L2_MEMORY_MMAP<span class="p">;</span>
     587                buf<span class="p">.</span>index       <span class="o">=</span> n_buffers<span class="p">;</span>
     588
     589                <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_QUERYBUF<span class="p">,</span> <span class="o">&amp;</span>buf<span class="p">))</span>
     590                        errno_exit<span class="p">(</span><span class="s">"VIDIOC_QUERYBUF"</span><span class="p">);</span>
     591
     592                buffers<span class="p">[</span>n_buffers<span class="p">].</span>length <span class="o">=</span> buf<span class="p">.</span>length<span class="p">;</span>
     593                buffers<span class="p">[</span>n_buffers<span class="p">].</span>start <span class="o">=</span>
     594                        mmap<span class="p">(</span><span class="nb">NULL</span> <span class="cm">/* start anywhere */</span><span class="p">,</span>
     595                              buf<span class="p">.</span>length<span class="p">,</span>
     596                              PROT_READ <span class="o">|</span> PROT_WRITE <span class="cm">/* required */</span><span class="p">,</span>
     597                              MAP_SHARED <span class="cm">/* recommended */</span><span class="p">,</span>
     598                              fd<span class="p">,</span> buf<span class="p">.</span>m<span class="p">.</span>offset<span class="p">);</span>
     599
     600                <span class="k">if</span> <span class="p">(</span>MAP_FAILED <span class="o">==</span> buffers<span class="p">[</span>n_buffers<span class="p">].</span>start<span class="p">)</span>
     601                        errno_exit<span class="p">(</span><span class="s">"mmap"</span><span class="p">);</span>
     602        <span class="p">}</span>
     603
     604        <span class="cm">/* queue buffers */</span>
     605        <span class="k">for</span> <span class="p">(</span>i <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> i <span class="o">&lt;</span> n_buffers<span class="p">;</span> <span class="o">++</span>i<span class="p">)</span> <span class="p">{</span>
     606                <span class="k">struct</span> v4l2_buffer buf<span class="p">;</span>
     607
     608                CLEAR<span class="p">(</span>buf<span class="p">);</span>
     609                buf<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     610                buf<span class="p">.</span>memory <span class="o">=</span> V4L2_MEMORY_MMAP<span class="p">;</span>
     611                buf<span class="p">.</span>index <span class="o">=</span> i<span class="p">;</span>
     612
     613                <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_QBUF<span class="p">,</span> <span class="o">&amp;</span>buf<span class="p">))</span>
     614                        errno_exit<span class="p">(</span><span class="s">"VIDIOC_QBUF"</span><span class="p">);</span>
     615        <span class="p">}</span>
     616
     617        <span class="cm">/* start capture */</span>
     618        type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     619        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_STREAMON<span class="p">,</span> <span class="o">&amp;</span>type<span class="p">))</span>
     620                errno_exit<span class="p">(</span><span class="s">"VIDIOC_STREAMON"</span><span class="p">);</span>
     621
     622        <span class="cm">/* capture frame(s) (we throw away first incomplete frame ) */</span>
     623        <span class="k">for</span> <span class="p">(</span>i <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> i <span class="o">&lt;</span> count <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> i<span class="o">++</span><span class="p">)</span> <span class="p">{</span>
     624                <span class="k">for</span> <span class="p">(;;)</span> <span class="p">{</span>
     625                        fd_set fds<span class="p">;</span>
     626                        <span class="k">struct</span> timeval tv<span class="p">;</span>
     627                        <span class="kt">int</span> r<span class="p">;</span>
     628
     629                        FD_ZERO<span class="p">(</span><span class="o">&amp;</span>fds<span class="p">);</span>
     630                        FD_SET<span class="p">(</span>fd<span class="p">,</span> <span class="o">&amp;</span>fds<span class="p">);</span>
     631
     632                        <span class="cm">/* Timeout. */</span>
     633                        tv<span class="p">.</span>tv_sec <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
     634                        tv<span class="p">.</span>tv_usec <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
     635
     636                        r <span class="o">=</span> select<span class="p">(</span>fd <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span>fds<span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span>tv<span class="p">);</span>
     637                        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> r<span class="p">)</span> <span class="p">{</span>
     638                                <span class="k">if</span> <span class="p">(</span>EINTR <span class="o">==</span> errno<span class="p">)</span>
     639                                        <span class="k">continue</span><span class="p">;</span>
     640                                errno_exit<span class="p">(</span><span class="s">"select"</span><span class="p">);</span>
     641                        <span class="p">}</span>
     642                        <span class="k">if</span> <span class="p">(</span><span class="mi">0</span> <span class="o">==</span> r<span class="p">)</span> <span class="p">{</span>
     643                                fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"select timeout</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
     644                                exit<span class="p">(</span>EXIT_FAILURE<span class="p">);</span>
     645                        <span class="p">}</span>
     646
     647                        <span class="cm">/* dequeue captured buffer */</span>
     648                        CLEAR<span class="p">(</span>buf<span class="p">);</span>
     649                        buf<span class="p">.</span>type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     650                        buf<span class="p">.</span>memory <span class="o">=</span> V4L2_MEMORY_MMAP<span class="p">;</span>
     651                        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_DQBUF<span class="p">,</span> <span class="o">&amp;</span>buf<span class="p">))</span> <span class="p">{</span>
     652                                <span class="k">if</span> <span class="p">(</span>errno <span class="o">==</span> EAGAIN<span class="p">)</span>
     653                                        <span class="k">continue</span><span class="p">;</span>
     654                                errno_exit<span class="p">(</span><span class="s">"VIDIOC_DQBUF"</span><span class="p">);</span>
     655                        <span class="p">}</span>
     656                        assert<span class="p">(</span>buf<span class="p">.</span>index <span class="o">&lt;</span> n_buffers<span class="p">);</span>
     657
     658                        <span class="cm">/* skip first image as it may not be sync'd */</span>
     659                        <span class="k">if</span> <span class="p">(</span>i <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
     660                                process_image<span class="p">(</span>buffers<span class="p">[</span>buf<span class="p">.</span>index<span class="p">].</span>start<span class="p">,</span>
     661                                        <span class="o">&amp;</span>fmt<span class="p">.</span>fmt<span class="p">.</span>pix<span class="p">);</span>
     662                                sprintf<span class="p">(</span>filename<span class="p">,</span> <span class="s">"frame%d.raw"</span><span class="p">,</span> i<span class="p">);</span>
     663                                save_frame<span class="p">(</span>filename<span class="p">,</span>
     664                                        buffers<span class="p">[</span>buf<span class="p">.</span>index<span class="p">].</span>start<span class="p">,</span>
     665                                        buf<span class="p">.</span>bytesused<span class="p">);</span>
     666                        <span class="p">}</span>
     667
     668                        <span class="cm">/* queue buffer */</span>
     669                        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_QBUF<span class="p">,</span> <span class="o">&amp;</span>buf<span class="p">))</span>
     670                                errno_exit<span class="p">(</span><span class="s">"VIDIOC_QBUF"</span><span class="p">);</span>
     671
     672                        <span class="k">break</span><span class="p">;</span>
     673                <span class="p">}</span>
     674        <span class="p">}</span>
     675
     676        <span class="cm">/* stop capture */</span>
     677        type <span class="o">=</span> V4L2_BUF_TYPE_VIDEO_CAPTURE<span class="p">;</span>
     678        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> xioctl<span class="p">(</span>fd<span class="p">,</span> VIDIOC_STREAMOFF<span class="p">,</span> <span class="o">&amp;</span>type<span class="p">))</span>
     679                errno_exit<span class="p">(</span><span class="s">"VIDIOC_STREAMOFF"</span><span class="p">);</span>
     680
     681        <span class="cm">/* unmap and free buffers */</span>
     682        <span class="k">for</span> <span class="p">(</span>i <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> i <span class="o">&lt;</span> n_buffers<span class="p">;</span> <span class="o">++</span>i<span class="p">)</span>
     683                <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> munmap<span class="p">(</span>buffers<span class="p">[</span>i<span class="p">].</span>start<span class="p">,</span> buffers<span class="p">[</span>i<span class="p">].</span>length<span class="p">))</span>
     684                        errno_exit<span class="p">(</span><span class="s">"munmap"</span><span class="p">);</span>
     685        free<span class="p">(</span>buffers<span class="p">);</span>
     686
     687        <span class="cm">/* close device */</span>
     688        <span class="k">if</span> <span class="p">(</span><span class="o">-</span><span class="mi">1</span> <span class="o">==</span> close<span class="p">(</span>fd<span class="p">))</span>
     689                errno_exit<span class="p">(</span><span class="s">"close"</span><span class="p">);</span>
     690
     691        fprintf<span class="p">(</span>stderr<span class="p">,</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
     692        <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
     693<span class="p">}</span>
     694</pre></div></li></ul><p>
     695Example usage:
     696</p>
     697<ul><li>Capture HDMI input on GW5400 from a 1080P HDMI source:
     698<div class="code"><pre><span class="nv">$ </span>./capture /dev/video0 1920 1080 1
     699/dev/video0: 1920x1080 UYVY 60.00fps
     700Processing Frame: 1920x1080 UYVY
     701<span class="o">[</span>   0,   0<span class="o">]</span> YUYV:0xeb00eb00 RGB:0xebebeb
     702<span class="o">[</span> 250,   0<span class="o">]</span> YUYV:0x9dad9d0d RGB:0xaeb409
     703<span class="o">[</span> 500,   0<span class="o">]</span> YUYV:0x801b80ae RGB:0x0bb6ae
     704<span class="o">[</span> 750,   0<span class="o">]</span> YUYV:0x6dc96dbb RGB:0x0ab50b
     705<span class="o">[</span>1000,   0<span class="o">]</span> YUYV:0x52365244 RGB:0xb111b0
     706red pixel <span class="nv">count</span><span class="o">=</span>259200
     707Wrote 4147200 of 4147200 bytes to frame.raw
     708
     709./convert -size 1920x1080 -depth 16 uyvy:frame.raw frame.png <span class="c"># convert to png via imagemagick
     710</span></pre></div></li><li>Capture CVBS input on GW5400 from NTSC camera (720x480):
     711<div class="code"><pre><span class="nv">$ </span>./capture /dev/video1 720 480 1
     712/dev/video1: 720x520 UYVY 30.00fps
     713Processing Frame: 720x520 UYVY
     714<span class="o">[</span>   0,   0<span class="o">]</span> YUYV:0x1eff1c00 RGB:0x1c1f18
     715<span class="o">[</span> 250,   0<span class="o">]</span> YUYV:0x1dfd1d01 RGB:0x1e2016
     716<span class="o">[</span> 500,   0<span class="o">]</span> YUYV:0x28fa2aff RGB:0x26321e
     717red pixel <span class="nv">count</span><span class="o">=</span>27
     718Wrote 748800 of 748800 bytes to frame.raw
     719
     720./convert -size 720x480 -depth 16 uyvy:frame.raw frame.png <span class="c"># convert to png via imagemagick
     721</span></pre></div></li></ul
     722}}}