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