<?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>Image Cropping, Insertion and Scaling</title><meta name="generator" content="DocBook XSL Stylesheets V1.76.1" /><link rel="home" href="index.html" title="LINUX MEDIA INFRASTRUCTURE API" /><link rel="up" href="common.html" title="Chapter 1. Common API Elements" /><link rel="prev" href="format.html" title="Data Formats" /><link rel="next" href="streaming-par.html" title="Streaming Parameters" /></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Image Cropping, Insertion and Scaling</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="format.html">Prev</a> </td><th width="60%" align="center">Chapter 1. Common API Elements</th><td width="20%" align="right"> <a accesskey="n" href="streaming-par.html">Next</a></td></tr></table><hr /></div><div class="section" title="Image Cropping, Insertion and Scaling"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a id="crop"></a>Image Cropping, Insertion and Scaling</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="crop.html#id3036831">Cropping Structures</a></span></dt><dt><span class="section"><a href="crop.html#id3036988">Scaling Adjustments</a></span></dt><dt><span class="section"><a href="crop.html#id3037071">Examples</a></span></dt></dl></div><p>Some video capture devices can sample a subsection of the picture and shrink or enlarge it to an image of arbitrary size. We call these abilities cropping and scaling. Some video output devices can scale an image up or down and insert it at an arbitrary scan line and horizontal offset into a video signal.</p><p>Applications can use the following API to select an area in the video signal, query the default area and the hardware limits. <span class="emphasis"><em>Despite their name, the <a class="link" href="vidioc-cropcap.html" title="ioctl VIDIOC_CROPCAP"><code class="constant">VIDIOC_CROPCAP</code></a>, <a class="link" href="vidioc-g-crop.html" title="ioctl VIDIOC_G_CROP, VIDIOC_S_CROP"><code class="constant">VIDIOC_G_CROP</code></a> and <a class="link" href="vidioc-g-crop.html" title="ioctl VIDIOC_G_CROP, VIDIOC_S_CROP"><code class="constant">VIDIOC_S_CROP</code></a> ioctls apply to input as well as output devices.</em></span></p><p>Scaling requires a source and a target. On a video capture or overlay device the source is the video signal, and the cropping ioctls determine the area actually sampled. The target are images read by the application or overlaid onto the graphics screen. Their size (and position for an overlay) is negotiated with the <a class="link" href="vidioc-g-fmt.html" title="ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT"><code class="constant">VIDIOC_G_FMT</code></a> and <a class="link" href="vidioc-g-fmt.html" title="ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT"><code class="constant">VIDIOC_S_FMT</code></a> ioctls.</p><p>On a video output device the source are the images passed in by the application, and their size is again negotiated with the <code class="constant">VIDIOC_G/S_FMT</code> ioctls, or may be encoded in a compressed video stream. The target is the video signal, and the cropping ioctls determine the area where the images are inserted.</p><p>Source and target rectangles are defined even if the device does not support scaling or the <code class="constant">VIDIOC_G/S_CROP</code> ioctls. Their size (and position where applicable) will be fixed in this case. <span class="emphasis"><em>All capture and output device must support the <code class="constant">VIDIOC_CROPCAP</code> ioctl such that applications can determine if scaling takes place.</em></span></p><div class="section" title="Cropping Structures"><div class="titlepage"><div><div><h3 class="title"><a id="id3036831"></a>Cropping Structures</h3></div></div></div><div class="figure"><a id="crop-scale"></a><p class="title"><strong>Figure 1.1. Image Cropping, Insertion and Scaling</strong></p><div class="figure-contents"><div class="mediaobject"><img src="crop.gif" alt="The cropping, insertion and scaling process" /></div></div></div><br class="figure-break" /><p>For capture devices the coordinates of the top left corner, width and height of the area which can be sampled is given by the <em class="structfield"><code>bounds</code></em> substructure of the struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a> returned by the <code class="constant">VIDIOC_CROPCAP</code> ioctl. To support a wide range of hardware this specification does not define an origin or units. However by convention drivers should horizontally count unscaled samples relative to 0H (the leading edge of the horizontal sync pulse, see <a class="xref" href="raw-vbi.html#vbi-hsync" title="Figure 4.1. Line synchronization">Figure 4.1, “Line synchronization”</a>). Vertically ITU-R line numbers of the first field (<a class="xref" href="raw-vbi.html#vbi-525" title="Figure 4.2. ITU-R 525 line numbering (M/NTSC and M/PAL)">Figure 4.2, “ITU-R 525 line numbering (M/NTSC and M/PAL)”</a>, <a class="xref" href="raw-vbi.html#vbi-625" title="Figure 4.3. ITU-R 625 line numbering">Figure 4.3, “ITU-R 625 line numbering”</a>), multiplied by two if the driver can capture both fields.</p><p>The top left corner, width and height of the source rectangle, that is the area actually sampled, is given by struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.40. struct v4l2_crop">v4l2_crop</a> using the same coordinate system as struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a>. Applications can use the <code class="constant">VIDIOC_G_CROP</code> and <code class="constant">VIDIOC_S_CROP</code> ioctls to get and set this rectangle. It must lie completely within the capture boundaries and the driver may further adjust the requested size and/or position according to hardware limitations.</p><p>Each capture device has a default source rectangle, given by the <em class="structfield"><code>defrect</code></em> substructure of struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a>. The center of this rectangle shall align with the center of the active picture area of the video signal, and cover what the driver writer considers the complete picture. Drivers shall reset the source rectangle to the default when the driver is first loaded, but not later.</p><p>For output devices these structures and ioctls are used accordingly, defining the <span class="emphasis"><em>target</em></span> rectangle where the images will be inserted into the video signal.</p></div><div class="section" title="Scaling Adjustments"><div class="titlepage"><div><div><h3 class="title"><a id="id3036988"></a>Scaling Adjustments</h3></div></div></div><p>Video hardware can have various cropping, insertion and scaling limitations. It may only scale up or down, support only discrete scaling factors, or have different scaling abilities in horizontal and vertical direction. Also it may not support scaling at all. At the same time the struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.40. struct v4l2_crop">v4l2_crop</a> rectangle may have to be aligned, and both the source and target rectangles may have arbitrary upper and lower size limits. In particular the maximum <em class="structfield"><code>width</code></em> and <em class="structfield"><code>height</code></em> in struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.40. struct v4l2_crop">v4l2_crop</a> may be smaller than the struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a>.<em class="structfield"><code>bounds</code></em> area. Therefore, as usual, drivers are expected to adjust the requested parameters and return the actual values selected.</p><p>Applications can change the source or the target rectangle first, as they may prefer a particular image size or a certain area in the video signal. If the driver has to adjust both to satisfy hardware limitations, the last requested rectangle shall take priority, and the driver should preferably adjust the opposite one. The <a class="link" href="vidioc-g-fmt.html" title="ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT"><code class="constant">VIDIOC_TRY_FMT</code></a> ioctl however shall not change the driver state and therefore only adjust the requested rectangle.</p><p>Suppose scaling on a video capture device is restricted to a factor 1:1 or 2:1 in either direction and the target image size must be a multiple of 16 × 16 pixels. The source cropping rectangle is set to defaults, which are also the upper limit in this example, of 640 × 400 pixels at offset 0, 0. An application requests an image size of 300 × 225 pixels, assuming video will be scaled down from the "full picture" accordingly. The driver sets the image size to the closest possible values 304 × 224, then chooses the cropping rectangle closest to the requested size, that is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is still valid, thus unmodified. Given the default cropping rectangle reported by <code class="constant">VIDIOC_CROPCAP</code> the application can easily propose another offset to center the cropping rectangle.</p><p>Now the application may insist on covering an area using a picture aspect ratio closer to the original request, so it asks for a cropping rectangle of 608 × 456 pixels. The present scaling factors limit cropping to 640 × 384, so the driver returns the cropping size 608 × 384 and adjusts the image size to closest possible 304 × 192.</p></div><div class="section" title="Examples"><div class="titlepage"><div><div><h3 class="title"><a id="id3037071"></a>Examples</h3></div></div></div><p>Source and target rectangles shall remain unchanged across closing and reopening a device, such that piping data into or out of a device will work without special preparations. More advanced applications should ensure the parameters are suitable before starting I/O.</p><div class="example"><a id="id3037102"></a><p class="title"><strong>Example 1.10. Resetting the cropping parameters</strong></p><div class="example-contents"><p>(A video capture device is assumed; change <code class="constant">V4L2_BUF_TYPE_VIDEO_CAPTURE</code> for other devices.)</p><pre class="programlisting"> struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.40. struct v4l2_crop">v4l2_crop</a> crop; memset (&cropcap, 0, sizeof (cropcap)); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (fd, <a class="link" href="vidioc-cropcap.html" title="ioctl VIDIOC_CROPCAP"><code class="constant">VIDIOC_CROPCAP</code></a>, &cropcap)) { perror ("VIDIOC_CROPCAP"); exit (EXIT_FAILURE); } memset (&crop, 0, sizeof (crop)); crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c = cropcap.defrect; /* Ignore if cropping is not supported (EINVAL). */ if (-1 == ioctl (fd, <a class="link" href="vidioc-g-crop.html" title="ioctl VIDIOC_G_CROP, VIDIOC_S_CROP"><code class="constant">VIDIOC_S_CROP</code></a>, &crop) && errno != EINVAL) { perror ("VIDIOC_S_CROP"); exit (EXIT_FAILURE); } </pre></div></div><br class="example-break" /><div class="example"><a id="id3037169"></a><p class="title"><strong>Example 1.11. Simple downscaling</strong></p><div class="example-contents"><p>(A video capture device is assumed.)</p><pre class="programlisting"> struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; struct <a class="link" href="vidioc-g-fmt.html#v4l2-format" title="Table A.55. struct v4l2_format">v4l2_format</a> format; reset_cropping_parameters (); /* Scale down to 1/4 size of full picture. */ memset (&format, 0, sizeof (format)); /* defaults */ format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; format.fmt.pix.width = cropcap.defrect.width >> 1; format.fmt.pix.height = cropcap.defrect.height >> 1; format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; if (-1 == ioctl (fd, <a class="link" href="vidioc-g-fmt.html" title="ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT"><code class="constant">VIDIOC_S_FMT</code></a>, &format)) { perror ("VIDIOC_S_FORMAT"); exit (EXIT_FAILURE); } /* We could check the actual image size now, the actual scaling factor or if the driver can scale at all. */ </pre></div></div><br class="example-break" /><div class="example"><a id="id3037225"></a><p class="title"><strong>Example 1.12. Selecting an output area</strong></p><div class="example-contents"><pre class="programlisting"> struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.40. struct v4l2_crop">v4l2_crop</a> crop; memset (&cropcap, 0, sizeof (cropcap)); cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) { perror ("VIDIOC_CROPCAP"); exit (EXIT_FAILURE); } memset (&crop, 0, sizeof (crop)); crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; crop.c = cropcap.defrect; /* Scale the width and height to 50 % of their original size and center the output. */ crop.c.width /= 2; crop.c.height /= 2; crop.c.left += crop.c.width / 2; crop.c.top += crop.c.height / 2; /* Ignore if cropping is not supported (EINVAL). */ if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop) && errno != EINVAL) { perror ("VIDIOC_S_CROP"); exit (EXIT_FAILURE); } </pre></div></div><br class="example-break" /><div class="example"><a id="id3037275"></a><p class="title"><strong>Example 1.13. Current scaling factor and pixel aspect</strong></p><div class="example-contents"><p>(A video capture device is assumed.)</p><pre class="programlisting"> struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.1. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.40. struct v4l2_crop">v4l2_crop</a> crop; struct <a class="link" href="vidioc-g-fmt.html#v4l2-format" title="Table A.55. struct v4l2_format">v4l2_format</a> format; double hscale, vscale; double aspect; int dwidth, dheight; memset (&cropcap, 0, sizeof (cropcap)); cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (fd, <a class="link" href="vidioc-cropcap.html" title="ioctl VIDIOC_CROPCAP"><code class="constant">VIDIOC_CROPCAP</code></a>, &cropcap)) { perror ("VIDIOC_CROPCAP"); exit (EXIT_FAILURE); } memset (&crop, 0, sizeof (crop)); crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (fd, <a class="link" href="vidioc-g-crop.html" title="ioctl VIDIOC_G_CROP, VIDIOC_S_CROP"><code class="constant">VIDIOC_G_CROP</code></a>, &crop)) { if (errno != EINVAL) { perror ("VIDIOC_G_CROP"); exit (EXIT_FAILURE); } /* Cropping not supported. */ crop.c = cropcap.defrect; } memset (&format, 0, sizeof (format)); format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == ioctl (fd, <a class="link" href="vidioc-g-fmt.html" title="ioctl VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT"><code class="constant">VIDIOC_G_FMT</code></a>, &format)) { perror ("VIDIOC_G_FMT"); exit (EXIT_FAILURE); } /* The scaling applied by the driver. */ hscale = format.fmt.pix.width / (double) crop.c.width; vscale = format.fmt.pix.height / (double) crop.c.height; aspect = cropcap.pixelaspect.numerator / (double) cropcap.pixelaspect.denominator; aspect = aspect * hscale / vscale; /* Devices following ITU-R BT.601 do not capture square pixels. For playback on a computer monitor we should scale the images to this size. */ dwidth = format.fmt.pix.width / aspect; dheight = format.fmt.pix.height; </pre></div></div><br class="example-break" /></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="format.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="common.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="streaming-par.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Data Formats </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Streaming Parameters</td></tr></table></div></body></html>