1<html><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.78.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="planar-apis.html" title="Single- and multi-planar APIs"><link rel="next" href="selection-api.html" title="Experimental API for cropping, composing and scaling"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Image Cropping, Insertion and Scaling</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="planar-apis.html">Prev</a> </td><th width="60%" align="center">Chapter 1. Common API Elements</th><td width="20%" align="right"> <a accesskey="n" href="selection-api.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="crop"></a>Image Cropping, Insertion and Scaling</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="section"><a href="crop.html#idp1098969740">Cropping Structures</a></span></dt><dt><span class="section"><a href="crop.html#idp1098993076">Scaling Adjustments</a></span></dt><dt><span class="section"><a href="crop.html#idp1098980540">Examples</a></span></dt></dl></div><p>Some video capture devices can sample a subsection of the 2picture and shrink or enlarge it to an image of arbitrary size. We 3call these abilities cropping and scaling. Some video output devices 4can scale an image up or down and insert it at an arbitrary scan line 5and horizontal offset into a video signal.</p><p>Applications can use the following API to select an area in 6the video signal, query the default area and the hardware limits. 7<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> 8and <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 9devices.</em></span></p><p>Scaling requires a source and a target. On a video capture 10or overlay device the source is the video signal, and the cropping 11ioctls determine the area actually sampled. The target are images 12read by the application or overlaid onto the graphics screen. Their 13size (and position for an overlay) is negotiated with the 14<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 15by the application, and their size is again negotiated with the 16<code class="constant">VIDIOC_G/S_FMT</code> ioctls, or may be encoded in a 17compressed video stream. The target is the video signal, and the 18cropping ioctls determine the area where the images are 19inserted.</p><p>Source and target rectangles are defined even if the device 20does not support scaling or the <code class="constant">VIDIOC_G/S_CROP</code> 21ioctls. Their size (and position where applicable) will be fixed in 22this case. <span class="emphasis"><em>All capture and output device must support the 23<code class="constant">VIDIOC_CROPCAP</code> ioctl such that applications can 24determine if scaling takes place.</em></span></p><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp1098969740"></a>Cropping Structures</h3></div></div></div><div class="figure"><a name="crop-scale"></a><p class="title"><b>Figure 1.1. Image Cropping, Insertion and Scaling</b></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 25corner, width and height of the area which can be sampled is given by 26the <em class="structfield"><code>bounds</code></em> substructure of the 27struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a> returned by the <code class="constant">VIDIOC_CROPCAP</code> 28ioctl. To support a wide range of hardware this specification does not 29define an origin or units. However by convention drivers should 30horizontally count unscaled samples relative to 0H (the leading edge 31of 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>). 32Vertically ITU-R line 33numbers 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 34fields.</p><p>The top left corner, width and height of the source 35rectangle, that is the area actually sampled, is given by struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.55. struct v4l2_crop">v4l2_crop</a> 36using the same coordinate system as struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a>. Applications can 37use the <code class="constant">VIDIOC_G_CROP</code> and 38<code class="constant">VIDIOC_S_CROP</code> ioctls to get and set this 39rectangle. It must lie completely within the capture boundaries and 40the driver may further adjust the requested size and/or position 41according to hardware limitations.</p><p>Each capture device has a default source rectangle, given 42by the <em class="structfield"><code>defrect</code></em> substructure of 43struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a>. The center of this rectangle shall align with the 44center of the active picture area of the video signal, and cover what 45the driver writer considers the complete picture. Drivers shall reset 46the source rectangle to the default when the driver is first loaded, 47but not later.</p><p>For output devices these structures and ioctls are used 48accordingly, defining the <span class="emphasis"><em>target</em></span> rectangle where 49the images will be inserted into the video signal.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp1098993076"></a>Scaling Adjustments</h3></div></div></div><p>Video hardware can have various cropping, insertion and 50scaling limitations. It may only scale up or down, support only 51discrete scaling factors, or have different scaling abilities in 52horizontal and vertical direction. Also it may not support scaling at 53all. At the same time the struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.55. struct v4l2_crop">v4l2_crop</a> rectangle may have to be 54aligned, and both the source and target rectangles may have arbitrary 55upper and lower size limits. In particular the maximum 56<em class="structfield"><code>width</code></em> and <em class="structfield"><code>height</code></em> 57in struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.55. struct v4l2_crop">v4l2_crop</a> may be smaller than the 58struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a>.<em class="structfield"><code>bounds</code></em> area. Therefore, as 59usual, drivers are expected to adjust the requested parameters and 60return the actual values selected.</p><p>Applications can change the source or the target rectangle 61first, as they may prefer a particular image size or a certain area in 62the video signal. If the driver has to adjust both to satisfy hardware 63limitations, the last requested rectangle shall take priority, and the 64driver 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> 65ioctl however shall not change the driver state and therefore only 66adjust the requested rectangle.</p><p>Suppose scaling on a video capture device is restricted to 67a factor 1:1 or 2:1 in either direction and the target image size must 68be a multiple of 16 × 16 pixels. The source cropping 69rectangle is set to defaults, which are also the upper limit in this 70example, of 640 × 400 pixels at offset 0, 0. An 71application requests an image size of 300 × 225 72pixels, assuming video will be scaled down from the "full picture" 73accordingly. The driver sets the image size to the closest possible 74values 304 × 224, then chooses the cropping rectangle 75closest to the requested size, that is 608 × 224 76(224 × 2:1 would exceed the limit 400). The offset 770, 0 is still valid, thus unmodified. Given the default cropping 78rectangle reported by <code class="constant">VIDIOC_CROPCAP</code> the 79application can easily propose another offset to center the cropping 80rectangle.</p><p>Now the application may insist on covering an area using a 81picture aspect ratio closer to the original request, so it asks for a 82cropping rectangle of 608 × 456 pixels. The present 83scaling factors limit cropping to 640 × 384, so the 84driver returns the cropping size 608 × 384 and adjusts 85the image size to closest possible 304 × 192.</p></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a name="idp1098980540"></a>Examples</h3></div></div></div><p>Source and target rectangles shall remain unchanged across 86closing and reopening a device, such that piping data into or out of a 87device will work without special preparations. More advanced 88applications should ensure the parameters are suitable before starting 89I/O.</p><div class="example"><a name="idp1098981772"></a><p class="title"><b>Example 1.11. Resetting the cropping parameters</b></p><div class="example-contents"><p>(A video capture device is assumed; change 90<code class="constant">V4L2_BUF_TYPE_VIDEO_CAPTURE</code> for other 91devices.)</p><pre class="programlisting"> 92struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; 93struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.55. struct v4l2_crop">v4l2_crop</a> crop; 94 95memset (&cropcap, 0, sizeof (cropcap)); 96cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 97 98if (-1 == ioctl (fd, <a class="link" href="vidioc-cropcap.html" title="ioctl VIDIOC_CROPCAP"><code class="constant">VIDIOC_CROPCAP</code></a>, &cropcap)) { 99 perror ("VIDIOC_CROPCAP"); 100 exit (EXIT_FAILURE); 101} 102 103memset (&crop, 0, sizeof (crop)); 104crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 105crop.c = cropcap.defrect; 106 107/* Ignore if cropping is not supported (EINVAL). */ 108 109if (-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) 110 && errno != EINVAL) { 111 perror ("VIDIOC_S_CROP"); 112 exit (EXIT_FAILURE); 113} 114 </pre></div></div><br class="example-break"><div class="example"><a name="idp1098986668"></a><p class="title"><b>Example 1.12. Simple downscaling</b></p><div class="example-contents"><p>(A video capture device is assumed.)</p><pre class="programlisting"> 115struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; 116struct <a class="link" href="vidioc-g-fmt.html#v4l2-format" title="Table A.72. struct v4l2_format">v4l2_format</a> format; 117 118reset_cropping_parameters (); 119 120/* Scale down to 1/4 size of full picture. */ 121 122memset (&format, 0, sizeof (format)); /* defaults */ 123 124format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 125 126format.fmt.pix.width = cropcap.defrect.width >> 1; 127format.fmt.pix.height = cropcap.defrect.height >> 1; 128format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 129 130if (-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)) { 131 perror ("VIDIOC_S_FORMAT"); 132 exit (EXIT_FAILURE); 133} 134 135/* We could check the actual image size now, the actual scaling factor 136 or if the driver can scale at all. */ 137 </pre></div></div><br class="example-break"><div class="example"><a name="idp1098989812"></a><p class="title"><b>Example 1.13. Selecting an output area</b></p><div class="example-contents"><pre class="programlisting"> 138struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; 139struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.55. struct v4l2_crop">v4l2_crop</a> crop; 140 141memset (&cropcap, 0, sizeof (cropcap)); 142cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 143 144if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) { 145 perror ("VIDIOC_CROPCAP"); 146 exit (EXIT_FAILURE); 147} 148 149memset (&crop, 0, sizeof (crop)); 150 151crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 152crop.c = cropcap.defrect; 153 154/* Scale the width and height to 50 % of their original size 155 and center the output. */ 156 157crop.c.width /= 2; 158crop.c.height /= 2; 159crop.c.left += crop.c.width / 2; 160crop.c.top += crop.c.height / 2; 161 162/* Ignore if cropping is not supported (EINVAL). */ 163 164if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop) 165 && errno != EINVAL) { 166 perror ("VIDIOC_S_CROP"); 167 exit (EXIT_FAILURE); 168} 169</pre></div></div><br class="example-break"><div class="example"><a name="idp1099008020"></a><p class="title"><b>Example 1.14. Current scaling factor and pixel aspect</b></p><div class="example-contents"><p>(A video capture device is assumed.)</p><pre class="programlisting"> 170struct <a class="link" href="vidioc-cropcap.html#v4l2-cropcap" title="Table A.2. struct v4l2_cropcap">v4l2_cropcap</a> cropcap; 171struct <a class="link" href="vidioc-g-crop.html#v4l2-crop" title="Table A.55. struct v4l2_crop">v4l2_crop</a> crop; 172struct <a class="link" href="vidioc-g-fmt.html#v4l2-format" title="Table A.72. struct v4l2_format">v4l2_format</a> format; 173double hscale, vscale; 174double aspect; 175int dwidth, dheight; 176 177memset (&cropcap, 0, sizeof (cropcap)); 178cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 179 180if (-1 == ioctl (fd, <a class="link" href="vidioc-cropcap.html" title="ioctl VIDIOC_CROPCAP"><code class="constant">VIDIOC_CROPCAP</code></a>, &cropcap)) { 181 perror ("VIDIOC_CROPCAP"); 182 exit (EXIT_FAILURE); 183} 184 185memset (&crop, 0, sizeof (crop)); 186crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 187 188if (-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)) { 189 if (errno != EINVAL) { 190 perror ("VIDIOC_G_CROP"); 191 exit (EXIT_FAILURE); 192 } 193 194 /* Cropping not supported. */ 195 crop.c = cropcap.defrect; 196} 197 198memset (&format, 0, sizeof (format)); 199format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 200 201if (-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)) { 202 perror ("VIDIOC_G_FMT"); 203 exit (EXIT_FAILURE); 204} 205 206/* The scaling applied by the driver. */ 207 208hscale = format.fmt.pix.width / (double) crop.c.width; 209vscale = format.fmt.pix.height / (double) crop.c.height; 210 211aspect = cropcap.pixelaspect.numerator / 212 (double) cropcap.pixelaspect.denominator; 213aspect = aspect * hscale / vscale; 214 215/* Devices following ITU-R BT.601 do not capture 216 square pixels. For playback on a computer monitor 217 we should scale the images to this size. */ 218 219dwidth = format.fmt.pix.width / aspect; 220dheight = format.fmt.pix.height; 221 </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="planar-apis.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="selection-api.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Single- and multi-planar APIs </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Experimental API for cropping, composing and scaling</td></tr></table></div></body></html> 222