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