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