|
@@ -0,0 +1,321 @@
|
|
|
+<section id="selection-api">
|
|
|
+
|
|
|
+ <title>Experimental API for cropping, composing and scaling</title>
|
|
|
+
|
|
|
+ <note>
|
|
|
+ <title>Experimental</title>
|
|
|
+
|
|
|
+ <para>This is an <link linkend="experimental">experimental</link>
|
|
|
+interface and may change in the future.</para>
|
|
|
+ </note>
|
|
|
+
|
|
|
+ <section>
|
|
|
+ <title>Introduction</title>
|
|
|
+
|
|
|
+<para>Some video capture devices can sample a subsection of a picture and
|
|
|
+shrink or enlarge it to an image of arbitrary size. Next, the devices can
|
|
|
+insert the image into larger one. Some video output devices can crop part of an
|
|
|
+input image, scale it up or down and insert it at an arbitrary scan line and
|
|
|
+horizontal offset into a video signal. We call these abilities cropping,
|
|
|
+scaling and composing.</para>
|
|
|
+
|
|
|
+<para>On a video <emphasis>capture</emphasis> device the source is a video
|
|
|
+signal, and the cropping target determine the area actually sampled. The sink
|
|
|
+is an image stored in a memory buffer. The composing area specifies which part
|
|
|
+of the buffer is actually written to by the hardware. </para>
|
|
|
+
|
|
|
+<para>On a video <emphasis>output</emphasis> device the source is an image in a
|
|
|
+memory buffer, and the cropping target is a part of an image to be shown on a
|
|
|
+display. The sink is the display or the graphics screen. The application may
|
|
|
+select the part of display where the image should be displayed. The size and
|
|
|
+position of such a window is controlled by the compose target.</para>
|
|
|
+
|
|
|
+<para>Rectangles for all cropping and composing targets are defined even if the
|
|
|
+device does supports neither cropping nor composing. Their size and position
|
|
|
+will be fixed in such a case. If the device does not support scaling then the
|
|
|
+cropping and composing rectangles have the same size.</para>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section>
|
|
|
+ <title>Selection targets</title>
|
|
|
+
|
|
|
+ <figure id="sel-targets-capture">
|
|
|
+ <title>Cropping and composing targets</title>
|
|
|
+ <mediaobject>
|
|
|
+ <imageobject>
|
|
|
+ <imagedata fileref="selection.png" format="PNG" />
|
|
|
+ </imageobject>
|
|
|
+ <textobject>
|
|
|
+ <phrase>Targets used by a cropping, composing and scaling
|
|
|
+ process</phrase>
|
|
|
+ </textobject>
|
|
|
+ </mediaobject>
|
|
|
+ </figure>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section>
|
|
|
+
|
|
|
+ <title>Configuration</title>
|
|
|
+
|
|
|
+<para>Applications can use the <link linkend="vidioc-g-selection">selection
|
|
|
+API</link> to select an area in a video signal or a buffer, and to query for
|
|
|
+default settings and hardware limits.</para>
|
|
|
+
|
|
|
+<para>Video hardware can have various cropping, composing and scaling
|
|
|
+limitations. It may only scale up or down, support only discrete scaling
|
|
|
+factors, or have different scaling abilities in the horizontal and vertical
|
|
|
+directions. Also it may not support scaling at all. At the same time the
|
|
|
+cropping/composing rectangles may have to be aligned, and both the source and
|
|
|
+the sink may have arbitrary upper and lower size limits. Therefore, as usual,
|
|
|
+drivers are expected to adjust the requested parameters and return the actual
|
|
|
+values selected. An application can control the rounding behaviour using <link
|
|
|
+linkend="v4l2-sel-flags"> constraint flags </link>.</para>
|
|
|
+
|
|
|
+ <section>
|
|
|
+
|
|
|
+ <title>Configuration of video capture</title>
|
|
|
+
|
|
|
+<para>See figure <xref linkend="sel-targets-capture" /> for examples of the
|
|
|
+selection targets available for a video capture device. It is recommended to
|
|
|
+configure the cropping targets before to the composing targets.</para>
|
|
|
+
|
|
|
+<para>The range of coordinates of the top left corner, width and height of
|
|
|
+areas that can be sampled is given by the <constant> V4L2_SEL_TGT_CROP_BOUNDS
|
|
|
+</constant> target. It is recommended for the driver developers to put the
|
|
|
+top/left corner at position <constant> (0,0) </constant>. The rectangle's
|
|
|
+coordinates are expressed in pixels.</para>
|
|
|
+
|
|
|
+<para>The top left corner, width and height of the source rectangle, that is
|
|
|
+the area actually sampled, is given by the <constant> V4L2_SEL_TGT_CROP_ACTIVE
|
|
|
+</constant> target. It uses the same coordinate system as <constant>
|
|
|
+V4L2_SEL_TGT_CROP_BOUNDS </constant>. The active cropping area must lie
|
|
|
+completely inside the capture boundaries. The driver may further adjust the
|
|
|
+requested size and/or position according to hardware limitations.</para>
|
|
|
+
|
|
|
+<para>Each capture device has a default source rectangle, given by the
|
|
|
+<constant> V4L2_SEL_TGT_CROP_DEFAULT </constant> target. This rectangle shall
|
|
|
+over what the driver writer considers the complete picture. Drivers shall set
|
|
|
+the active crop rectangle to the default when the driver is first loaded, but
|
|
|
+not later.</para>
|
|
|
+
|
|
|
+<para>The composing targets refer to a memory buffer. The limits of composing
|
|
|
+coordinates are obtained using <constant> V4L2_SEL_TGT_COMPOSE_BOUNDS
|
|
|
+</constant>. All coordinates are expressed in pixels. The rectangle's top/left
|
|
|
+corner must be located at position <constant> (0,0) </constant>. The width and
|
|
|
+height are equal to the image size set by <constant> VIDIOC_S_FMT </constant>.
|
|
|
+</para>
|
|
|
+
|
|
|
+<para>The part of a buffer into which the image is inserted by the hardware is
|
|
|
+controlled by the <constant> V4L2_SEL_TGT_COMPOSE_ACTIVE </constant> target.
|
|
|
+The rectangle's coordinates are also expressed in the same coordinate system as
|
|
|
+the bounds rectangle. The composing rectangle must lie completely inside bounds
|
|
|
+rectangle. The driver must adjust the composing rectangle to fit to the
|
|
|
+bounding limits. Moreover, the driver can perform other adjustments according
|
|
|
+to hardware limitations. The application can control rounding behaviour using
|
|
|
+<link linkend="v4l2-sel-flags"> constraint flags </link>.</para>
|
|
|
+
|
|
|
+<para>For capture devices the default composing rectangle is queried using
|
|
|
+<constant> V4L2_SEL_TGT_COMPOSE_DEFAULT </constant>. It is usually equal to the
|
|
|
+bounding rectangle.</para>
|
|
|
+
|
|
|
+<para>The part of a buffer that is modified by the hardware is given by
|
|
|
+<constant> V4L2_SEL_TGT_COMPOSE_PADDED </constant>. It contains all pixels
|
|
|
+defined using <constant> V4L2_SEL_TGT_COMPOSE_ACTIVE </constant> plus all
|
|
|
+padding data modified by hardware during insertion process. All pixels outside
|
|
|
+this rectangle <emphasis>must not</emphasis> be changed by the hardware. The
|
|
|
+content of pixels that lie inside the padded area but outside active area is
|
|
|
+undefined. The application can use the padded and active rectangles to detect
|
|
|
+where the rubbish pixels are located and remove them if needed.</para>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section>
|
|
|
+
|
|
|
+ <title>Configuration of video output</title>
|
|
|
+
|
|
|
+<para>For output devices targets and ioctls are used similarly to the video
|
|
|
+capture case. The <emphasis> composing </emphasis> rectangle refers to the
|
|
|
+insertion of an image into a video signal. The cropping rectangles refer to a
|
|
|
+memory buffer. It is recommended to configure the composing targets before to
|
|
|
+the cropping targets.</para>
|
|
|
+
|
|
|
+<para>The cropping targets refer to the memory buffer that contains an image to
|
|
|
+be inserted into a video signal or graphical screen. The limits of cropping
|
|
|
+coordinates are obtained using <constant> V4L2_SEL_TGT_CROP_BOUNDS </constant>.
|
|
|
+All coordinates are expressed in pixels. The top/left corner is always point
|
|
|
+<constant> (0,0) </constant>. The width and height is equal to the image size
|
|
|
+specified using <constant> VIDIOC_S_FMT </constant> ioctl.</para>
|
|
|
+
|
|
|
+<para>The top left corner, width and height of the source rectangle, that is
|
|
|
+the area from which image date are processed by the hardware, is given by the
|
|
|
+<constant> V4L2_SEL_TGT_CROP_ACTIVE </constant>. Its coordinates are expressed
|
|
|
+in in the same coordinate system as the bounds rectangle. The active cropping
|
|
|
+area must lie completely inside the crop boundaries and the driver may further
|
|
|
+adjust the requested size and/or position according to hardware
|
|
|
+limitations.</para>
|
|
|
+
|
|
|
+<para>For output devices the default cropping rectangle is queried using
|
|
|
+<constant> V4L2_SEL_TGT_CROP_DEFAULT </constant>. It is usually equal to the
|
|
|
+bounding rectangle.</para>
|
|
|
+
|
|
|
+<para>The part of a video signal or graphics display where the image is
|
|
|
+inserted by the hardware is controlled by <constant>
|
|
|
+V4L2_SEL_TGT_COMPOSE_ACTIVE </constant> target. The rectangle's coordinates
|
|
|
+are expressed in pixels. The composing rectangle must lie completely inside the
|
|
|
+bounds rectangle. The driver must adjust the area to fit to the bounding
|
|
|
+limits. Moreover, the driver can perform other adjustments according to
|
|
|
+hardware limitations. </para>
|
|
|
+
|
|
|
+<para>The device has a default composing rectangle, given by the <constant>
|
|
|
+V4L2_SEL_TGT_COMPOSE_DEFAULT </constant> target. This rectangle shall cover what
|
|
|
+the driver writer considers the complete picture. It is recommended for the
|
|
|
+driver developers to put the top/left corner at position <constant> (0,0)
|
|
|
+</constant>. Drivers shall set the active composing rectangle to the default
|
|
|
+one when the driver is first loaded.</para>
|
|
|
+
|
|
|
+<para>The devices may introduce additional content to video signal other than
|
|
|
+an image from memory buffers. It includes borders around an image. However,
|
|
|
+such a padded area is driver-dependent feature not covered by this document.
|
|
|
+Driver developers are encouraged to keep padded rectangle equal to active one.
|
|
|
+The padded target is accessed by the <constant> V4L2_SEL_TGT_COMPOSE_PADDED
|
|
|
+</constant> identifier. It must contain all pixels from the <constant>
|
|
|
+V4L2_SEL_TGT_COMPOSE_ACTIVE </constant> target.</para>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section>
|
|
|
+
|
|
|
+ <title>Scaling control.</title>
|
|
|
+
|
|
|
+<para>An application can detect if scaling is performed by comparing the width
|
|
|
+and the height of rectangles obtained using <constant> V4L2_SEL_TGT_CROP_ACTIVE
|
|
|
+</constant> and <constant> V4L2_SEL_TGT_COMPOSE_ACTIVE </constant> targets. If
|
|
|
+these are not equal then the scaling is applied. The application can compute
|
|
|
+the scaling ratios using these values.</para>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section>
|
|
|
+
|
|
|
+ <title>Comparison with old cropping API.</title>
|
|
|
+
|
|
|
+<para>The selection API was introduced to cope with deficiencies of previous
|
|
|
+<link linkend="crop"> API </link>, that was designed to control simple capture
|
|
|
+devices. Later the cropping API was adopted by video output drivers. The ioctls
|
|
|
+are used to select a part of the display were the video signal is inserted. It
|
|
|
+should be considered as an API abuse because the described operation is
|
|
|
+actually the composing. The selection API makes a clear distinction between
|
|
|
+composing and cropping operations by setting the appropriate targets. The V4L2
|
|
|
+API lacks any support for composing to and cropping from an image inside a
|
|
|
+memory buffer. The application could configure a capture device to fill only a
|
|
|
+part of an image by abusing V4L2 API. Cropping a smaller image from a larger
|
|
|
+one is achieved by setting the field <structfield>
|
|
|
+&v4l2-pix-format;::bytesperline </structfield>. Introducing an image offsets
|
|
|
+could be done by modifying field <structfield> &v4l2-buffer;::m:userptr
|
|
|
+</structfield> before calling <constant> VIDIOC_QBUF </constant>. Those
|
|
|
+operations should be avoided because they are not portable (endianness), and do
|
|
|
+not work for macroblock and Bayer formats and mmap buffers. The selection API
|
|
|
+deals with configuration of buffer cropping/composing in a clear, intuitive and
|
|
|
+portable way. Next, with the selection API the concepts of the padded target
|
|
|
+and constraints flags are introduced. Finally, <structname> &v4l2-crop;
|
|
|
+</structname> and <structname> &v4l2-cropcap; </structname> have no reserved
|
|
|
+fields. Therefore there is no way to extend their functionality. The new
|
|
|
+<structname> &v4l2-selection; </structname> provides a lot of place for future
|
|
|
+extensions. Driver developers are encouraged to implement only selection API.
|
|
|
+The former cropping API would be simulated using the new one. </para>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section>
|
|
|
+ <title>Examples</title>
|
|
|
+ <example>
|
|
|
+ <title>Resetting the cropping parameters</title>
|
|
|
+
|
|
|
+ <para>(A video capture device is assumed; change <constant>
|
|
|
+V4L2_BUF_TYPE_VIDEO_CAPTURE </constant> for other devices; change target to
|
|
|
+<constant> V4L2_SEL_TGT_COMPOSE_* </constant> family to configure composing
|
|
|
+area)</para>
|
|
|
+
|
|
|
+ <programlisting>
|
|
|
+
|
|
|
+ &v4l2-selection; sel = {
|
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
|
+ .target = V4L2_SEL_TGT_CROP_DEFAULT,
|
|
|
+ };
|
|
|
+ ret = ioctl(fd, &VIDIOC-G-SELECTION;, &sel);
|
|
|
+ if (ret)
|
|
|
+ exit(-1);
|
|
|
+ sel.target = V4L2_SEL_TGT_CROP_ACTIVE;
|
|
|
+ ret = ioctl(fd, &VIDIOC-S-SELECTION;, &sel);
|
|
|
+ if (ret)
|
|
|
+ exit(-1);
|
|
|
+
|
|
|
+ </programlisting>
|
|
|
+ </example>
|
|
|
+
|
|
|
+ <example>
|
|
|
+ <title>Simple downscaling</title>
|
|
|
+ <para>Setting a composing area on output of size of <emphasis> at most
|
|
|
+</emphasis> half of limit placed at a center of a display.</para>
|
|
|
+ <programlisting>
|
|
|
+
|
|
|
+ &v4l2-selection; sel = {
|
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
|
|
+ .target = V4L2_SEL_TGT_COMPOSE_BOUNDS,
|
|
|
+ };
|
|
|
+ struct v4l2_rect r;
|
|
|
+
|
|
|
+ ret = ioctl(fd, &VIDIOC-G-SELECTION;, &sel);
|
|
|
+ if (ret)
|
|
|
+ exit(-1);
|
|
|
+ /* setting smaller compose rectangle */
|
|
|
+ r.width = sel.r.width / 2;
|
|
|
+ r.height = sel.r.height / 2;
|
|
|
+ r.left = sel.r.width / 4;
|
|
|
+ r.top = sel.r.height / 4;
|
|
|
+ sel.r = r;
|
|
|
+ sel.target = V4L2_SEL_TGT_COMPOSE_ACTIVE;
|
|
|
+ sel.flags = V4L2_SEL_FLAG_LE;
|
|
|
+ ret = ioctl(fd, &VIDIOC-S-SELECTION;, &sel);
|
|
|
+ if (ret)
|
|
|
+ exit(-1);
|
|
|
+
|
|
|
+ </programlisting>
|
|
|
+ </example>
|
|
|
+
|
|
|
+ <example>
|
|
|
+ <title>Querying for scaling factors</title>
|
|
|
+ <para>A video output device is assumed; change <constant>
|
|
|
+V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> for other devices</para>
|
|
|
+ <programlisting>
|
|
|
+
|
|
|
+ &v4l2-selection; compose = {
|
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
|
|
+ .target = V4L2_SEL_TGT_COMPOSE_ACTIVE,
|
|
|
+ };
|
|
|
+ &v4l2-selection; crop = {
|
|
|
+ .type = V4L2_BUF_TYPE_VIDEO_OUTPUT,
|
|
|
+ .target = V4L2_SEL_TGT_CROP_ACTIVE,
|
|
|
+ };
|
|
|
+ double hscale, vscale;
|
|
|
+
|
|
|
+ ret = ioctl(fd, &VIDIOC-G-SELECTION;, &compose);
|
|
|
+ if (ret)
|
|
|
+ exit(-1);
|
|
|
+ ret = ioctl(fd, &VIDIOC-G-SELECTION;, &crop);
|
|
|
+ if (ret)
|
|
|
+ exit(-1);
|
|
|
+
|
|
|
+ /* computing scaling factors */
|
|
|
+ hscale = (double)compose.r.width / crop.r.width;
|
|
|
+ vscale = (double)compose.r.height / crop.r.height;
|
|
|
+
|
|
|
+ </programlisting>
|
|
|
+ </example>
|
|
|
+
|
|
|
+ </section>
|
|
|
+
|
|
|
+</section>
|