brintos

brintos / linux-shallow public Read only

0
0
Text · 10.9 KiB · 3fe185e Raw
318 lines · plain
1.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later2 3.. _crop:4 5*****************************************************6Image Cropping, Insertion and Scaling -- the CROP API7*****************************************************8 9.. note::10 11   The CROP API is mostly superseded by the newer :ref:`SELECTION API12   <selection-api>`. The new API should be preferred in most cases,13   with the exception of pixel aspect ratio detection, which is14   implemented by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` and has no15   equivalent in the SELECTION API. See :ref:`selection-vs-crop` for a16   comparison of the two APIs.17 18Some video capture devices can sample a subsection of the picture and19shrink or enlarge it to an image of arbitrary size. We call these20abilities cropping and scaling. Some video output devices can scale an21image up or down and insert it at an arbitrary scan line and horizontal22offset into a video signal.23 24Applications can use the following API to select an area in the video25signal, query the default area and the hardware limits.26 27.. note::28 29   Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`,30   :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP31   <VIDIOC_G_CROP>` ioctls apply to input as well as output devices.32 33Scaling requires a source and a target. On a video capture or overlay34device the source is the video signal, and the cropping ioctls determine35the area actually sampled. The target are images read by the application36or overlaid onto the graphics screen. Their size (and position for an37overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`38and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls.39 40On a video output device the source are the images passed in by the41application, and their size is again negotiated with the42:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`43ioctls, or may be encoded in a compressed video stream. The target is44the video signal, and the cropping ioctls determine the area where the45images are inserted.46 47Source and target rectangles are defined even if the device does not48support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and49:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position50where applicable) will be fixed in this case.51 52.. note::53 54   All capture and output devices that support the CROP or SELECTION55   API will also support the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`56   ioctl.57 58Cropping Structures59===================60 61 62.. _crop-scale:63 64.. kernel-figure:: crop.svg65    :alt:    crop.svg66    :align:  center67 68    Image Cropping, Insertion and Scaling69 70    The cropping, insertion and scaling process71 72 73 74For capture devices the coordinates of the top left corner, width and75height of the area which can be sampled is given by the ``bounds``76substructure of the struct :c:type:`v4l2_cropcap` returned77by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide78range of hardware this specification does not define an origin or units.79However by convention drivers should horizontally count unscaled samples80relative to 0H (the leading edge of the horizontal sync pulse, see81:ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field82(see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for83:ref:`625 lines <vbi-625>`), multiplied by two if the driver84can capture both fields.85 86The top left corner, width and height of the source rectangle, that is87the area actually sampled, is given by struct88:c:type:`v4l2_crop` using the same coordinate system as89struct :c:type:`v4l2_cropcap`. Applications can use the90:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>`91ioctls to get and set this rectangle. It must lie completely within the92capture boundaries and the driver may further adjust the requested size93and/or position according to hardware limitations.94 95Each capture device has a default source rectangle, given by the96``defrect`` substructure of struct97:c:type:`v4l2_cropcap`. The center of this rectangle98shall align with the center of the active picture area of the video99signal, and cover what the driver writer considers the complete picture.100Drivers shall reset the source rectangle to the default when the driver101is first loaded, but not later.102 103For output devices these structures and ioctls are used accordingly,104defining the *target* rectangle where the images will be inserted into105the video signal.106 107 108Scaling Adjustments109===================110 111Video hardware can have various cropping, insertion and scaling112limitations. It may only scale up or down, support only discrete scaling113factors, or have different scaling abilities in horizontal and vertical114direction. Also it may not support scaling at all. At the same time the115struct :c:type:`v4l2_crop` rectangle may have to be aligned,116and both the source and target rectangles may have arbitrary upper and117lower size limits. In particular the maximum ``width`` and ``height`` in118struct :c:type:`v4l2_crop` may be smaller than the struct119:c:type:`v4l2_cropcap`. ``bounds`` area. Therefore, as120usual, drivers are expected to adjust the requested parameters and121return the actual values selected.122 123Applications can change the source or the target rectangle first, as124they may prefer a particular image size or a certain area in the video125signal. If the driver has to adjust both to satisfy hardware126limitations, the last requested rectangle shall take priority, and the127driver should preferably adjust the opposite one. The128:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change129the driver state and therefore only adjust the requested rectangle.130 131Suppose scaling on a video capture device is restricted to a factor 1:1132or 2:1 in either direction and the target image size must be a multiple133of 16 × 16 pixels. The source cropping rectangle is set to defaults,134which are also the upper limit in this example, of 640 × 400 pixels at135offset 0, 0. An application requests an image size of 300 × 225 pixels,136assuming video will be scaled down from the "full picture" accordingly.137The driver sets the image size to the closest possible values 304 × 224,138then chooses the cropping rectangle closest to the requested size, that139is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is140still valid, thus unmodified. Given the default cropping rectangle141reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can142easily propose another offset to center the cropping rectangle.143 144Now the application may insist on covering an area using a picture145aspect ratio closer to the original request, so it asks for a cropping146rectangle of 608 × 456 pixels. The present scaling factors limit147cropping to 640 × 384, so the driver returns the cropping size 608 × 384148and adjusts the image size to closest possible 304 × 192.149 150 151Examples152========153 154Source and target rectangles shall remain unchanged across closing and155reopening a device, such that piping data into or out of a device will156work without special preparations. More advanced applications should157ensure the parameters are suitable before starting I/O.158 159.. note::160 161   On the next two examples, a video capture device is assumed;162   change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device.163 164Example: Resetting the cropping parameters165==========================================166 167.. code-block:: c168 169    struct v4l2_cropcap cropcap;170    struct v4l2_crop crop;171 172    memset (&cropcap, 0, sizeof (cropcap));173    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;174 175    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {176	perror ("VIDIOC_CROPCAP");177	exit (EXIT_FAILURE);178    }179 180    memset (&crop, 0, sizeof (crop));181    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;182    crop.c = cropcap.defrect;183 184    /* Ignore if cropping is not supported (EINVAL). */185 186    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)187	&& errno != EINVAL) {188	perror ("VIDIOC_S_CROP");189	exit (EXIT_FAILURE);190    }191 192 193Example: Simple downscaling194===========================195 196.. code-block:: c197 198    struct v4l2_cropcap cropcap;199    struct v4l2_format format;200 201    reset_cropping_parameters ();202 203    /* Scale down to 1/4 size of full picture. */204 205    memset (&format, 0, sizeof (format)); /* defaults */206 207    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;208 209    format.fmt.pix.width = cropcap.defrect.width >> 1;210    format.fmt.pix.height = cropcap.defrect.height >> 1;211    format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;212 213    if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) {214	perror ("VIDIOC_S_FORMAT");215	exit (EXIT_FAILURE);216    }217 218    /* We could check the actual image size now, the actual scaling factor219       or if the driver can scale at all. */220 221Example: Selecting an output area222=================================223 224.. note:: This example assumes an output device.225 226.. code-block:: c227 228    struct v4l2_cropcap cropcap;229    struct v4l2_crop crop;230 231    memset (&cropcap, 0, sizeof (cropcap));232    cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;233 234    if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {235	perror ("VIDIOC_CROPCAP");236	exit (EXIT_FAILURE);237    }238 239    memset (&crop, 0, sizeof (crop));240 241    crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;242    crop.c = cropcap.defrect;243 244    /* Scale the width and height to 50 % of their original size245       and center the output. */246 247    crop.c.width /= 2;248    crop.c.height /= 2;249    crop.c.left += crop.c.width / 2;250    crop.c.top += crop.c.height / 2;251 252    /* Ignore if cropping is not supported (EINVAL). */253 254    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)255	&& errno != EINVAL) {256	perror ("VIDIOC_S_CROP");257	exit (EXIT_FAILURE);258    }259 260Example: Current scaling factor and pixel aspect261================================================262 263.. note:: This example assumes a video capture device.264 265.. code-block:: c266 267    struct v4l2_cropcap cropcap;268    struct v4l2_crop crop;269    struct v4l2_format format;270    double hscale, vscale;271    double aspect;272    int dwidth, dheight;273 274    memset (&cropcap, 0, sizeof (cropcap));275    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;276 277    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {278	perror ("VIDIOC_CROPCAP");279	exit (EXIT_FAILURE);280    }281 282    memset (&crop, 0, sizeof (crop));283    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;284 285    if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) {286	if (errno != EINVAL) {287	    perror ("VIDIOC_G_CROP");288	    exit (EXIT_FAILURE);289	}290 291	/* Cropping not supported. */292	crop.c = cropcap.defrect;293    }294 295    memset (&format, 0, sizeof (format));296    format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;297 298    if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) {299	perror ("VIDIOC_G_FMT");300	exit (EXIT_FAILURE);301    }302 303    /* The scaling applied by the driver. */304 305    hscale = format.fmt.pix.width / (double) crop.c.width;306    vscale = format.fmt.pix.height / (double) crop.c.height;307 308    aspect = cropcap.pixelaspect.numerator /309	 (double) cropcap.pixelaspect.denominator;310    aspect = aspect * hscale / vscale;311 312    /* Devices following ITU-R BT.601 do not capture313       square pixels. For playback on a computer monitor314       we should scale the images to this size. */315 316    dwidth = format.fmt.pix.width / aspect;317    dheight = format.fmt.pix.height;318