Back to home page

OSCL-LXR

 
 

    


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;