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