crop.rst 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
.. -*- coding: utf-8; mode: rst -*-

.. _crop:

*************************************
Image Cropping, Insertion and Scaling
*************************************

Some video capture devices can sample a subsection of the picture and
shrink or enlarge it to an image of arbitrary size. We call these
abilities cropping and scaling. Some video output devices can scale an
image up or down and insert it at an arbitrary scan line and horizontal
offset into a video signal.

Applications can use the following API to select an area in the video
16 17 18 19 20
signal, query the default area and the hardware limits.

**NOTE**: Despite their name, the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>`,
:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP
<VIDIOC_G_CROP>` ioctls apply to input as well as output devices.
21 22 23 24 25

Scaling requires a source and a target. On a video capture or overlay
device the source is the video signal, and the cropping ioctls determine
the area actually sampled. The target are images read by the application
or overlaid onto the graphics screen. Their size (and position for an
26
overlay) is negotiated with the :ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>`
27
and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>` ioctls.
28 29 30

On a video output device the source are the images passed in by the
application, and their size is again negotiated with the
31 32 33 34
:ref:`VIDIOC_G_FMT <VIDIOC_G_FMT>` and :ref:`VIDIOC_S_FMT <VIDIOC_G_FMT>`
ioctls, or may be encoded in a compressed video stream. The target is
the video signal, and the cropping ioctls determine the area where the
images are inserted.
35 36

Source and target rectangles are defined even if the device does not
37 38 39 40 41 42 43
support scaling or the :ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and
:ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>` ioctls. Their size (and position
where applicable) will be fixed in this case.

**NOTE:** All capture and output devices must support the
:ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl such that applications can
determine if scaling takes place.
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63


Cropping Structures
===================


.. _crop-scale:

.. figure::  crop_files/crop.*
    :alt:    crop.pdf / crop.gif
    :align:  center

    Image Cropping, Insertion and Scaling

    The cropping, insertion and scaling process



For capture devices the coordinates of the top left corner, width and
height of the area which can be sampled is given by the ``bounds``
64 65 66 67
substructure of the struct :ref:`v4l2_cropcap <v4l2-cropcap>` returned
by the :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` ioctl. To support a wide
range of hardware this specification does not define an origin or units.
However by convention drivers should horizontally count unscaled samples
68 69
relative to 0H (the leading edge of the horizontal sync pulse, see
:ref:`vbi-hsync`). Vertically ITU-R line numbers of the first field
70 71
(see ITU R-525 line numbering for :ref:`525 lines <vbi-525>` and for
:ref:`625 lines <vbi-625>`), multiplied by two if the driver
72 73 74 75 76 77
can capture both fields.

The top left corner, width and height of the source rectangle, that is
the area actually sampled, is given by struct
:ref:`v4l2_crop <v4l2-crop>` using the same coordinate system as
struct :ref:`v4l2_cropcap <v4l2-cropcap>`. Applications can use the
78 79 80 81
:ref:`VIDIOC_G_CROP <VIDIOC_G_CROP>` and :ref:`VIDIOC_S_CROP <VIDIOC_G_CROP>`
ioctls to get and set this rectangle. It must lie completely within the
capture boundaries and the driver may further adjust the requested size
and/or position according to hardware limitations.
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

Each capture device has a default source rectangle, given by the
``defrect`` substructure of struct
:ref:`v4l2_cropcap <v4l2-cropcap>`. The center of this rectangle
shall align with the center of the active picture area of the video
signal, and cover what the driver writer considers the complete picture.
Drivers shall reset the source rectangle to the default when the driver
is first loaded, but not later.

For output devices these structures and ioctls are used accordingly,
defining the *target* rectangle where the images will be inserted into
the video signal.


Scaling Adjustments
===================

Video hardware can have various cropping, insertion and scaling
limitations. It may only scale up or down, support only discrete scaling
factors, or have different scaling abilities in horizontal and vertical
direction. Also it may not support scaling at all. At the same time the
struct :ref:`v4l2_crop <v4l2-crop>` rectangle may have to be aligned,
and both the source and target rectangles may have arbitrary upper and
lower size limits. In particular the maximum ``width`` and ``height`` in
struct :ref:`v4l2_crop <v4l2-crop>` may be smaller than the struct
:ref:`v4l2_cropcap <v4l2-cropcap>`. ``bounds`` area. Therefore, as
usual, drivers are expected to adjust the requested parameters and
return the actual values selected.

Applications can change the source or the target rectangle first, as
they may prefer a particular image size or a certain area in the video
signal. If the driver has to adjust both to satisfy hardware
limitations, the last requested rectangle shall take priority, and the
driver should preferably adjust the opposite one. The
116
:ref:`VIDIOC_TRY_FMT <VIDIOC_G_FMT>` ioctl however shall not change
117 118 119 120 121 122 123 124 125 126 127 128
the driver state and therefore only adjust the requested rectangle.

Suppose scaling on a video capture device is restricted to a factor 1:1
or 2:1 in either direction and the target image size must be a multiple
of 16 × 16 pixels. The source cropping rectangle is set to defaults,
which are also the upper limit in this example, of 640 × 400 pixels at
offset 0, 0. An application requests an image size of 300 × 225 pixels,
assuming video will be scaled down from the "full picture" accordingly.
The driver sets the image size to the closest possible values 304 × 224,
then chooses the cropping rectangle closest to the requested size, that
is 608 × 224 (224 × 2:1 would exceed the limit 400). The offset 0, 0 is
still valid, thus unmodified. Given the default cropping rectangle
129 130
reported by :ref:`VIDIOC_CROPCAP <VIDIOC_CROPCAP>` the application can
easily propose another offset to center the cropping rectangle.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

Now the application may insist on covering an area using a picture
aspect ratio closer to the original request, so it asks for a cropping
rectangle of 608 × 456 pixels. The present scaling factors limit
cropping to 640 × 384, so the driver returns the cropping size 608 × 384
and adjusts the image size to closest possible 304 × 192.


Examples
========

Source and target rectangles shall remain unchanged across closing and
reopening a device, such that piping data into or out of a device will
work without special preparations. More advanced applications should
ensure the parameters are suitable before starting I/O.

147 148
**NOTE:** on the next two examples, a video capture device is assumed;
change ``V4L2_BUF_TYPE_VIDEO_CAPTURE`` for other types of device.
149

150 151 152
Example: Resetting the cropping parameters
==========================================

153 154 155 156 157 158 159 160 161
.. code-block:: c

    struct v4l2_cropcap cropcap;
    struct v4l2_crop crop;

    memset (&cropcap, 0, sizeof (cropcap));
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
162 163
	perror ("VIDIOC_CROPCAP");
	exit (EXIT_FAILURE);
164 165 166 167 168 169 170 171 172
    }

    memset (&crop, 0, sizeof (crop));
    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    crop.c = cropcap.defrect;

    /* Ignore if cropping is not supported (EINVAL). */

    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
173 174 175
	&& errno != EINVAL) {
	perror ("VIDIOC_S_CROP");
	exit (EXIT_FAILURE);
176 177
    }

178 179 180 181

Example: Simple downscaling
===========================

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
.. code-block:: c

    struct v4l2_cropcap cropcap;
    struct v4l2_format format;

    reset_cropping_parameters ();

    /* Scale down to 1/4 size of full picture. */

    memset (&format, 0, sizeof (format)); /* defaults */

    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    format.fmt.pix.width = cropcap.defrect.width >> 1;
    format.fmt.pix.height = cropcap.defrect.height >> 1;
    format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;

    if (-1 == ioctl (fd, VIDIOC_S_FMT, &format)) {
200 201
	perror ("VIDIOC_S_FORMAT");
	exit (EXIT_FAILURE);
202 203 204 205 206
    }

    /* We could check the actual image size now, the actual scaling factor
       or if the driver can scale at all. */

207 208 209
Example: Selecting an output area
=================================

210
**NOTE:** This example assumes an output device.
211 212 213 214 215 216 217 218 219 220

.. code-block:: c

    struct v4l2_cropcap cropcap;
    struct v4l2_crop crop;

    memset (&cropcap, 0, sizeof (cropcap));
    cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;

    if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
221 222
	perror ("VIDIOC_CROPCAP");
	exit (EXIT_FAILURE);
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
    }

    memset (&crop, 0, sizeof (crop));

    crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
    crop.c = cropcap.defrect;

    /* Scale the width and height to 50 % of their original size
       and center the output. */

    crop.c.width /= 2;
    crop.c.height /= 2;
    crop.c.left += crop.c.width / 2;
    crop.c.top += crop.c.height / 2;

    /* Ignore if cropping is not supported (EINVAL). */

    if (-1 == ioctl (fd, VIDIOC_S_CROP, &crop)
241 242 243
	&& errno != EINVAL) {
	perror ("VIDIOC_S_CROP");
	exit (EXIT_FAILURE);
244 245
    }

246 247 248
Example: Current scaling factor and pixel aspect
================================================

249
**NOTE:** This example assumes a video capture device.
250 251 252 253 254 255 256 257 258 259 260 261 262 263

.. code-block:: c

    struct v4l2_cropcap cropcap;
    struct v4l2_crop crop;
    struct v4l2_format format;
    double hscale, vscale;
    double aspect;
    int dwidth, dheight;

    memset (&cropcap, 0, sizeof (cropcap));
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == ioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
264 265
	perror ("VIDIOC_CROPCAP");
	exit (EXIT_FAILURE);
266 267 268 269 270 271
    }

    memset (&crop, 0, sizeof (crop));
    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == ioctl (fd, VIDIOC_G_CROP, &crop)) {
272 273 274 275
	if (errno != EINVAL) {
	    perror ("VIDIOC_G_CROP");
	    exit (EXIT_FAILURE);
	}
276

277 278
	/* Cropping not supported. */
	crop.c = cropcap.defrect;
279 280 281 282 283 284
    }

    memset (&format, 0, sizeof (format));
    format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (-1 == ioctl (fd, VIDIOC_G_FMT, &format)) {
285 286
	perror ("VIDIOC_G_FMT");
	exit (EXIT_FAILURE);
287 288 289 290 291 292 293 294
    }

    /* The scaling applied by the driver. */

    hscale = format.fmt.pix.width / (double) crop.c.width;
    vscale = format.fmt.pix.height / (double) crop.c.height;

    aspect = cropcap.pixelaspect.numerator /
295
	 (double) cropcap.pixelaspect.denominator;
296 297 298 299 300 301 302 303
    aspect = aspect * hscale / vscale;

    /* Devices following ITU-R BT.601 do not capture
       square pixels. For playback on a computer monitor
       we should scale the images to this size. */

    dwidth = format.fmt.pix.width / aspect;
    dheight = format.fmt.pix.height;