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