Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35c3017a authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] v4l: v4l2_subdev userspace frame interval API



The three new ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL,
VIDIOC_SUBDEV_G_FRAME_INTERVAL and VIDIOC_SUBDEV_S_FRAME_INTERVAL can be
used to enumerate and configure a subdev's frame rate from userspace.

Two new video::g/s_frame_interval subdev operations are introduced to
support those ioctls. The existing video::g/s_parm operations are
deprecated and shouldn't be used anymore.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.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 333c8b97
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -89,7 +89,9 @@
<!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-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>">
<!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
<!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</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-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
@@ -193,6 +195,8 @@
<!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-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
<!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>">
<!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</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>">
@@ -331,10 +335,12 @@
<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.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-subdev-enum-frame-interval SYSTEM "v4l/vidioc-subdev-enum-frame-interval.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-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml">
<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
+2 −0
Original line number Diff line number Diff line
@@ -507,9 +507,11 @@ and discussions on the V4L mailing list.</revremark>
    &sub-reqbufs;
    &sub-s-hw-freq-seek;
    &sub-streamon;
    &sub-subdev-enum-frame-interval;
    &sub-subdev-enum-frame-size;
    &sub-subdev-enum-mbus-code;
    &sub-subdev-g-fmt;
    &sub-subdev-g-frame-interval;
    &sub-subscribe-event;
    <!-- End of ioctls. -->
    &sub-mmap;
+152 −0
Original line number Diff line number Diff line
<refentry id="vidioc-subdev-enum-frame-interval">
  <refmeta>
    <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refentrytitle>
    &manvol;
  </refmeta>

  <refnamediv>
    <refname>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refname>
    <refpurpose>Enumerate frame intervals</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_interval_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_INTERVAL</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 lets applications enumerate available frame intervals on a
    given sub-device pad. Frame intervals only makes sense for sub-devices that
    can control the frame period on their own. This includes, for instance,
    image sensors and TV tuners.</para>

    <para>For the common use case of image sensors, the frame intervals
    available on the sub-device output pad depend on the frame format and size
    on the same pad. Applications must thus specify the desired format and size
    when enumerating frame intervals.</para>

    <para>To enumerate frame intervals applications initialize the
    <structfield>index</structfield>, <structfield>pad</structfield>,
    <structfield>code</structfield>, <structfield>width</structfield> and
    <structfield>height</structfield> fields of
    &v4l2-subdev-frame-interval-enum; and call the
    <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
    to this structure. Drivers fill the rest of the structure or return
    an &EINVAL; if one of the input fields is invalid. All frame intervals are
    enumerable by beginning at index zero and incrementing by one until
    <errorcode>EINVAL</errorcode> is returned.</para>

    <para>Available frame intervals 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>

    <para>Sub-devices that support the frame interval enumeration ioctl should
    implemented it on a single pad only. Its behaviour when supported on
    multiple pads of the same sub-device is not defined.</para>

    <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval-enum">
      <title>struct <structname>v4l2_subdev_frame_interval_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>width</structfield></entry>
	    <entry>Frame width, in pixels.</entry>
	  </row>
	  <row>
	    <entry>__u32</entry>
	    <entry><structfield>height</structfield></entry>
	    <entry>Frame height, in pixels.</entry>
	  </row>
	  <row>
	    <entry>&v4l2-fract;</entry>
	    <entry><structfield>interval</structfield></entry>
	    <entry>Period, in seconds, between consecutive video frames.</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-interval-enum;
	  <structfield>pad</structfield> references a non-existing pad, one of
	  the <structfield>code</structfield>, <structfield>width</structfield>
	  or <structfield>height</structfield> fields are invalid for the given
	  pad or the <structfield>index</structfield> field is out of bounds.
	  </para>
	</listitem>
      </varlistentry>
    </variablelist>
  </refsect1>
</refentry>
+141 −0
Original line number Diff line number Diff line
<refentry id="vidioc-subdev-g-frame-interval">
  <refmeta>
    <refentrytitle>ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</refentrytitle>
    &manvol;
  </refmeta>

  <refnamediv>
    <refname>VIDIOC_SUBDEV_G_FRAME_INTERVAL</refname>
    <refname>VIDIOC_SUBDEV_S_FRAME_INTERVAL</refname>
    <refpurpose>Get or set the frame interval 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_frame_interval *<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_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</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 get and set the frame interval at specific
    subdev pads in the image pipeline. The frame interval only makes sense for
    sub-devices that can control the frame period on their own. This includes,
    for instance, image sensors and TV tuners. Sub-devices that don't support
    frame intervals must not implement these ioctls.</para>

    <para>To retrieve the current frame interval applications set the
    <structfield>pad</structfield> field of a &v4l2-subdev-frame-interval; to
    the desired pad number as reported by the media controller API. When they
    call the <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> ioctl with a
    pointer to this structure the driver fills the members of the
    <structfield>interval</structfield> field.</para>

    <para>To change the current frame interval applications set both the
    <structfield>pad</structfield> field and all members of the
    <structfield>interval</structfield> field. When they call the
    <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant> ioctl with a pointer to
    this structure the driver verifies the requested interval, adjusts it based
    on the hardware capabilities and configures the device. Upon return the
    &v4l2-subdev-frame-interval; contains the current frame interval as would be
    returned by a <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> call.
    </para>

    <para>Drivers must not return an error solely because the requested interval
    doesn't match the device capabilities. They must instead modify the interval
    to match what the hardware can provide. The modified interval should be as
    close as possible to the original request.</para>

    <para>Sub-devices that support the frame interval ioctls should implement
    them on a single pad only. Their behaviour when supported on multiple pads
    of the same sub-device is not defined.</para>

    <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval">
      <title>struct <structname>v4l2_subdev_frame_interval</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>&v4l2-fract;</entry>
	    <entry><structfield>interval</structfield></entry>
	    <entry>Period, in seconds, between consecutive video frames.</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>EBUSY</errorcode></term>
	<listitem>
	  <para>The frame interval 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_FRAME_INTERVAL</constant></para>
	</listitem>
      </varlistentry>
      <varlistentry>
	<term><errorcode>EINVAL</errorcode></term>
	<listitem>
	  <para>The &v4l2-subdev-frame-interval; <structfield>pad</structfield>
	  references a non-existing pad, or the pad doesn't support frame
	  intervals.</para>
	</listitem>
      </varlistentry>
    </variablelist>
  </refsect1>
</refentry>
+16 −0
Original line number Diff line number Diff line
@@ -232,6 +232,22 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
		return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh,
					fse);
	}

	case VIDIOC_SUBDEV_G_FRAME_INTERVAL:
		return v4l2_subdev_call(sd, video, g_frame_interval, arg);

	case VIDIOC_SUBDEV_S_FRAME_INTERVAL:
		return v4l2_subdev_call(sd, video, s_frame_interval, arg);

	case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {
		struct v4l2_subdev_frame_interval_enum *fie = arg;

		if (fie->pad >= sd->entity.num_pads)
			return -EINVAL;

		return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
					fie);
	}
#endif
	default:
		return -ENOIOCTLCMD;
Loading