Message ID | 1349188056-4886-3-git-send-email-t.stanislaws@samsung.com |
---|---|
State | New |
Headers | show |
Hi Tomasz, Just a few more stylistic issues... On Tue October 2 2012 16:27:13 Tomasz Stanislawski wrote: > This patch adds description and usage examples for importing > DMABUF file descriptor in V4L2. > > Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com> > Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> > CC: linux-doc@vger.kernel.org > --- > Documentation/DocBook/media/v4l/compat.xml | 4 + > Documentation/DocBook/media/v4l/io.xml | 180 +++++++++++++++++++- > .../DocBook/media/v4l/vidioc-create-bufs.xml | 16 +- > Documentation/DocBook/media/v4l/vidioc-qbuf.xml | 17 ++ > Documentation/DocBook/media/v4l/vidioc-reqbufs.xml | 47 ++--- > 5 files changed, 234 insertions(+), 30 deletions(-) > > diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml > index faa0fd1..a46f95b 100644 > --- a/Documentation/DocBook/media/v4l/compat.xml > +++ b/Documentation/DocBook/media/v4l/compat.xml > @@ -2621,6 +2621,10 @@ ioctls.</para> > <listitem> > <para>Support for frequency band enumeration: &VIDIOC-ENUM-FREQ-BANDS; ioctl.</para> > </listitem> > + <listitem> > + <para>Importing DMABUF file descriptors as a new IO method described > + in <xref linkend="dmabuf" />.</para> > + </listitem> > </itemizedlist> > </section> > > diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml > index 1885cc0..5b58657 100644 > --- a/Documentation/DocBook/media/v4l/io.xml > +++ b/Documentation/DocBook/media/v4l/io.xml > @@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By default > outgoing queue. When the <constant>O_NONBLOCK</constant> flag was > given to the &func-open; function, <constant>VIDIOC_DQBUF</constant> > returns immediately with an &EAGAIN; when no buffer is available. The > -&func-select; or &func-poll; function are always available.</para> > +&func-select; or &func-poll; functions are always available.</para> > > <para>To start and stop capturing or output applications call the > &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note > @@ -472,6 +472,161 @@ rest should be evident.</para> > </footnote></para> > </section> > > + <section id="dmabuf"> > + <title>Streaming I/O (DMA buffer importing)</title> > + > + <note> > + <title>Experimental</title> > + <para>This is an <link linkend="experimental"> experimental </link> > + interface and may change in the future.</para> > + </note> > + > +<para>The DMABUF framework provides a generic method for sharing buffers > +between multiple devices. Device drivers that support DMABUF can export a DMA > +buffer to userspace as a file descriptor (known as the exporter role), import a > +DMA buffer from userspace using a file descriptor previously exported for a > +different or the same device (known as the importer role), or both. This > +section describes the DMABUF importer role API in V4L2.</para> > + > +<para>Input and output devices support the streaming I/O method when the > +<constant>V4L2_CAP_STREAMING</constant> flag in the > +<structfield>capabilities</structfield> field of &v4l2-capability; returned by > +the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through > +DMABUF file descriptors is supported is determined by calling the > +&VIDIOC-REQBUFS; ioctl with the memory type set to > +<constant>V4L2_MEMORY_DMABUF</constant>.</para> > + > + <para>This I/O method is dedicated for sharing DMA buffers between V4L and > +other APIs. It's more accurate to say something along the lines of: "...is dedicated to sharing DMA buffers between different devices, which may be V4L devices or other video-related devices (e.g. DRM)." One of the uses of this API is to share buffers between different V4L devices, so that's a bit more generic than the original sentence suggests. > Buffers (planes) are allocated by a driver on behalf of an > +application. Next, these buffers are exported to the application as file > +descriptors using an API which is specific for an allocator driver. Only such > +file descriptor are exchanged. The descriptors and meta-information are passed > +in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case). The driver > +must be switched into DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the > +desired buffer type.</para> > + > + <example> > + <title>Initiating streaming I/O with DMABUF file descriptors</title> > + > + <programlisting> > +&v4l2-requestbuffers; reqbuf; > + > +memset (&reqbuf, 0, sizeof (reqbuf)); no space after memset > +reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; > +reqbuf.memory = V4L2_MEMORY_DMABUF; > +reqbuf.count = 1; > + > +if (ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) { no space after ioctl > + if (errno == EINVAL) > + printf("Video capturing or DMABUF streaming is not supported\n"); > + else > + perror("VIDIOC_REQBUFS"); > + > + exit(EXIT_FAILURE); > +} > + </programlisting> > + </example> > + > + <para>The buffer (plane) file descriptor is passed on the fly with the > +&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be > +associated with a different DMABUF descriptor. Although buffers are commonly > +cycled, applications can pass a different DMABUF descriptor at each > +<constant>VIDIOC_QBUF</constant> call.</para> > + > + <example> > + <title>Queueing DMABUF using single plane API</title> > + > + <programlisting> > +int buffer_queue(int v4lfd, int index, int dmafd) > +{ > + &v4l2-buffer; buf; > + > + memset(&buf, 0, sizeof buf); > + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; > + buf.memory = V4L2_MEMORY_DMABUF; > + buf.index = index; > + buf.m.fd = dmafd; > + > + if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) { > + perror("VIDIOC_QBUF"); > + return -1; > + } > + > + return 0; > +} > + </programlisting> > + </example> > + > + <example> > + <title>Queueing DMABUF using multi plane API</title> > + > + <programlisting> > +int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes) > +{ > + &v4l2-buffer; buf; > + &v4l2-plane; planes[VIDEO_MAX_PLANES]; > + int i; > + > + memset(&buf, 0, sizeof buf); > + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; > + buf.memory = V4L2_MEMORY_DMABUF; > + buf.index = index; > + buf.m.planes = planes; > + buf.length = n_planes; > + > + memset(&planes, 0, sizeof planes); > + > + for (i = 0; i < n_planes; ++i) > + buf.m.planes[i].m.fd = dmafd[i]; > + > + if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) { > + perror("VIDIOC_QBUF"); > + return -1; > + } > + > + return 0; > +} > + </programlisting> > + </example> > + > + <para>Filled or displayed buffers are dequeued with the Filled -> Captured > +&VIDIOC-DQBUF; ioctl. The driver can unlock the buffer at any > +time between the completion of the DMA and this ioctl. The memory is > +also unlocked when &VIDIOC-STREAMOFF; is called, &VIDIOC-REQBUFS;, or > +when the device is closed.</para> > + > + <para>For capturing applications it is customary to enqueue a > +number of empty buffers, to start capturing and enter the read loop. > +Here the application waits until a filled buffer can be dequeued, and > +re-enqueues the buffer when the data is no longer needed. Output > +applications fill and enqueue buffers, when enough buffers are stacked > +up output is started. In the write loop, when the application > +runs out of free buffers it must wait until an empty buffer can be > +dequeued and reused. Two methods exist to suspend execution of the > +application until one or more buffers can be dequeued. By default > +<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the > +outgoing queue. When the <constant>O_NONBLOCK</constant> flag was > +given to the &func-open; function, <constant>VIDIOC_DQBUF</constant> > +returns immediately with an &EAGAIN; when no buffer is available. The > +&func-select; or &func-poll; function are always available.</para> or -> and function -> functions > + > + <para>To start and stop capturing or output applications call the output -> displaying > +&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctls. Note that > +<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both queues and > +unlocks all buffers as a side effect. Since there is no notion of doing > +anything "now" on a multitasking system, if an application needs to synchronize > +with another event it should examine the &v4l2-buffer; > +<structfield>timestamp</structfield> of captured buffers, or set the field > +before enqueuing buffers for output.</para> > + > + <para>Drivers implementing DMABUF importing I/O must support the > +<constant>VIDIOC_REQBUFS</constant>, <constant>VIDIOC_QBUF</constant>, > +<constant>VIDIOC_DQBUF</constant>, <constant>VIDIOC_STREAMON</constant> and > +<constant>VIDIOC_STREAMOFF</constant> ioctls, and the > +<function>select()</function> and <function>poll()</function> functions.</para> > + > + </section> > + > <section id="async"> > <title>Asynchronous I/O</title> > > @@ -673,6 +828,14 @@ memory, set by the application. See <xref linkend="userp" /> for details. > <structname>v4l2_buffer</structname> structure.</entry> > </row> > <row> > + <entry></entry> > + <entry>int</entry> > + <entry><structfield>fd</structfield></entry> > + <entry>For the single-plane API and when > +<structfield>memory</structfield> is <constant>V4L2_MEMORY_DMABUF</constant> this > +is the file descriptor associated with a DMABUF buffer.</entry> > + </row> > + <row> > <entry>__u32</entry> > <entry><structfield>length</structfield></entry> > <entry></entry> > @@ -746,6 +909,15 @@ should set this to 0.</entry> > </entry> > </row> > <row> > + <entry></entry> > + <entry>int</entry> > + <entry><structfield>fd</structfield></entry> > + <entry>When the memory type in the containing &v4l2-buffer; is > + <constant>V4L2_MEMORY_DMABUF</constant>, this is a file > + descriptor associated with a DMABUF buffer, similar to the > + <structfield>fd</structfield> field in &v4l2-buffer;.</entry> > + </row> > + <row> > <entry>__u32</entry> > <entry><structfield>data_offset</structfield></entry> > <entry></entry> > @@ -973,6 +1145,12 @@ pointer</link> I/O.</entry> > <entry>3</entry> > <entry>[to do]</entry> > </row> > + <row> > + <entry><constant>V4L2_MEMORY_DMABUF</constant></entry> > + <entry>4</entry> > + <entry>The buffer is used for <link linkend="dmabuf">DMA shared > +buffer</link> I/O.</entry> > + </row> > </tbody> > </tgroup> > </table> > diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml > index a8cda1a..cd99436 100644 > --- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml > +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml > @@ -6,7 +6,8 @@ > > <refnamediv> > <refname>VIDIOC_CREATE_BUFS</refname> > - <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose> > + <refpurpose>Create buffers for Memory Mapped or User Pointer or DMA Buffer > + I/O</refpurpose> > </refnamediv> > > <refsynopsisdiv> > @@ -55,11 +56,11 @@ > </note> > > <para>This ioctl is used to create buffers for <link linkend="mmap">memory > -mapped</link> or <link linkend="userp">user pointer</link> > -I/O. It can be used as an alternative or in addition to the > -<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers > -is required. This ioctl can be called multiple times to create buffers of > -different sizes.</para> > +mapped</link> or <link linkend="userp">user pointer</link> or <link > +linkend="dmabuf">DMA buffer</link> I/O. It can be used as an alternative or in > +addition to the <constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter > +control over buffers is required. This ioctl can be called multiple times to > +create buffers of different sizes.</para> > > <para>To allocate device buffers applications initialize relevant fields of > the <structname>v4l2_create_buffers</structname> structure. They set the > @@ -109,7 +110,8 @@ information.</para> > <entry>__u32</entry> > <entry><structfield>memory</structfield></entry> > <entry>Applications set this field to > -<constant>V4L2_MEMORY_MMAP</constant> or > +<constant>V4L2_MEMORY_MMAP</constant>, > +<constant>V4L2_MEMORY_DMABUF</constant> or > <constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory" > /></entry> > </row> > diff --git a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml > index 77ff5be..f40dfa0 100644 > --- a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml > +++ b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml > @@ -109,6 +109,23 @@ they cannot be swapped out to disk. Buffers remain locked until > dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is > called, or until the device is closed.</para> > > + <para>To enqueue a <link linkend="dmabuf">DMABUF</link> buffer applications > +set the <structfield>memory</structfield> field to > +<constant>V4L2_MEMORY_DMABUF</constant> and the <structfield>m.fd</structfield> > +field to a file descriptor associated with a DMABUF buffer. When the > +multi-planar API is used the <structfield>m.fd</structfield> fields of the > +passed array of &v4l2-plane; have to be used instead. When > +<constant>VIDIOC_QBUF</constant> is called with a pointer to this structure the > +driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the > +<constant>V4L2_BUF_FLAG_MAPPED</constant> and > +<constant>V4L2_BUF_FLAG_DONE</constant> flags in the > +<structfield>flags</structfield> field, or it returns an error code. This > +ioctl locks the buffer. Locking a buffer means passing it to a driver for an > +access by hardware. "an access by hardware" -> "hardware access (usually DMA)" > If an application accesses (reads/writes) a locked buffer > +then the result is undefined. Buffers remain locked until dequeued, until the > +&VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is called, or until the device is > +closed.</para> > + > <para>Applications call the <constant>VIDIOC_DQBUF</constant> > ioctl to dequeue a filled (capturing) or displayed (output) buffer > from the driver's outgoing queue. They just set the > diff --git a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml > index d7c9505..20f4323 100644 > --- a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml > +++ b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml > @@ -48,28 +48,30 @@ > <refsect1> > <title>Description</title> > > - <para>This ioctl is used to initiate <link linkend="mmap">memory > -mapped</link> or <link linkend="userp">user pointer</link> > -I/O. Memory mapped buffers are located in device memory and must be > -allocated with this ioctl before they can be mapped into the > -application's address space. User buffers are allocated by > -applications themselves, and this ioctl is merely used to switch the > -driver into user pointer I/O mode and to setup some internal structures.</para> > +<para>This ioctl is used to initiate <link linkend="mmap">memory mapped</link>, > +<link linkend="userp">user pointer</link> or <link > +linkend="dmabuf">DMABUF</link> based I/O. Memory mapped buffers are located in > +device memory and must be allocated with this ioctl before they can be mapped > +into the application's address space. User buffers are allocated by > +applications themselves, and this ioctl is merely used to switch the driver > +into user pointer I/O mode and to setup some internal structures. > +Similarly, DMABUF buffers are allocated by applications through a device > +driver, and this ioctl only configures the driver into DMABUF I/O mode without > +performing any direct allocation.</para> > > - <para>To allocate device buffers applications initialize all > -fields of the <structname>v4l2_requestbuffers</structname> structure. > -They set the <structfield>type</structfield> field to the respective > -stream or buffer type, the <structfield>count</structfield> field to > -the desired number of buffers, <structfield>memory</structfield> > -must be set to the requested I/O method and the <structfield>reserved</structfield> array > -must be zeroed. When the ioctl > -is called with a pointer to this structure the driver will attempt to allocate > -the requested number of buffers and it stores the actual number > -allocated in the <structfield>count</structfield> field. It can be > -smaller than the number requested, even zero, when the driver runs out > -of free memory. A larger number is also possible when the driver requires > -more buffers to function correctly. For example video output requires at least two buffers, > -one displayed and one filled by the application.</para> > + <para>To allocate device buffers applications initialize all fields of the > +<structname>v4l2_requestbuffers</structname> structure. They set the > +<structfield>type</structfield> field to the respective stream or buffer type, > +the <structfield>count</structfield> field to the desired number of buffers, > +<structfield>memory</structfield> must be set to the requested I/O method and > +the <structfield>reserved</structfield> array must be zeroed. When the ioctl is > +called with a pointer to this structure the driver will attempt to allocate the > +requested number of buffers and it stores the actual number allocated in the > +<structfield>count</structfield> field. It can be smaller than the number > +requested, even zero, when the driver runs out of free memory. A larger number > +is also possible when the driver requires more buffers to function correctly. > +For example video output requires at least two buffers, one displayed and one > +filled by the application.</para> > <para>When the I/O method is not supported the ioctl > returns an &EINVAL;.</para> > > @@ -102,7 +104,8 @@ as the &v4l2-format; <structfield>type</structfield> field. See <xref > <entry>__u32</entry> > <entry><structfield>memory</structfield></entry> > <entry>Applications set this field to > -<constant>V4L2_MEMORY_MMAP</constant> or > +<constant>V4L2_MEMORY_MMAP</constant>, > +<constant>V4L2_MEMORY_DMABUF</constant> or > <constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory" > />.</entry> > </row> > Regards, Hans
diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index faa0fd1..a46f95b 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2621,6 +2621,10 @@ ioctls.</para> <listitem> <para>Support for frequency band enumeration: &VIDIOC-ENUM-FREQ-BANDS; ioctl.</para> </listitem> + <listitem> + <para>Importing DMABUF file descriptors as a new IO method described + in <xref linkend="dmabuf" />.</para> + </listitem> </itemizedlist> </section> diff --git a/Documentation/DocBook/media/v4l/io.xml b/Documentation/DocBook/media/v4l/io.xml index 1885cc0..5b58657 100644 --- a/Documentation/DocBook/media/v4l/io.xml +++ b/Documentation/DocBook/media/v4l/io.xml @@ -331,7 +331,7 @@ application until one or more buffers can be dequeued. By default outgoing queue. When the <constant>O_NONBLOCK</constant> flag was given to the &func-open; function, <constant>VIDIOC_DQBUF</constant> returns immediately with an &EAGAIN; when no buffer is available. The -&func-select; or &func-poll; function are always available.</para> +&func-select; or &func-poll; functions are always available.</para> <para>To start and stop capturing or output applications call the &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note @@ -472,6 +472,161 @@ rest should be evident.</para> </footnote></para> </section> + <section id="dmabuf"> + <title>Streaming I/O (DMA buffer importing)</title> + + <note> + <title>Experimental</title> + <para>This is an <link linkend="experimental"> experimental </link> + interface and may change in the future.</para> + </note> + +<para>The DMABUF framework provides a generic method for sharing buffers +between multiple devices. Device drivers that support DMABUF can export a DMA +buffer to userspace as a file descriptor (known as the exporter role), import a +DMA buffer from userspace using a file descriptor previously exported for a +different or the same device (known as the importer role), or both. This +section describes the DMABUF importer role API in V4L2.</para> + +<para>Input and output devices support the streaming I/O method when the +<constant>V4L2_CAP_STREAMING</constant> flag in the +<structfield>capabilities</structfield> field of &v4l2-capability; returned by +the &VIDIOC-QUERYCAP; ioctl is set. Whether importing DMA buffers through +DMABUF file descriptors is supported is determined by calling the +&VIDIOC-REQBUFS; ioctl with the memory type set to +<constant>V4L2_MEMORY_DMABUF</constant>.</para> + + <para>This I/O method is dedicated for sharing DMA buffers between V4L and +other APIs. Buffers (planes) are allocated by a driver on behalf of an +application. Next, these buffers are exported to the application as file +descriptors using an API which is specific for an allocator driver. Only such +file descriptor are exchanged. The descriptors and meta-information are passed +in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case). The driver +must be switched into DMABUF I/O mode by calling the &VIDIOC-REQBUFS; with the +desired buffer type.</para> + + <example> + <title>Initiating streaming I/O with DMABUF file descriptors</title> + + <programlisting> +&v4l2-requestbuffers; reqbuf; + +memset (&reqbuf, 0, sizeof (reqbuf)); +reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; +reqbuf.memory = V4L2_MEMORY_DMABUF; +reqbuf.count = 1; + +if (ioctl (fd, &VIDIOC-REQBUFS;, &reqbuf) == -1) { + if (errno == EINVAL) + printf("Video capturing or DMABUF streaming is not supported\n"); + else + perror("VIDIOC_REQBUFS"); + + exit(EXIT_FAILURE); +} + </programlisting> + </example> + + <para>The buffer (plane) file descriptor is passed on the fly with the +&VIDIOC-QBUF; ioctl. In case of multiplanar buffers, every plane can be +associated with a different DMABUF descriptor. Although buffers are commonly +cycled, applications can pass a different DMABUF descriptor at each +<constant>VIDIOC_QBUF</constant> call.</para> + + <example> + <title>Queueing DMABUF using single plane API</title> + + <programlisting> +int buffer_queue(int v4lfd, int index, int dmafd) +{ + &v4l2-buffer; buf; + + memset(&buf, 0, sizeof buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_DMABUF; + buf.index = index; + buf.m.fd = dmafd; + + if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) { + perror("VIDIOC_QBUF"); + return -1; + } + + return 0; +} + </programlisting> + </example> + + <example> + <title>Queueing DMABUF using multi plane API</title> + + <programlisting> +int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes) +{ + &v4l2-buffer; buf; + &v4l2-plane; planes[VIDEO_MAX_PLANES]; + int i; + + memset(&buf, 0, sizeof buf); + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_DMABUF; + buf.index = index; + buf.m.planes = planes; + buf.length = n_planes; + + memset(&planes, 0, sizeof planes); + + for (i = 0; i < n_planes; ++i) + buf.m.planes[i].m.fd = dmafd[i]; + + if (ioctl(v4lfd, &VIDIOC-QBUF;, &buf) == -1) { + perror("VIDIOC_QBUF"); + return -1; + } + + return 0; +} + </programlisting> + </example> + + <para>Filled or displayed buffers are dequeued with the +&VIDIOC-DQBUF; ioctl. The driver can unlock the buffer at any +time between the completion of the DMA and this ioctl. The memory is +also unlocked when &VIDIOC-STREAMOFF; is called, &VIDIOC-REQBUFS;, or +when the device is closed.</para> + + <para>For capturing applications it is customary to enqueue a +number of empty buffers, to start capturing and enter the read loop. +Here the application waits until a filled buffer can be dequeued, and +re-enqueues the buffer when the data is no longer needed. Output +applications fill and enqueue buffers, when enough buffers are stacked +up output is started. In the write loop, when the application +runs out of free buffers it must wait until an empty buffer can be +dequeued and reused. Two methods exist to suspend execution of the +application until one or more buffers can be dequeued. By default +<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the +outgoing queue. When the <constant>O_NONBLOCK</constant> flag was +given to the &func-open; function, <constant>VIDIOC_DQBUF</constant> +returns immediately with an &EAGAIN; when no buffer is available. The +&func-select; or &func-poll; function are always available.</para> + + <para>To start and stop capturing or output applications call the +&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctls. Note that +<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both queues and +unlocks all buffers as a side effect. Since there is no notion of doing +anything "now" on a multitasking system, if an application needs to synchronize +with another event it should examine the &v4l2-buffer; +<structfield>timestamp</structfield> of captured buffers, or set the field +before enqueuing buffers for output.</para> + + <para>Drivers implementing DMABUF importing I/O must support the +<constant>VIDIOC_REQBUFS</constant>, <constant>VIDIOC_QBUF</constant>, +<constant>VIDIOC_DQBUF</constant>, <constant>VIDIOC_STREAMON</constant> and +<constant>VIDIOC_STREAMOFF</constant> ioctls, and the +<function>select()</function> and <function>poll()</function> functions.</para> + + </section> + <section id="async"> <title>Asynchronous I/O</title> @@ -673,6 +828,14 @@ memory, set by the application. See <xref linkend="userp" /> for details. <structname>v4l2_buffer</structname> structure.</entry> </row> <row> + <entry></entry> + <entry>int</entry> + <entry><structfield>fd</structfield></entry> + <entry>For the single-plane API and when +<structfield>memory</structfield> is <constant>V4L2_MEMORY_DMABUF</constant> this +is the file descriptor associated with a DMABUF buffer.</entry> + </row> + <row> <entry>__u32</entry> <entry><structfield>length</structfield></entry> <entry></entry> @@ -746,6 +909,15 @@ should set this to 0.</entry> </entry> </row> <row> + <entry></entry> + <entry>int</entry> + <entry><structfield>fd</structfield></entry> + <entry>When the memory type in the containing &v4l2-buffer; is + <constant>V4L2_MEMORY_DMABUF</constant>, this is a file + descriptor associated with a DMABUF buffer, similar to the + <structfield>fd</structfield> field in &v4l2-buffer;.</entry> + </row> + <row> <entry>__u32</entry> <entry><structfield>data_offset</structfield></entry> <entry></entry> @@ -973,6 +1145,12 @@ pointer</link> I/O.</entry> <entry>3</entry> <entry>[to do]</entry> </row> + <row> + <entry><constant>V4L2_MEMORY_DMABUF</constant></entry> + <entry>4</entry> + <entry>The buffer is used for <link linkend="dmabuf">DMA shared +buffer</link> I/O.</entry> + </row> </tbody> </tgroup> </table> diff --git a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml index a8cda1a..cd99436 100644 --- a/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml +++ b/Documentation/DocBook/media/v4l/vidioc-create-bufs.xml @@ -6,7 +6,8 @@ <refnamediv> <refname>VIDIOC_CREATE_BUFS</refname> - <refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose> + <refpurpose>Create buffers for Memory Mapped or User Pointer or DMA Buffer + I/O</refpurpose> </refnamediv> <refsynopsisdiv> @@ -55,11 +56,11 @@ </note> <para>This ioctl is used to create buffers for <link linkend="mmap">memory -mapped</link> or <link linkend="userp">user pointer</link> -I/O. It can be used as an alternative or in addition to the -<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers -is required. This ioctl can be called multiple times to create buffers of -different sizes.</para> +mapped</link> or <link linkend="userp">user pointer</link> or <link +linkend="dmabuf">DMA buffer</link> I/O. It can be used as an alternative or in +addition to the <constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter +control over buffers is required. This ioctl can be called multiple times to +create buffers of different sizes.</para> <para>To allocate device buffers applications initialize relevant fields of the <structname>v4l2_create_buffers</structname> structure. They set the @@ -109,7 +110,8 @@ information.</para> <entry>__u32</entry> <entry><structfield>memory</structfield></entry> <entry>Applications set this field to -<constant>V4L2_MEMORY_MMAP</constant> or +<constant>V4L2_MEMORY_MMAP</constant>, +<constant>V4L2_MEMORY_DMABUF</constant> or <constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory" /></entry> </row> diff --git a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml index 77ff5be..f40dfa0 100644 --- a/Documentation/DocBook/media/v4l/vidioc-qbuf.xml +++ b/Documentation/DocBook/media/v4l/vidioc-qbuf.xml @@ -109,6 +109,23 @@ they cannot be swapped out to disk. Buffers remain locked until dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is called, or until the device is closed.</para> + <para>To enqueue a <link linkend="dmabuf">DMABUF</link> buffer applications +set the <structfield>memory</structfield> field to +<constant>V4L2_MEMORY_DMABUF</constant> and the <structfield>m.fd</structfield> +field to a file descriptor associated with a DMABUF buffer. When the +multi-planar API is used the <structfield>m.fd</structfield> fields of the +passed array of &v4l2-plane; have to be used instead. When +<constant>VIDIOC_QBUF</constant> is called with a pointer to this structure the +driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the +<constant>V4L2_BUF_FLAG_MAPPED</constant> and +<constant>V4L2_BUF_FLAG_DONE</constant> flags in the +<structfield>flags</structfield> field, or it returns an error code. This +ioctl locks the buffer. Locking a buffer means passing it to a driver for an +access by hardware. If an application accesses (reads/writes) a locked buffer +then the result is undefined. Buffers remain locked until dequeued, until the +&VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl is called, or until the device is +closed.</para> + <para>Applications call the <constant>VIDIOC_DQBUF</constant> ioctl to dequeue a filled (capturing) or displayed (output) buffer from the driver's outgoing queue. They just set the diff --git a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml index d7c9505..20f4323 100644 --- a/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml +++ b/Documentation/DocBook/media/v4l/vidioc-reqbufs.xml @@ -48,28 +48,30 @@ <refsect1> <title>Description</title> - <para>This ioctl is used to initiate <link linkend="mmap">memory -mapped</link> or <link linkend="userp">user pointer</link> -I/O. Memory mapped buffers are located in device memory and must be -allocated with this ioctl before they can be mapped into the -application's address space. User buffers are allocated by -applications themselves, and this ioctl is merely used to switch the -driver into user pointer I/O mode and to setup some internal structures.</para> +<para>This ioctl is used to initiate <link linkend="mmap">memory mapped</link>, +<link linkend="userp">user pointer</link> or <link +linkend="dmabuf">DMABUF</link> based I/O. Memory mapped buffers are located in +device memory and must be allocated with this ioctl before they can be mapped +into the application's address space. User buffers are allocated by +applications themselves, and this ioctl is merely used to switch the driver +into user pointer I/O mode and to setup some internal structures. +Similarly, DMABUF buffers are allocated by applications through a device +driver, and this ioctl only configures the driver into DMABUF I/O mode without +performing any direct allocation.</para> - <para>To allocate device buffers applications initialize all -fields of the <structname>v4l2_requestbuffers</structname> structure. -They set the <structfield>type</structfield> field to the respective -stream or buffer type, the <structfield>count</structfield> field to -the desired number of buffers, <structfield>memory</structfield> -must be set to the requested I/O method and the <structfield>reserved</structfield> array -must be zeroed. When the ioctl -is called with a pointer to this structure the driver will attempt to allocate -the requested number of buffers and it stores the actual number -allocated in the <structfield>count</structfield> field. It can be -smaller than the number requested, even zero, when the driver runs out -of free memory. A larger number is also possible when the driver requires -more buffers to function correctly. For example video output requires at least two buffers, -one displayed and one filled by the application.</para> + <para>To allocate device buffers applications initialize all fields of the +<structname>v4l2_requestbuffers</structname> structure. They set the +<structfield>type</structfield> field to the respective stream or buffer type, +the <structfield>count</structfield> field to the desired number of buffers, +<structfield>memory</structfield> must be set to the requested I/O method and +the <structfield>reserved</structfield> array must be zeroed. When the ioctl is +called with a pointer to this structure the driver will attempt to allocate the +requested number of buffers and it stores the actual number allocated in the +<structfield>count</structfield> field. It can be smaller than the number +requested, even zero, when the driver runs out of free memory. A larger number +is also possible when the driver requires more buffers to function correctly. +For example video output requires at least two buffers, one displayed and one +filled by the application.</para> <para>When the I/O method is not supported the ioctl returns an &EINVAL;.</para> @@ -102,7 +104,8 @@ as the &v4l2-format; <structfield>type</structfield> field. See <xref <entry>__u32</entry> <entry><structfield>memory</structfield></entry> <entry>Applications set this field to -<constant>V4L2_MEMORY_MMAP</constant> or +<constant>V4L2_MEMORY_MMAP</constant>, +<constant>V4L2_MEMORY_DMABUF</constant> or <constant>V4L2_MEMORY_USERPTR</constant>. See <xref linkend="v4l2-memory" />.</entry> </row>