Commit 333c8b97 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] v4l: v4l2_subdev userspace format API

Add a userspace API to get, set and enumerate the media format on a
subdev pad.

The format at the output of a subdev usually depends on the format at
its input(s). The try format operation is thus not suitable for probing
format at individual pads, as it can't modify the device state and thus
can't remember the format tried at the input to compute the output
format.

To fix the problem, pass an extra argument to the get/set format
operations to select the 'try' or 'active' format.

The try format is used when probing the subdev. Setting the try format
must not change the device configuration but can store data for later
reuse. Data storage is provided at the file-handle level so applications
probing the subdev concurently won't interfere with each other.

The active format is used when configuring the subdev. It's identical to
the format handled by the usual get/set operations.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarStanimir Varbanov <svarbanov@mm-sol.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@iki.fi>
Acked-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent d3a7ed99
...@@ -53,7 +53,10 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS)) ...@@ -53,7 +53,10 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS))
mandocs: $(MAN) mandocs: $(MAN)
build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \ build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/ cp $(srctree)/Documentation/DocBook/dvb/*.png \
$(srctree)/Documentation/DocBook/v4l/*.gif \
$(srctree)/Documentation/DocBook/v4l/*.png \
$(objtree)/Documentation/DocBook/media/
xmldoclinks: xmldoclinks:
ifneq ($(objtree),$(srctree)) ifneq ($(objtree),$(srctree))
......
...@@ -86,6 +86,10 @@ ...@@ -86,6 +86,10 @@
<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>"> <!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>"> <!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>"> <!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
<!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>">
<!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>">
<!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>">
<!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>"> <!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>"> <!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>"> <!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
...@@ -107,6 +111,7 @@ ...@@ -107,6 +111,7 @@
<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>"> <!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>"> <!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>"> <!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
<!ENTITY v4l2-mbus-pixelcode "enum&nbsp;<link linkend='v4l2-mbus-pixelcode'>v4l2_mbus_pixelcode</link>">
<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>"> <!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>"> <!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>"> <!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
...@@ -130,6 +135,7 @@ ...@@ -130,6 +135,7 @@
<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>"> <!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>"> <!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>"> <!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
<!ENTITY v4l2-subdev-format-whence "enum&nbsp;<link linkend='v4l2-subdev-format-whence'>v4l2_subdev_format_whence</link>">
<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>"> <!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>"> <!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
...@@ -172,6 +178,7 @@ ...@@ -172,6 +178,7 @@
<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>"> <!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>"> <!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>"> <!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
<!ENTITY v4l2-mbus-framefmt "struct&nbsp;<link linkend='v4l2-mbus-framefmt'>v4l2_mbus_framefmt</link>">
<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>"> <!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>"> <!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>"> <!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
...@@ -186,6 +193,9 @@ ...@@ -186,6 +193,9 @@
<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>"> <!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>"> <!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>"> <!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
<!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>">
<!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>">
<!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>">
<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>"> <!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>"> <!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>"> <!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
...@@ -215,6 +225,7 @@ ...@@ -215,6 +225,7 @@
<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code"> <!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code"> <!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code"> <!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
<!ENTITY EPIPE "<errorcode>EPIPE</errorcode> error code">
<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code"> <!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
<!-- Subsections --> <!-- Subsections -->
...@@ -234,6 +245,7 @@ ...@@ -234,6 +245,7 @@
<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml"> <!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml"> <!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml"> <!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
<!ENTITY sub-dev-subdev SYSTEM "v4l/dev-subdev.xml">
<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml"> <!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
<!ENTITY sub-driver SYSTEM "v4l/driver.xml"> <!ENTITY sub-driver SYSTEM "v4l/driver.xml">
<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml"> <!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
...@@ -319,6 +331,10 @@ ...@@ -319,6 +331,10 @@
<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> <!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> <!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml"> <!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
<!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml">
<!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml">
<!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml">
<!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml">
<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml"> <!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml"> <!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> <!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
......
This diff is collapsed.
This diff is collapsed.
...@@ -439,6 +439,7 @@ and discussions on the V4L mailing list.</revremark> ...@@ -439,6 +439,7 @@ and discussions on the V4L mailing list.</revremark>
<section id="radio"> &sub-dev-radio; </section> <section id="radio"> &sub-dev-radio; </section>
<section id="rds"> &sub-dev-rds; </section> <section id="rds"> &sub-dev-rds; </section>
<section id="event"> &sub-dev-event; </section> <section id="event"> &sub-dev-event; </section>
<section id="subdev"> &sub-dev-subdev; </section>
</chapter> </chapter>
<chapter id="driver"> <chapter id="driver">
...@@ -506,6 +507,9 @@ and discussions on the V4L mailing list.</revremark> ...@@ -506,6 +507,9 @@ and discussions on the V4L mailing list.</revremark>
&sub-reqbufs; &sub-reqbufs;
&sub-s-hw-freq-seek; &sub-s-hw-freq-seek;
&sub-streamon; &sub-streamon;
&sub-subdev-enum-frame-size;
&sub-subdev-enum-mbus-code;
&sub-subdev-g-fmt;
&sub-subscribe-event; &sub-subscribe-event;
<!-- End of ioctls. --> <!-- End of ioctls. -->
&sub-mmap; &sub-mmap;
......
...@@ -93,6 +93,15 @@ synchronize with other events.</para> ...@@ -93,6 +93,15 @@ synchronize with other events.</para>
been allocated (memory mapping) or enqueued (output) yet.</para> been allocated (memory mapping) or enqueued (output) yet.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><errorcode>EPIPE</errorcode></term>
<listitem>
<para>The driver implements <link
linkend="pad-level-formats">pad-level format configuration</link> and
the pipeline configuration is invalid.
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
</refentry> </refentry>
......
<refentry id="vidioc-subdev-enum-frame-size">
<refmeta>
<refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refname>
<refpurpose>Enumerate media bus frame sizes</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_subdev_frame_size_enum *
<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<note>
<title>Experimental</title>
<para>This is an <link linkend="experimental">experimental</link>
interface and may change in the future.</para>
</note>
<para>This ioctl allows applications to enumerate all frame sizes
supported by a sub-device on the given pad for the given media bus format.
Supported formats can be retrieved with the &VIDIOC-SUBDEV-ENUM-MBUS-CODE;
ioctl.</para>
<para>To enumerate frame sizes applications initialize the
<structfield>pad</structfield>, <structfield>code</structfield> and
<structfield>index</structfield> fields of the
&v4l2-subdev-mbus-code-enum; and call the
<constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
the structure. Drivers fill the minimum and maximum frame sizes or return
an &EINVAL; if one of the input parameters is invalid.</para>
<para>Sub-devices that only support discrete frame sizes (such as most
sensors) will return one or more frame sizes with identical minimum and
maximum values.</para>
<para>Not all possible sizes in given [minimum, maximum] ranges need to be
supported. For instance, a scaler that uses a fixed-point scaling ratio
might not be able to produce every frame size between the minimum and
maximum values. Applications must use the &VIDIOC-SUBDEV-S-FMT; ioctl to
try the sub-device for an exact supported frame size.</para>
<para>Available frame sizes may depend on the current 'try' formats at other
pads of the sub-device, as well as on the current active links and the
current values of V4L2 controls. See &VIDIOC-SUBDEV-G-FMT; for more
information about try formats.</para>
<table pgwide="1" frame="none" id="v4l2-subdev-frame-size-enum">
<title>struct <structname>v4l2_subdev_frame_size_enum</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>index</structfield></entry>
<entry>Number of the format in the enumeration, set by the
application.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>pad</structfield></entry>
<entry>Pad number as reported by the media controller API.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>code</structfield></entry>
<entry>The media bus format code, as defined in
<xref linkend="v4l2-mbus-format" />.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>min_width</structfield></entry>
<entry>Minimum frame width, in pixels.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>max_width</structfield></entry>
<entry>Maximum frame width, in pixels.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>min_height</structfield></entry>
<entry>Minimum frame height, in pixels.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>max_height</structfield></entry>
<entry>Maximum frame height, in pixels.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[9]</entry>
<entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-subdev-frame-size-enum; <structfield>pad</structfield>
references a non-existing pad, the <structfield>code</structfield> is
invalid for the given pad or the <structfield>index</structfield>
field is out of bounds.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
<refentry id="vidioc-subdev-enum-mbus-code">
<refmeta>
<refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_SUBDEV_ENUM_MBUS_CODE</refname>
<refpurpose>Enumerate media bus formats</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_subdev_mbus_code_enum *
<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_SUBDEV_ENUM_MBUS_CODE</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<note>
<title>Experimental</title>
<para>This is an <link linkend="experimental">experimental</link>
interface and may change in the future.</para>
</note>
<para>To enumerate media bus formats available at a given sub-device pad
applications initialize the <structfield>pad</structfield> and
<structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
pointer to this structure. Drivers fill the rest of the structure or return
an &EINVAL; if either the <structfield>pad</structfield> or
<structfield>index</structfield> are invalid. All media bus formats are
enumerable by beginning at index zero and incrementing by one until
<errorcode>EINVAL</errorcode> is returned.</para>
<para>Available media bus formats may depend on the current 'try' formats
at other pads of the sub-device, as well as on the current active links. See
&VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
<table pgwide="1" frame="none" id="v4l2-subdev-mbus-code-enum">
<title>struct <structname>v4l2_subdev_mbus_code_enum</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>pad</structfield></entry>
<entry>Pad number as reported by the media controller API.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>index</structfield></entry>
<entry>Number of the format in the enumeration, set by the
application.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>code</structfield></entry>
<entry>The media bus format code, as defined in
<xref linkend="v4l2-mbus-format" />.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[9]</entry>
<entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-subdev-mbus-code-enum; <structfield>pad</structfield>
references a non-existing pad, or the <structfield>index</structfield>
field is out of bounds.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
<refentry id="vidioc-subdev-g-fmt">
<refmeta>
<refentrytitle>ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_SUBDEV_G_FMT</refname>
<refname>VIDIOC_SUBDEV_S_FMT</refname>
<refpurpose>Get or set the data format on a subdev pad</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_subdev_format *<parameter>argp</parameter>
</paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<note>
<title>Experimental</title>
<para>This is an <link linkend="experimental">experimental</link>
interface and may change in the future.</para>
</note>
<para>These ioctls are used to negotiate the frame format at specific
subdev pads in the image pipeline.</para>
<para>To retrieve the current format applications set the
<structfield>pad</structfield> field of a &v4l2-subdev-format; to the
desired pad number as reported by the media API and the
<structfield>which</structfield> field to
<constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. When they call the
<constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl with a pointer to this
structure the driver fills the members of the <structfield>format</structfield>
field.</para>
<para>To change the current format applications set both the
<structfield>pad</structfield> and <structfield>which</structfield> fields
and all members of the <structfield>format</structfield> field. When they
call the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl with a pointer to this
structure the driver verifies the requested format, adjusts it based on the
hardware capabilities and configures the device. Upon return the
&v4l2-subdev-format; contains the current format as would be returned by a
<constant>VIDIOC_SUBDEV_G_FMT</constant> call.</para>
<para>Applications can query the device capabilities by setting the
<structfield>which</structfield> to
<constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' formats are not
applied to the device by the driver, but are changed exactly as active
formats and stored in the sub-device file handle. Two applications querying
the same sub-device would thus not interact with each other.</para>
<para>For instance, to try a format at the output pad of a sub-device,
applications would first set the try format at the sub-device input with the
<constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl. They would then either
retrieve the default format at the output pad with the
<constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl, or set the desired output
pad format with the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl and check
the returned value.</para>
<para>Try formats do not depend on active formats, but can depend on the
current links configuration or sub-device controls value. For instance, a
low-pass noise filter might crop pixels at the frame boundaries, modifying
its output frame size.</para>
<para>Drivers must not return an error solely because the requested format
doesn't match the device capabilities. They must instead modify the format
to match what the hardware can provide. The modified format should be as
close as possible to the original request.</para>
<table pgwide="1" frame="none" id="v4l2-subdev-format">
<title>struct <structname>v4l2_subdev_format</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>pad</structfield></entry>
<entry>Pad number as reported by the media controller API.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>which</structfield></entry>
<entry>Format to modified, from &v4l2-subdev-format-whence;.</entry>
</row>
<row>
<entry>&v4l2-mbus-framefmt;</entry>
<entry><structfield>format</structfield></entry>
<entry>Definition of an image format, see <xref
linkend="v4l2-mbus-framefmt" /> for details.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[8]</entry>
<entry>Reserved for future extensions. Applications and drivers must
set the array to zero.</entry>
</row>
</tbody>
</tgroup>
</table>
<table pgwide="1" frame="none" id="v4l2-subdev-format-whence">
<title>enum <structname>v4l2_subdev_format_whence</structname></title>
<tgroup cols="3">
&cs-def;
<tbody valign="top">
<row>
<entry>V4L2_SUBDEV_FORMAT_TRY</entry>
<entry>0</entry>
<entry>Try formats, used for querying device capabilities.</entry>
</row>
<row>
<entry>V4L2_SUBDEV_FORMAT_ACTIVE</entry>
<entry>1</entry>
<entry>Active formats, applied to the hardware.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EBUSY</errorcode></term>
<listitem>
<para>The format can't be changed because the pad is currently busy.
This can be caused, for instance, by an active video stream on the
pad. The ioctl must not be retried without performing another action
to fix the problem first. Only returned by
<constant>VIDIOC_SUBDEV_S_FMT</constant></para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The &v4l2-subdev-format; <structfield>pad</structfield>
references a non-existing pad, or the <structfield>which</structfield>
field references a non-existing format.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
...@@ -149,6 +149,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -149,6 +149,9 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
struct video_device *vdev = video_devdata(file); struct video_device *vdev = video_devdata(file);
struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev); struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
struct v4l2_fh *vfh = file->private_data; struct v4l2_fh *vfh = file->private_data;
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
#endif
switch (cmd) { switch (cmd) {
case VIDIOC_QUERYCTRL: case VIDIOC_QUERYCTRL:
...@@ -183,7 +186,53 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) ...@@ -183,7 +186,53 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_UNSUBSCRIBE_EVENT: case VIDIOC_UNSUBSCRIBE_EVENT:
return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg); return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
case VIDIOC_SUBDEV_G_FMT: {
struct v4l2_subdev_format *format = arg;
if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (format->pad >= sd->entity.num_pads)
return -EINVAL;
return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
}
case VIDIOC_SUBDEV_S_FMT: {
struct v4l2_subdev_format *format = arg;
if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
return -EINVAL;
if (format->pad >= sd->entity.num_pads)
return -EINVAL;
return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
}
case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
struct v4l2_subdev_mbus_code_enum *code = arg;
if (code->pad >= sd->entity.num_pads)
return -EINVAL;
return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh,
code);
}
case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {
struct v4l2_subdev_frame_size_enum *fse = arg;
if (fse->pad >= sd->entity.num_pads)
return -EINVAL;
return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh,
fse);
}
#endif
default: default:
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
......
...@@ -372,6 +372,7 @@ header-y += usbdevice_fs.h ...@@ -372,6 +372,7 @@ header-y += usbdevice_fs.h
header-y += utime.h header-y += utime.h
header-y += utsname.h header-y += utsname.h
header-y += v4l2-mediabus.h header-y += v4l2-mediabus.h
header-y += v4l2-subdev.h
header-y += veth.h header-y += veth.h
header-y += vhost.h header-y += vhost.h
header-y += videodev2.h header-y += videodev2.h
......
/*
* V4L2 subdev userspace API
*
* Copyright (C) 2010 Nokia Corporation
*
* Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
* Sakari Ailus <sakari.ailus@iki.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LINUX_V4L2_SUBDEV_H
#define __LINUX_V4L2_SUBDEV_H
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/v4l2-mediabus.h>
/**
* enum v4l2_subdev_format_whence - Media bus format type
* @V4L2_SUBDEV_FORMAT_TRY: try format, for negotiation only
* @V4L2_SUBDEV_FORMAT_ACTIVE: active format, applied to the device
*/
enum v4l2_subdev_format_whence {
V4L2_SUBDEV_FORMAT_TRY = 0,
V4L2_SUBDEV_FORMAT_ACTIVE = 1,
};
/**
* struct v4l2_subdev_format - Pad-level media bus format
* @which: format type (from enum v4l2_subdev_format_whence)
* @pad: pad number, as reported by the media API
* @format: media bus format (format code and frame size)
*/
struct v4l2_subdev_format {
__u32 which;
__u32 pad;
struct v4l2_mbus_framefmt format;
__u32 reserved[8];
};
/**
* struct v4l2_subdev_mbus_code_enum - Media bus format enumeration
* @pad: pad number, as reported by the media API
* @index: format index during enumeration
* @code: format code (from enum v4l2_mbus_pixelcode)
*/
struct v4l2_subdev_mbus_code_enum {
__u32 pad;
__u32 index;
__u32 code;
__u32 reserved[9];
};
/**
* struct v4l2_subdev_frame_size_enum - Media bus format enumeration
* @pad: pad number, as reported by the media API
* @index: format index during enumeration
* @code: format code (from enum v4l2_mbus_pixelcode)
*/
struct v4l2_subdev_frame_size_enum {
__u32 index;
__u32 pad;
__u32 code;
__u32 min_width;
__u32 max_width;
__u32 min_height;
__u32 max_height;
__u32 reserved[9];
};
#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
#define VIDIOC_SUBDEV_ENUM_MBUS_CODE \
_IOWR('V', 2, struct v4l2_subdev_mbus_code_enum)
#define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \
_IOWR('V', 74, struct v4l2_subdev_frame_size_enum)
#endif
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#ifndef _V4L2_SUBDEV_H #ifndef _V4L2_SUBDEV_H
#define _V4L2_SUBDEV_H #define _V4L2_SUBDEV_H
#include <linux/v4l2-subdev.h>
#include <media/media-entity.h> #include <media/media-entity.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-dev.h> #include <media/v4l2-dev.h>
...@@ -414,6 +415,15 @@ struct v4l2_subdev_ir_ops { ...@@ -414,6 +415,15 @@ struct v4l2_subdev_ir_ops {
}; };
struct v4l2_subdev_pad_ops { struct v4l2_subdev_pad_ops {
int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_mbus_code_enum *code);
int (*enum_frame_size)(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh,
struct v4l2_subdev_frame_size_enum *fse);
int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_format *format);
int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
struct v4l2_subdev_format *format);
}; };
struct v4l2_subdev_ops { struct v4l2_subdev_ops {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment