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