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