0001 .. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
0002
0003 .. _crop:
0004
0005 *****************************************************
0006 Image Cropping, Insertion and Scaling -- the CROP API
0007 *****************************************************
0008
0009 .. note::
0010
0011 The CROP API is mostly superseded by the newer :ref:`SELECTION API
0012 <selection-api>`. The new API should be preferred in most cases,
0013 with the exception of pixel aspect ratio detection, which is
0014 implemented by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` and has no
0015 equivalent in the SELECTION API. See :ref:`selection-vs-crop` for a
0016 comparison of the two APIs.
0017
0018 Some video capture devices can sample a subsection of the picture and
0019 shrink or enlarge it to an image of arbitrary size. We call these
0020 abilities cropping and scaling. Some video output devices can scale an
0021 image up or down and insert it at an arbitrary scan line and horizontal
0022 offset into a video signal.
0023
0024 Applications can use the following API to select an area in the video
0025 signal, query the default area and the hardware limits.
0026
0027 .. note::
0028
0029 Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`,
0030 :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP
0031 <VIDIOC_G_CROP>` ioctls apply to input as well as output devices.
0032
0033 Scaling requires a source and a target. On a video capture or overlay
0034 device the source is the video signal, and the cropping ioctls determine
0035 the area actually sampled. The target are images read by the application
0036 or overlaid onto the graphics screen. Their size (and position for an
0037 overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
0038 and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls.
0039
0040 On a video output device the source are the images passed in by the
0041 application, and their size is again negotiated with the
0042 :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
0043 ioctls, or may be encoded in a compressed video stream. The target is
0044 the video signal, and the cropping ioctls determine the area where the
0045 images are inserted.
0046
0047 Source and target rectangles are defined even if the device does not
0048 support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
0049 :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position
0050 where applicable) will be fixed in this case.
0051
0052 .. note::
0053
0054 All capture and output devices that support the CROP or SELECTION
0055 API will also support the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`
0056 ioctl.
0057
0058 Cropping Structures
0059 ===================
0060
0061
0062 .. _crop-scale:
0063
0064 .. kernel-figure:: crop.svg
0065 :alt: crop.svg
0066 :align: center
0067
0068 Image Cropping, Insertion and Scaling
0069
0070 The cropping, insertion and scaling process
0071
0072
0073
0074 For capture devices the coordinates of the top left corner, width and
0075 height of the area which can be sampled is given by the ``bounds``
0076 substructure of the struct :c:type:`v4l2_cropcap` returned
0077 by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide
0078 range of hardware this specification does not define an origin or units.
0079 However by convention drivers should horizontally count unscaled samples
0080 relative to 0H (the leading edge of the horizontal sync pulse, see
0081 :ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field
0082 (see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for
0083 :ref:`625 lines <vbi-625>`), multiplied by two if the driver
0084 can capture both fields.
0085
0086 The top left corner, width and height of the source rectangle, that is
0087 the area actually sampled, is given by struct
0088 :c:type:`v4l2_crop` using the same coordinate system as
0089 struct :c:type:`v4l2_cropcap`. Applications can use the
0090 :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>`
0091 ioctls to get and set this rectangle. It must lie completely within the
0092 capture boundaries and the driver may further adjust the requested size
0093 and/or position according to hardware limitations.
0094
0095 Each capture device has a default source rectangle, given by the
0096 ``defrect`` substructure of struct
0097 :c:type:`v4l2_cropcap`. The center of this rectangle
0098 shall align with the center of the active picture area of the video
0099 signal, and cover what the driver writer considers the complete picture.
0100 Drivers shall reset the source rectangle to the default when the driver
0101 is first loaded, but not later.
0102
0103 For output devices these structures and ioctls are used accordingly,
0104 defining the *target* rectangle where the images will be inserted into
0105 the video signal.
0106
0107
0108 Scaling Adjustments
0109 ===================
0110
0111 Video hardware can have various cropping, insertion and scaling
0112 limitations. It may only scale up or down, support only discrete scaling
0113 factors, or have different scaling abilities in horizontal and vertical
0114 direction. Also it may not support scaling at all. At the same time the
0115 struct :c:type:`v4l2_crop` rectangle may have to be aligned,
0116 and both the source and target rectangles may have arbitrary upper and
0117 lower size limits. In particular the maximum ``width`` and ``height`` in
0118 struct :c:type:`v4l2_crop` may be smaller than the struct
0119 :c:type:`v4l2_cropcap`. ``bounds`` area. Therefore, as
0120 usual, drivers are expected to adjust the requested parameters and
0121 return the actual values selected.
0122
0123 Applications can change the source or the target rectangle first, as
0124 they may prefer a particular image size or a certain area in the video
0125 signal. If the driver has to adjust both to satisfy hardware
0126 limitations, the last requested rectangle shall take priority, and the
0127 driver should preferably adjust the opposite one. The
0128 :ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change
0129 the driver state and therefore only adjust the requested rectangle.
0130
0131 Suppose scaling on a video capture device is restricted to a factor 1:1
0132 or 2:1 in either direction and the target image size must be a multiple
0133 of 16 × 16 pixels. The source cropping rectangle is set to defaults,
0134 which are also the upper limit in this example, of 640 × 400 pixels at
0135 offset 0, 0. An application requests an image size of 300 × 225 pixels,
0136 assuming video will be scaled down from the "full picture" accordingly.
0137 The driver sets the image size to the closest possible values 304 × 224,
0138 then chooses the cropping rectangle closest to the requested size, that
0139 is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is
0140 still valid, thus unmodified. Given the default cropping rectangle
0141 reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can
0142 easily propose another offset to center the cropping rectangle.
0143
0144 Now the application may insist on covering an area using a picture
0145 aspect ratio closer to the original request, so it asks for a cropping
0146 rectangle of 608 × 456 pixels. The present scaling factors limit
0147 cropping to 640 × 384, so the driver returns the cropping size 608 × 384
0148 and adjusts the image size to closest possible 304 × 192.
0149
0150
0151 Examples
0152 ========
0153
0154 Source and target rectangles shall remain unchanged across closing and
0155 reopening a device, such that piping data into or out of a device will
0156 work without special preparations. More advanced applications should
0157 ensure the parameters are suitable before starting I/O.
0158
0159 .. note::
0160
0161 On the next two examples, a video capture device is assumed;
0162 change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device.
0163
0164 Example: Resetting the cropping parameters
0165 ==========================================
0166
0167 .. code-block:: c
0168
0169 struct v4l2_cropcap cropcap;
0170 struct v4l2_crop crop;
0171
0172 memset (&cropcap, 0, sizeof (cropcap));
0173 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0174
0175 if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
0176 perror ("VIDIOC_CROPCAP");
0177 exit (EXIT_FAILURE);
0178 }
0179
0180 memset (&crop, 0, sizeof (crop));
0181 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0182 crop.c = cropcap.defrect;
0183
0184 /* Ignore if cropping is not supported (EINVAL). */
0185
0186 if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
0187 && errno != EINVAL) {
0188 perror ("VIDIOC_S_CROP");
0189 exit (EXIT_FAILURE);
0190 }
0191
0192
0193 Example: Simple downscaling
0194 ===========================
0195
0196 .. code-block:: c
0197
0198 struct v4l2_cropcap cropcap;
0199 struct v4l2_format format;
0200
0201 reset_cropping_parameters ();
0202
0203 /* Scale down to 1/4 size of full picture. */
0204
0205 memset (&format, 0, sizeof (format)); /* defaults */
0206
0207 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0208
0209 format.fmt.pix.width = cropcap.defrect.width >> 1;
0210 format.fmt.pix.height = cropcap.defrect.height >> 1;
0211 format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
0212
0213 if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) {
0214 perror ("VIDIOC_S_FORMAT");
0215 exit (EXIT_FAILURE);
0216 }
0217
0218 /* We could check the actual image size now, the actual scaling factor
0219 or if the driver can scale at all. */
0220
0221 Example: Selecting an output area
0222 =================================
0223
0224 .. note:: This example assumes an output device.
0225
0226 .. code-block:: c
0227
0228 struct v4l2_cropcap cropcap;
0229 struct v4l2_crop crop;
0230
0231 memset (&cropcap, 0, sizeof (cropcap));
0232 cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
0233
0234 if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
0235 perror ("VIDIOC_CROPCAP");
0236 exit (EXIT_FAILURE);
0237 }
0238
0239 memset (&crop, 0, sizeof (crop));
0240
0241 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
0242 crop.c = cropcap.defrect;
0243
0244 /* Scale the width and height to 50 % of their original size
0245 and center the output. */
0246
0247 crop.c.width /= 2;
0248 crop.c.height /= 2;
0249 crop.c.left += crop.c.width / 2;
0250 crop.c.top += crop.c.height / 2;
0251
0252 /* Ignore if cropping is not supported (EINVAL). */
0253
0254 if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
0255 && errno != EINVAL) {
0256 perror ("VIDIOC_S_CROP");
0257 exit (EXIT_FAILURE);
0258 }
0259
0260 Example: Current scaling factor and pixel aspect
0261 ================================================
0262
0263 .. note:: This example assumes a video capture device.
0264
0265 .. code-block:: c
0266
0267 struct v4l2_cropcap cropcap;
0268 struct v4l2_crop crop;
0269 struct v4l2_format format;
0270 double hscale, vscale;
0271 double aspect;
0272 int dwidth, dheight;
0273
0274 memset (&cropcap, 0, sizeof (cropcap));
0275 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0276
0277 if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
0278 perror ("VIDIOC_CROPCAP");
0279 exit (EXIT_FAILURE);
0280 }
0281
0282 memset (&crop, 0, sizeof (crop));
0283 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0284
0285 if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) {
0286 if (errno != EINVAL) {
0287 perror ("VIDIOC_G_CROP");
0288 exit (EXIT_FAILURE);
0289 }
0290
0291 /* Cropping not supported. */
0292 crop.c = cropcap.defrect;
0293 }
0294
0295 memset (&format, 0, sizeof (format));
0296 format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0297
0298 if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) {
0299 perror ("VIDIOC_G_FMT");
0300 exit (EXIT_FAILURE);
0301 }
0302
0303 /* The scaling applied by the driver. */
0304
0305 hscale = format.fmt.pix.width / (double) crop.c.width;
0306 vscale = format.fmt.pix.height / (double) crop.c.height;
0307
0308 aspect = cropcap.pixelaspect.numerator /
0309 (double) cropcap.pixelaspect.denominator;
0310 aspect = aspect * hscale / vscale;
0311
0312 /* Devices following ITU-R BT.601 do not capture
0313 square pixels. For playback on a computer monitor
0314 we should scale the images to this size. */
0315
0316 dwidth = format.fmt.pix.width / aspect;
0317 dheight = format.fmt.pix.height;