Re: [PATCH v3] V4L: add two new ioctl()s for multi-size videobuffer management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Jul 27, 2011 at 09:11:38PM -0700, Pawel Osciak wrote:
> Hi Guennadi,

Hi Pawel,

> On Wed, Jul 20, 2011 at 01:43, Guennadi Liakhovetski
> <g.liakhovetski@xxxxxx> wrote:
> > A possibility to preallocate and initialise buffers of different sizes
> > in V4L2 is required for an efficient implementation of asnapshot mode.
> > This patch adds two new ioctl()s: VIDIOC_CREATE_BUFS and
> > VIDIOC_PREPARE_BUF and defines respective data structures.
> >
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@xxxxxx>
> > ---
> >
> <snip>
> 
> This looks nicer, I like how we got rid of destroy and gave up on
> making holes, it would've given us a lot of headaches. I'm thinking
> about some issues though and also have some comments/questions further
> below.

Holes could be re-introduced by defining DESTROY_BUFS. But it would be up to
the application to use it or not.

> Already mentioned by others mixing of REQBUFS and CREATE_BUFS.
> Personally I'd like to allow mixing, including REQBUFS for non-zero,
> because I think it would be easy to do. I think it could work in the
> same way as REQBUFS for !=0 works currently (at least in vb2), if we
> already have some buffers allocated and they are not in use, we free
> them and a new set is allocated. So I guess it could just stay this
> way. REQBUFS(0) would of course free everything.
> 
> Passing format to CREATE_BUFS will make vb2 a bit format-aware, as it
> would have to pass it forward to the driver somehow. The obvious way
> would be just vb2 calling the driver's s_fmt handler, but that won't
> work, as you can't pass indexes to s_fmt. So we'd have to implement a
> new driver callback for setting formats per index. I guess there is no
> way around it, unless we actually take the format struct out of
> CREATE_BUFS and somehow do it via S_FMT. The single-planar structure
> is full already though, the only way would be to use
> v4l2_pix_format_mplane instead with plane count = 1 (or more if
> needed).

I've been pondering a while an idea to change v4l2_format. None of the
structures in the union use the full size of it. This would allow adding
fields to the end of the union and reduce its size accordingly. No-one would
be harmed in the process, struct v4l2_format would just change slightly.

Guennadi might have thought this in the past but at least I misunderstood it
at the time. :-)

> Another thing is the case of passing size to CREATE_BUFS. vb2, when
> allocating buffers, gets their sizes from the driver (via
> queue_setup), it never "suggest" any particular size. So that flow
> would have to be changed as well. I guess vb2 could pass the size to
> queue_setup in a similar way as it does with buffer count. This would
> mean though that the ioctl would fail if the driver didn't agree to
> the given size. Right now I don't see an option to "negotiate" the
> size with the driver via this option.
> 
> The more I think of it though, why do we need the size argument? It's
> not needed in the existing flows (that use S_FMT) and, more
> importantly, I don't think the application can know more than the
> driver can, so why giving that option? The driver should know the size
> for a format at least as well as the application... Also, is there a
> real use case of providing just size, will the driver know which
> format to use given a size?
> 
> 
> > +    <para>To allocate device buffers applications initialize all
> > +fields of the <structname>v4l2_create_buffers</structname> structure.
> > +They set the <structfield>type</structfield> field in the
> > +<structname>v4l2_format</structname> structure, embedded in this
> > +structure, to the respective stream or buffer type.
> > +<structfield>count</structfield> must be set to the number of required
> > +buffers. <structfield>memory</structfield> specifies the required I/O
> > +method. Applications have two possibilities to specify the size of buffers
> > +to be prepared: they can either set the <structfield>size</structfield>
> > +field explicitly to a non-zero value, or fill in the frame format data in the
> > +<structfield>format</structfield> field. In the latter case buffer sizes
> > +will be calculated automatically by the driver. The
> 
> Technically, we shouldn't say "applications initialize all fields" in
> the first sentence if they do not have to initialize both size and
> format fields at the same time.
> 
> > +<structfield>reserved</structfield> array must be zeroed. When the ioctl
> > +is called with a pointer to this structure the driver will attempt to allocate
> > +up to the requested number of buffers and store the actual number allocated
> > +and the starting index in the <structfield>count</structfield> and
> > +the <structfield>index</structfield> fields respectively.
> > +<structfield>count</structfield> can be smaller than the number requested.
> > +-ENOMEM is returned, if the driver runs out of free memory.</para>
> > +    <para>When the I/O method is not supported the ioctl
> > +returns an &EINVAL;.</para>
> > +
> > +    <table pgwide="1" frame="none" id="v4l2-create-buffers">
> > +      <title>struct <structname>v4l2_create_buffers</structname></title>
> > +      <tgroup cols="3">
> > +       &cs-str;
> > +       <tbody valign="top">
> > +         <row>
> > +           <entry>__u32</entry>
> > +           <entry><structfield>index</structfield></entry>
> > +           <entry>The starting buffer index, returned by the driver.</entry>
> > +         </row>
> > +         <row>
> > +           <entry>__u32</entry>
> > +           <entry><structfield>count</structfield></entry>
> > +           <entry>The number of buffers requested or granted.</entry>
> > +         </row>
> > +         <row>
> > +           <entry>&v4l2-memory;</entry>
> > +           <entry><structfield>memory</structfield></entry>
> > +           <entry>Applications set this field to
> > +<constant>V4L2_MEMORY_MMAP</constant> or
> > +<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
> > +         </row>
> > +         <row>
> > +           <entry>__u32</entry>
> > +           <entry><structfield>size</structfield></entry>
> > +           <entry>Explicit size of buffers, being created.</entry>
> > +         </row>
> > +         <row>
> > +           <entry>&v4l2-format;</entry>
> > +           <entry><structfield>format</structfield></entry>
> > +           <entry>Application has to set the <structfield>type</structfield>
> > +field, other fields should be used, if the application wants to allocate buffers
> > +for a specific frame format.</entry>
> > +         </row>
> > +         <row>
> > +           <entry>__u32</entry>
> > +           <entry><structfield>reserved</structfield>[8]</entry>
> > +           <entry>A place holder for future extensions.</entry>
> > +         </row>
> > +       </tbody>
> > +      </tgroup>
> > +    </table>
> > +  </refsect1>
> > +
> > +  <refsect1>
> > +    &return-value;
> > +
> > +    <variablelist>
> > +      <varlistentry>
> > +       <term><errorcode>ENOMEM</errorcode></term>
> > +       <listitem>
> > +         <para>No memory to allocate buffers for <link linkend="mmap">memory
> > +mapped</link> I/O.</para>
> > +       </listitem>
> > +      </varlistentry>
> > +      <varlistentry>
> > +       <term><errorcode>EINVAL</errorcode></term>
> > +       <listitem>
> > +         <para>The buffer type (<structfield>type</structfield> field) or the
> > +requested I/O method (<structfield>memory</structfield>) is not
> > +supported.</para>
> > +       </listitem>
> > +      </varlistentry>
> > +    </variablelist>
> > +  </refsect1>
> > +</refentry>
> > +
> 
> What happens if the driver does not agree to the provided size? EINVAL?
> 
> > +<!--
> > +Local Variables:
> > +mode: sgml
> > +sgml-parent-document: "v4l2.sgml"
> > +indent-tabs-mode: nil
> > +End:
> > +-->
> > diff --git a/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> > new file mode 100644
> > index 0000000..509e752
> > --- /dev/null
> > +++ b/Documentation/DocBook/media/v4l/vidioc-prepare-buf.xml
> > @@ -0,0 +1,96 @@
> > +<refentry id="vidioc-prepare-buf">
> > +  <refmeta>
> > +    <refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
> > +    &manvol;
> > +  </refmeta>
> > +
> > +  <refnamediv>
> > +    <refname>VIDIOC_PREPARE_BUF</refname>
> > +    <refpurpose>Prepare a buffer for I/O</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_buffer *<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_PREPARE_BUF</para>
> > +       </listitem>
> > +      </varlistentry>
> > +      <varlistentry>
> > +       <term><parameter>argp</parameter></term>
> > +       <listitem>
> > +         <para></para>
> > +       </listitem>
> > +      </varlistentry>
> > +    </variablelist>
> > +  </refsect1>
> > +
> > +  <refsect1>
> > +    <title>Description</title>
> > +
> > +    <para>Applications can optionally call the
> > +<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
> > +to the driver before actually enqueuing it, using the
> > +<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
> > +Such preparations may include cache invalidation or cleaning. Performing them
> > +in advance saves time during the actual I/O. In case such cache operations are
> > +not required, the application can use one of
> > +<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
> > +<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
> > +step.</para>
> > +
> 
> I'm probably forgetting something, but why would we want to do both
> PREPARE_BUF and QBUF? Why not queue in advance?
> Could you give a full sequence of ioctls how it will be used
> (including streamons, etc.)? I'm trying to picture how passing of both
> types of buffers will have to look like between vb2 and a driver.
> 
> <snip>
> 
> --
> Best regards,
> Pawel Osciak

-- 
Sakari Ailus
sakari.ailus@xxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux