&sub-controls;
Data FormatsData Format NegotiationDifferent devices exchange different kinds of data with
applications, for example video images, raw or sliced VBI data, RDS
datagrams. Even within one kind many different formats are possible,
in particular an abundance of image formats. Although drivers must
provide a default and the selection persists across closing and
reopening a device, applications should always negotiate a data format
before engaging in data exchange. Negotiation means the application
asks for a particular format and the driver selects and reports the
best the hardware can do to satisfy the request. Of course
applications can also just query the current selection.A single mechanism exists to negotiate all data formats
using the aggregate &v4l2-format; and the &VIDIOC-G-FMT; and
&VIDIOC-S-FMT; ioctls. Additionally the &VIDIOC-TRY-FMT; ioctl can be
used to examine what the hardware could do,
without actually selecting a new data format. The data formats
supported by the V4L2 API are covered in the respective device section
in . For a closer look at image formats see
.The VIDIOC_S_FMT ioctl is a major
turning-point in the initialization sequence. Prior to this point
multiple panel applications can access the same device concurrently to
select the current input, change controls or modify other properties.
The first VIDIOC_S_FMT assigns a logical stream
(video data, VBI data etc.) exclusively to one file descriptor.Exclusive means no other application, more precisely no
other file descriptor, can grab this stream or change device
properties inconsistent with the negotiated parameters. A video
standard change for example, when the new standard uses a different
number of scan lines, can invalidate the selected image format.
Therefore only the file descriptor owning the stream can make
invalidating changes. Accordingly multiple file descriptors which
grabbed different logical streams prevent each other from interfering
with their settings. When for example video overlay is about to start
or already in progress, simultaneous video capturing may be restricted
to the same cropping and image size.When applications omit the
VIDIOC_S_FMT ioctl its locking side effects are
implied by the next step, the selection of an I/O method with the
&VIDIOC-REQBUFS; ioctl or implicit with the first &func-read; or
&func-write; call.Generally only one logical stream can be assigned to a
file descriptor, the exception being drivers permitting simultaneous
video capturing and overlay using the same file descriptor for
compatibility with V4L and earlier versions of V4L2. Switching the
logical stream or returning into "panel mode" is possible by closing
and reopening the device. Drivers may support a
switch using VIDIOC_S_FMT.All drivers exchanging data with
applications must support the VIDIOC_G_FMT and
VIDIOC_S_FMT ioctl. Implementation of the
VIDIOC_TRY_FMT is highly recommended but
optional.Image Format EnumerationApart of the generic format negotiation functions
a special ioctl to enumerate all image formats supported by video
capture, overlay or output devices is available.Enumerating formats an application has no a-priori
knowledge of (otherwise it could explicitely ask for them and need not
enumerate) seems useless, but there are applications serving as proxy
between drivers and the actual video applications for which this is
useful.The &VIDIOC-ENUM-FMT; ioctl must be supported
by all drivers exchanging image data with applications.Drivers are not supposed to convert image formats in
kernel space. They must enumerate only formats directly supported by
the hardware. If necessary driver writers should publish an example
conversion routine or library for integration into applications.Image Cropping, Insertion and ScalingSome 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 signal, query the default area and the hardware limits.
Despite their name, the &VIDIOC-CROPCAP;, &VIDIOC-G-CROP;
and &VIDIOC-S-CROP; ioctls apply to input as well as output
devices.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 overlay) is negotiated with the
&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls.On a video output device the source are the images passed in
by the application, and their size is again negotiated with the
VIDIOC_G/S_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.Source and target rectangles are defined even if the device
does not support scaling or the VIDIOC_G/S_CROP
ioctls. Their size (and position where applicable) will be fixed in
this case. All capture and output device must support the
VIDIOC_CROPCAP ioctl such that applications can
determine if scaling takes place.Cropping StructuresFor capture devices the coordinates of the top left
corner, width and height of the area which can be sampled is given by
the bounds substructure of the
&v4l2-cropcap; returned by the 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 relative to 0H (the leading edge
of the horizontal sync pulse, see ).
Vertically ITU-R line
numbers of the first field (, ), multiplied by two if the driver can capture both
fields.The top left corner, width and height of the source
rectangle, that is the area actually sampled, is given by &v4l2-crop;
using the same coordinate system as &v4l2-cropcap;. Applications can
use the VIDIOC_G_CROP and
VIDIOC_S_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.Each capture device has a default source rectangle, given
by the defrect substructure of
&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 AdjustmentsVideo 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 &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 &v4l2-crop; may be smaller than the
&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 &VIDIOC-TRY-FMT;
ioctl however shall not change 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 reported by VIDIOC_CROPCAP the
application can easily propose another offset to center the cropping
rectangle.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.ExamplesSource 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.Resetting the cropping parameters(A video capture device is assumed; change
V4L2_BUF_TYPE_VIDEO_CAPTURE for other
devices.)
&v4l2-cropcap; cropcap;
&v4l2-crop; crop;
memset (&cropcap, 0, sizeof (cropcap));
cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &cropcap)) {
perror ("VIDIOC_CROPCAP");
exit (EXIT_FAILURE);
}
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)
&& errno != EINVAL) {
perror ("VIDIOC_S_CROP");
exit (EXIT_FAILURE);
}
Simple downscaling(A video capture device is assumed.)
&v4l2-cropcap; cropcap;
&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)) {
perror ("VIDIOC_S_FORMAT");
exit (EXIT_FAILURE);
}
/* We could check the actual image size now, the actual scaling factor
or if the driver can scale at all. */
Selecting an output area
&v4l2-cropcap; cropcap;
&v4l2-crop; crop;
memset (&cropcap, 0, sizeof (cropcap));
cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &cropcap)) {
perror ("VIDIOC_CROPCAP");
exit (EXIT_FAILURE);
}
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)
&& errno != EINVAL) {
perror ("VIDIOC_S_CROP");
exit (EXIT_FAILURE);
}
Current scaling factor and pixel aspect(A video capture device is assumed.)
&v4l2-cropcap; cropcap;
&v4l2-crop; crop;
&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)) {
perror ("VIDIOC_CROPCAP");
exit (EXIT_FAILURE);
}
memset (&crop, 0, sizeof (crop));
crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == ioctl (fd, &VIDIOC-G-CROP;, &crop)) {
if (errno != EINVAL) {
perror ("VIDIOC_G_CROP");
exit (EXIT_FAILURE);
}
/* Cropping not supported. */
crop.c = cropcap.defrect;
}
memset (&format, 0, sizeof (format));
format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == ioctl (fd, &VIDIOC-G-FMT;, &format)) {
perror ("VIDIOC_G_FMT");
exit (EXIT_FAILURE);
}
/* 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 /
(double) cropcap.pixelaspect.denominator;
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;
Streaming ParametersStreaming parameters are intended to optimize the video
capture process as well as I/O. Presently applications can request a
high quality capture mode with the &VIDIOC-S-PARM; ioctl.The current video standard determines a nominal number of
frames per second. If less than this number of frames is to be
captured or output, applications can request frame skipping or
duplicating on the driver side. This is especially useful when using
the &func-read; or &func-write;, which are not augmented by timestamps
or sequence counters, and to avoid unneccessary data copying.Finally these ioctls can be used to determine the number of
buffers used internally by a driver in read/write mode. For
implications see the section discussing the &func-read;
function.To get and set the streaming parameters applications call
the &VIDIOC-G-PARM; and &VIDIOC-S-PARM; ioctl, respectively. They take
a pointer to a &v4l2-streamparm;, which contains a union holding
separate parameters for input and output devices.These ioctls are optional, drivers need not implement
them. If so, they return the &EINVAL;.