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