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