Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later
0002 .. c:namespace:: V4L
0003 
0004 .. _dmabuf:
0005 
0006 ************************************
0007 Streaming I/O (DMA buffer importing)
0008 ************************************
0009 
0010 The DMABUF framework provides a generic method for sharing buffers
0011 between multiple devices. Device drivers that support DMABUF can export
0012 a DMA buffer to userspace as a file descriptor (known as the exporter
0013 role), import a DMA buffer from userspace using a file descriptor
0014 previously exported for a different or the same device (known as the
0015 importer role), or both. This section describes the DMABUF importer role
0016 API in V4L2.
0017 
0018 Refer to :ref:`DMABUF exporting <VIDIOC_EXPBUF>` for details about
0019 exporting V4L2 buffers as DMABUF file descriptors.
0020 
0021 Input and output devices support the streaming I/O method when the
0022 ``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct
0023 :c:type:`v4l2_capability` returned by the
0024 :ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>` ioctl is set. Whether
0025 importing DMA buffers through DMABUF file descriptors is supported is
0026 determined by calling the :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`
0027 ioctl with the memory type set to ``V4L2_MEMORY_DMABUF``.
0028 
0029 This I/O method is dedicated to sharing DMA buffers between different
0030 devices, which may be V4L devices or other video-related devices (e.g.
0031 DRM). Buffers (planes) are allocated by a driver on behalf of an
0032 application. Next, these buffers are exported to the application as file
0033 descriptors using an API which is specific for an allocator driver. Only
0034 such file descriptor are exchanged. The descriptors and meta-information
0035 are passed in struct :c:type:`v4l2_buffer` (or in struct
0036 :c:type:`v4l2_plane` in the multi-planar API case). The
0037 driver must be switched into DMABUF I/O mode by calling the
0038 :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` with the desired buffer type.
0039 
0040 Example: Initiating streaming I/O with DMABUF file descriptors
0041 ==============================================================
0042 
0043 .. code-block:: c
0044 
0045     struct v4l2_requestbuffers reqbuf;
0046 
0047     memset(&reqbuf, 0, sizeof (reqbuf));
0048     reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0049     reqbuf.memory = V4L2_MEMORY_DMABUF;
0050     reqbuf.count = 1;
0051 
0052     if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
0053         if (errno == EINVAL)
0054             printf("Video capturing or DMABUF streaming is not supported\\n");
0055         else
0056             perror("VIDIOC_REQBUFS");
0057 
0058         exit(EXIT_FAILURE);
0059     }
0060 
0061 The buffer (plane) file descriptor is passed on the fly with the
0062 :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. In case of multiplanar
0063 buffers, every plane can be associated with a different DMABUF
0064 descriptor. Although buffers are commonly cycled, applications can pass
0065 a different DMABUF descriptor at each :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call.
0066 
0067 Example: Queueing DMABUF using single plane API
0068 ===============================================
0069 
0070 .. code-block:: c
0071 
0072     int buffer_queue(int v4lfd, int index, int dmafd)
0073     {
0074         struct v4l2_buffer buf;
0075 
0076         memset(&buf, 0, sizeof buf);
0077         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0078         buf.memory = V4L2_MEMORY_DMABUF;
0079         buf.index = index;
0080         buf.m.fd = dmafd;
0081 
0082         if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
0083             perror("VIDIOC_QBUF");
0084             return -1;
0085         }
0086 
0087         return 0;
0088     }
0089 
0090 Example 3.6. Queueing DMABUF using multi plane API
0091 ==================================================
0092 
0093 .. code-block:: c
0094 
0095     int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes)
0096     {
0097         struct v4l2_buffer buf;
0098         struct v4l2_plane planes[VIDEO_MAX_PLANES];
0099         int i;
0100 
0101         memset(&buf, 0, sizeof buf);
0102         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
0103         buf.memory = V4L2_MEMORY_DMABUF;
0104         buf.index = index;
0105         buf.m.planes = planes;
0106         buf.length = n_planes;
0107 
0108         memset(&planes, 0, sizeof planes);
0109 
0110         for (i = 0; i < n_planes; ++i)
0111             buf.m.planes[i].m.fd = dmafd[i];
0112 
0113         if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) {
0114             perror("VIDIOC_QBUF");
0115             return -1;
0116         }
0117 
0118         return 0;
0119     }
0120 
0121 Captured or displayed buffers are dequeued with the
0122 :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the
0123 buffer at any time between the completion of the DMA and this ioctl. The
0124 memory is also unlocked when
0125 :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called,
0126 :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, or when the device is closed.
0127 
0128 For capturing applications it is customary to enqueue a number of empty
0129 buffers, to start capturing and enter the read loop. Here the
0130 application waits until a filled buffer can be dequeued, and re-enqueues
0131 the buffer when the data is no longer needed. Output applications fill
0132 and enqueue buffers, when enough buffers are stacked up output is
0133 started. In the write loop, when the application runs out of free
0134 buffers it must wait until an empty buffer can be dequeued and reused.
0135 Two methods exist to suspend execution of the application until one or
0136 more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF
0137 <VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the
0138 ``O_NONBLOCK`` flag was given to the :c:func:`open()` function,
0139 :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN``
0140 error code when no buffer is available. The
0141 :c:func:`select()` and :c:func:`poll()`
0142 functions are always available.
0143 
0144 To start and stop capturing or displaying applications call the
0145 :ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and
0146 :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls.
0147 
0148 .. note::
0149 
0150    :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from
0151    both queues and unlocks all buffers as a side effect. Since there is no
0152    notion of doing anything "now" on a multitasking system, if an
0153    application needs to synchronize with another event it should examine
0154    the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or
0155    outputted buffers.
0156 
0157 Drivers implementing DMABUF importing I/O must support the
0158 :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`,
0159 :ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON
0160 <VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls,
0161 and the :c:func:`select()` and :c:func:`poll()`
0162 functions.