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