1.. Permission is granted to copy, distribute and/or modify this 2.. document under the terms of the GNU Free Documentation License, 3.. Version 1.1 or any later version published by the Free Software 4.. Foundation, with no Invariant Sections, no Front-Cover Texts 5.. and no Back-Cover Texts. A copy of the license is included at 6.. Documentation/userspace-api/media/fdl-appendix.rst. 7.. 8.. TODO: replace it to GFDL-1.1-or-later WITH no-invariant-sections 9 10.. _crop: 11 12***************************************************** 13Image Cropping, Insertion and Scaling -- the CROP API 14***************************************************** 15 16.. note:: 17 18 The CROP API is mostly superseded by the newer :ref:`SELECTION API 19 <selection-api>`. The new API should be preferred in most cases, 20 with the exception of pixel aspect ratio detection, which is 21 implemented by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` and has no 22 equivalent in the SELECTION API. See :ref:`selection-vs-crop` for a 23 comparison of the two APIs. 24 25Some video capture devices can sample a subsection of the picture and 26shrink or enlarge it to an image of arbitrary size. We call these 27abilities cropping and scaling. Some video output devices can scale an 28image up or down and insert it at an arbitrary scan line and horizontal 29offset into a video signal. 30 31Applications can use the following API to select an area in the video 32signal, query the default area and the hardware limits. 33 34.. note:: 35 36 Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`, 37 :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP 38 <VIDIOC_G_CROP>` ioctls apply to input as well as output devices. 39 40Scaling requires a source and a target. On a video capture or overlay 41device the source is the video signal, and the cropping ioctls determine 42the area actually sampled. The target are images read by the application 43or overlaid onto the graphics screen. Their size (and position for an 44overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` 45and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls. 46 47On a video output device the source are the images passed in by the 48application, and their size is again negotiated with the 49:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` 50ioctls, or may be encoded in a compressed video stream. The target is 51the video signal, and the cropping ioctls determine the area where the 52images are inserted. 53 54Source and target rectangles are defined even if the device does not 55support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and 56:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position 57where applicable) will be fixed in this case. 58 59.. note:: 60 61 All capture and output devices that support the CROP or SELECTION 62 API will also support the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` 63 ioctl. 64 65Cropping Structures 66=================== 67 68 69.. _crop-scale: 70 71.. kernel-figure:: crop.svg 72 :alt: crop.svg 73 :align: center 74 75 Image Cropping, Insertion and Scaling 76 77 The cropping, insertion and scaling process 78 79 80 81For capture devices the coordinates of the top left corner, width and 82height of the area which can be sampled is given by the ``bounds`` 83substructure of the struct :c:type:`v4l2_cropcap` returned 84by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide 85range of hardware this specification does not define an origin or units. 86However by convention drivers should horizontally count unscaled samples 87relative to 0H (the leading edge of the horizontal sync pulse, see 88:ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field 89(see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for 90:ref:`625 lines <vbi-625>`), multiplied by two if the driver 91can capture both fields. 92 93The top left corner, width and height of the source rectangle, that is 94the area actually sampled, is given by struct 95:c:type:`v4l2_crop` using the same coordinate system as 96struct :c:type:`v4l2_cropcap`. Applications can use the 97:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` 98ioctls to get and set this rectangle. It must lie completely within the 99capture boundaries and the driver may further adjust the requested size 100and/or position according to hardware limitations. 101 102Each capture device has a default source rectangle, given by the 103``defrect`` substructure of struct 104:c:type:`v4l2_cropcap`. The center of this rectangle 105shall align with the center of the active picture area of the video 106signal, and cover what the driver writer considers the complete picture. 107Drivers shall reset the source rectangle to the default when the driver 108is first loaded, but not later. 109 110For output devices these structures and ioctls are used accordingly, 111defining the *target* rectangle where the images will be inserted into 112the video signal. 113 114 115Scaling Adjustments 116=================== 117 118Video hardware can have various cropping, insertion and scaling 119limitations. It may only scale up or down, support only discrete scaling 120factors, or have different scaling abilities in horizontal and vertical 121direction. Also it may not support scaling at all. At the same time the 122struct :c:type:`v4l2_crop` rectangle may have to be aligned, 123and both the source and target rectangles may have arbitrary upper and 124lower size limits. In particular the maximum ``width`` and ``height`` in 125struct :c:type:`v4l2_crop` may be smaller than the struct 126:c:type:`v4l2_cropcap`. ``bounds`` area. Therefore, as 127usual, drivers are expected to adjust the requested parameters and 128return the actual values selected. 129 130Applications can change the source or the target rectangle first, as 131they may prefer a particular image size or a certain area in the video 132signal. If the driver has to adjust both to satisfy hardware 133limitations, the last requested rectangle shall take priority, and the 134driver should preferably adjust the opposite one. The 135:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change 136the driver state and therefore only adjust the requested rectangle. 137 138Suppose scaling on a video capture device is restricted to a factor 1:1 139or 2:1 in either direction and the target image size must be a multiple 140of 16 × 16 pixels. The source cropping rectangle is set to defaults, 141which are also the upper limit in this example, of 640 × 400 pixels at 142offset 0, 0. An application requests an image size of 300 × 225 pixels, 143assuming video will be scaled down from the "full picture" accordingly. 144The driver sets the image size to the closest possible values 304 × 224, 145then chooses the cropping rectangle closest to the requested size, that 146is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is 147still valid, thus unmodified. Given the default cropping rectangle 148reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can 149easily propose another offset to center the cropping rectangle. 150 151Now the application may insist on covering an area using a picture 152aspect ratio closer to the original request, so it asks for a cropping 153rectangle of 608 × 456 pixels. The present scaling factors limit 154cropping to 640 × 384, so the driver returns the cropping size 608 × 384 155and adjusts the image size to closest possible 304 × 192. 156 157 158Examples 159======== 160 161Source and target rectangles shall remain unchanged across closing and 162reopening a device, such that piping data into or out of a device will 163work without special preparations. More advanced applications should 164ensure the parameters are suitable before starting I/O. 165 166.. note:: 167 168 On the next two examples, a video capture device is assumed; 169 change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device. 170 171Example: Resetting the cropping parameters 172========================================== 173 174.. code-block:: c 175 176 struct v4l2_cropcap cropcap; 177 struct v4l2_crop crop; 178 179 memset (&cropcap, 0, sizeof (cropcap)); 180 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 181 182 if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) { 183 perror ("VIDIOC_CROPCAP"); 184 exit (EXIT_FAILURE); 185 } 186 187 memset (&crop, 0, sizeof (crop)); 188 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 189 crop.c = cropcap.defrect; 190 191 /* Ignore if cropping is not supported (EINVAL). */ 192 193 if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop) 194 && errno != EINVAL) { 195 perror ("VIDIOC_S_CROP"); 196 exit (EXIT_FAILURE); 197 } 198 199 200Example: Simple downscaling 201=========================== 202 203.. code-block:: c 204 205 struct v4l2_cropcap cropcap; 206 struct v4l2_format format; 207 208 reset_cropping_parameters (); 209 210 /* Scale down to 1/4 size of full picture. */ 211 212 memset (&format, 0, sizeof (format)); /* defaults */ 213 214 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 215 216 format.fmt.pix.width = cropcap.defrect.width >> 1; 217 format.fmt.pix.height = cropcap.defrect.height >> 1; 218 format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; 219 220 if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) { 221 perror ("VIDIOC_S_FORMAT"); 222 exit (EXIT_FAILURE); 223 } 224 225 /* We could check the actual image size now, the actual scaling factor 226 or if the driver can scale at all. */ 227 228Example: Selecting an output area 229================================= 230 231.. note:: This example assumes an output device. 232 233.. code-block:: c 234 235 struct v4l2_cropcap cropcap; 236 struct v4l2_crop crop; 237 238 memset (&cropcap, 0, sizeof (cropcap)); 239 cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 240 241 if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) { 242 perror ("VIDIOC_CROPCAP"); 243 exit (EXIT_FAILURE); 244 } 245 246 memset (&crop, 0, sizeof (crop)); 247 248 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; 249 crop.c = cropcap.defrect; 250 251 /* Scale the width and height to 50 % of their original size 252 and center the output. */ 253 254 crop.c.width /= 2; 255 crop.c.height /= 2; 256 crop.c.left += crop.c.width / 2; 257 crop.c.top += crop.c.height / 2; 258 259 /* Ignore if cropping is not supported (EINVAL). */ 260 261 if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop) 262 && errno != EINVAL) { 263 perror ("VIDIOC_S_CROP"); 264 exit (EXIT_FAILURE); 265 } 266 267Example: Current scaling factor and pixel aspect 268================================================ 269 270.. note:: This example assumes a video capture device. 271 272.. code-block:: c 273 274 struct v4l2_cropcap cropcap; 275 struct v4l2_crop crop; 276 struct v4l2_format format; 277 double hscale, vscale; 278 double aspect; 279 int dwidth, dheight; 280 281 memset (&cropcap, 0, sizeof (cropcap)); 282 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 283 284 if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) { 285 perror ("VIDIOC_CROPCAP"); 286 exit (EXIT_FAILURE); 287 } 288 289 memset (&crop, 0, sizeof (crop)); 290 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 291 292 if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) { 293 if (errno != EINVAL) { 294 perror ("VIDIOC_G_CROP"); 295 exit (EXIT_FAILURE); 296 } 297 298 /* Cropping not supported. */ 299 crop.c = cropcap.defrect; 300 } 301 302 memset (&format, 0, sizeof (format)); 303 format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 304 305 if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) { 306 perror ("VIDIOC_G_FMT"); 307 exit (EXIT_FAILURE); 308 } 309 310 /* The scaling applied by the driver. */ 311 312 hscale = format.fmt.pix.width / (double) crop.c.width; 313 vscale = format.fmt.pix.height / (double) crop.c.height; 314 315 aspect = cropcap.pixelaspect.numerator / 316 (double) cropcap.pixelaspect.denominator; 317 aspect = aspect * hscale / vscale; 318 319 /* Devices following ITU-R BT.601 do not capture 320 square pixels. For playback on a computer monitor 321 we should scale the images to this size. */ 322 323 dwidth = format.fmt.pix.width / aspect; 324 dheight = format.fmt.pix.height; 325