1.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later 2 3.. _dmabuf: 4 5************************************ 6Streaming I/O (DMA buffer importing) 7************************************ 8 9The DMABUF framework provides a generic method for sharing buffers 10between multiple devices. Device drivers that support DMABUF can export 11a DMA buffer to userspace as a file descriptor (known as the exporter 12role), import a DMA buffer from userspace using a file descriptor 13previously exported for a different or the same device (known as the 14importer role), or both. This section describes the DMABUF importer role 15API in V4L2. 16 17Refer to :ref:`DMABUF exporting <VIDIOC_EXPBUF>` for details about 18exporting V4L2 buffers as DMABUF file descriptors. 19 20Input and output devices support the streaming I/O method when the 21``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct 22:c:type:`v4l2_capability` returned by the 23:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>` ioctl is set. Whether 24importing DMA buffers through DMABUF file descriptors is supported is 25determined by calling the :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` 26ioctl with the memory type set to ``V4L2_MEMORY_DMABUF``. 27 28This I/O method is dedicated to sharing DMA buffers between different 29devices, which may be V4L devices or other video-related devices (e.g. 30DRM). Buffers (planes) are allocated by a driver on behalf of an 31application. Next, these buffers are exported to the application as file 32descriptors using an API which is specific for an allocator driver. Only 33such file descriptor are exchanged. The descriptors and meta-information 34are passed in struct :c:type:`v4l2_buffer` (or in struct 35:c:type:`v4l2_plane` in the multi-planar API case). The 36driver must be switched into DMABUF I/O mode by calling the 37:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` with the desired buffer type. 38 39 40Example: Initiating streaming I/O with DMABUF file descriptors 41============================================================== 42 43.. code-block:: c 44 45 struct v4l2_requestbuffers reqbuf; 46 47 memset(&reqbuf, 0, sizeof (reqbuf)); 48 reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 49 reqbuf.memory = V4L2_MEMORY_DMABUF; 50 reqbuf.count = 1; 51 52 if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) { 53 if (errno == EINVAL) 54 printf("Video capturing or DMABUF streaming is not supported\\n"); 55 else 56 perror("VIDIOC_REQBUFS"); 57 58 exit(EXIT_FAILURE); 59 } 60 61The buffer (plane) file descriptor is passed on the fly with the 62:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. In case of multiplanar 63buffers, every plane can be associated with a different DMABUF 64descriptor. Although buffers are commonly cycled, applications can pass 65a different DMABUF descriptor at each :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call. 66 67Example: Queueing DMABUF using single plane API 68=============================================== 69 70.. code-block:: c 71 72 int buffer_queue(int v4lfd, int index, int dmafd) 73 { 74 struct v4l2_buffer buf; 75 76 memset(&buf, 0, sizeof buf); 77 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 78 buf.memory = V4L2_MEMORY_DMABUF; 79 buf.index = index; 80 buf.m.fd = dmafd; 81 82 if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) { 83 perror("VIDIOC_QBUF"); 84 return -1; 85 } 86 87 return 0; 88 } 89 90Example 3.6. Queueing DMABUF using multi plane API 91================================================== 92 93.. code-block:: c 94 95 int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes) 96 { 97 struct v4l2_buffer buf; 98 struct v4l2_plane planes[VIDEO_MAX_PLANES]; 99 int i; 100 101 memset(&buf, 0, sizeof buf); 102 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 103 buf.memory = V4L2_MEMORY_DMABUF; 104 buf.index = index; 105 buf.m.planes = planes; 106 buf.length = n_planes; 107 108 memset(&planes, 0, sizeof planes); 109 110 for (i = 0; i < n_planes; ++i) 111 buf.m.planes[i].m.fd = dmafd[i]; 112 113 if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) { 114 perror("VIDIOC_QBUF"); 115 return -1; 116 } 117 118 return 0; 119 } 120 121Captured or displayed buffers are dequeued with the 122:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the 123buffer at any time between the completion of the DMA and this ioctl. The 124memory is also unlocked when 125:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called, 126:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, or when the device is closed. 127 128For capturing applications it is customary to enqueue a number of empty 129buffers, to start capturing and enter the read loop. Here the 130application waits until a filled buffer can be dequeued, and re-enqueues 131the buffer when the data is no longer needed. Output applications fill 132and enqueue buffers, when enough buffers are stacked up output is 133started. In the write loop, when the application runs out of free 134buffers it must wait until an empty buffer can be dequeued and reused. 135Two methods exist to suspend execution of the application until one or 136more buffers can be dequeued. By default :ref:`VIDIOC_DQBUF 137<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the 138``O_NONBLOCK`` flag was given to the :ref:`open() <func-open>` function, 139:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN`` 140error code when no buffer is available. The 141:ref:`select() <func-select>` and :ref:`poll() <func-poll>` 142functions are always available. 143 144To start and stop capturing or displaying applications call the 145:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and 146:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls. 147 148.. note:: 149 150 :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from 151 both queues and unlocks all buffers as a side effect. Since there is no 152 notion of doing anything "now" on a multitasking system, if an 153 application needs to synchronize with another event it should examine 154 the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or 155 outputted buffers. 156 157Drivers implementing DMABUF importing I/O must support the 158:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, 159:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON 160<VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls, 161and the :ref:`select() <func-select>` and :ref:`poll() <func-poll>` 162functions. 163