1059b1c5bSMauro Carvalho Chehab.. SPDX-License-Identifier: GFDL-1.1-no-invariants-or-later 2*407e84cdSMauro Carvalho Chehab.. c:namespace:: V4L 354f38fcaSMauro Carvalho Chehab 454f38fcaSMauro Carvalho Chehab.. _dmabuf: 554f38fcaSMauro Carvalho Chehab 654f38fcaSMauro Carvalho Chehab************************************ 754f38fcaSMauro Carvalho ChehabStreaming I/O (DMA buffer importing) 854f38fcaSMauro Carvalho Chehab************************************ 954f38fcaSMauro Carvalho Chehab 1054f38fcaSMauro Carvalho ChehabThe DMABUF framework provides a generic method for sharing buffers 1154f38fcaSMauro Carvalho Chehabbetween multiple devices. Device drivers that support DMABUF can export 1254f38fcaSMauro Carvalho Chehaba DMA buffer to userspace as a file descriptor (known as the exporter 1354f38fcaSMauro Carvalho Chehabrole), import a DMA buffer from userspace using a file descriptor 1454f38fcaSMauro Carvalho Chehabpreviously exported for a different or the same device (known as the 1554f38fcaSMauro Carvalho Chehabimporter role), or both. This section describes the DMABUF importer role 1654f38fcaSMauro Carvalho ChehabAPI in V4L2. 1754f38fcaSMauro Carvalho Chehab 1854f38fcaSMauro Carvalho ChehabRefer to :ref:`DMABUF exporting <VIDIOC_EXPBUF>` for details about 1954f38fcaSMauro Carvalho Chehabexporting V4L2 buffers as DMABUF file descriptors. 2054f38fcaSMauro Carvalho Chehab 2154f38fcaSMauro Carvalho ChehabInput and output devices support the streaming I/O method when the 2254f38fcaSMauro Carvalho Chehab``V4L2_CAP_STREAMING`` flag in the ``capabilities`` field of struct 2354f38fcaSMauro Carvalho Chehab:c:type:`v4l2_capability` returned by the 2454f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_QUERYCAP <VIDIOC_QUERYCAP>` ioctl is set. Whether 2554f38fcaSMauro Carvalho Chehabimporting DMA buffers through DMABUF file descriptors is supported is 2654f38fcaSMauro Carvalho Chehabdetermined by calling the :ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` 2754f38fcaSMauro Carvalho Chehabioctl with the memory type set to ``V4L2_MEMORY_DMABUF``. 2854f38fcaSMauro Carvalho Chehab 2954f38fcaSMauro Carvalho ChehabThis I/O method is dedicated to sharing DMA buffers between different 3054f38fcaSMauro Carvalho Chehabdevices, which may be V4L devices or other video-related devices (e.g. 3154f38fcaSMauro Carvalho ChehabDRM). Buffers (planes) are allocated by a driver on behalf of an 3254f38fcaSMauro Carvalho Chehabapplication. Next, these buffers are exported to the application as file 3354f38fcaSMauro Carvalho Chehabdescriptors using an API which is specific for an allocator driver. Only 3454f38fcaSMauro Carvalho Chehabsuch file descriptor are exchanged. The descriptors and meta-information 3554f38fcaSMauro Carvalho Chehabare passed in struct :c:type:`v4l2_buffer` (or in struct 3654f38fcaSMauro Carvalho Chehab:c:type:`v4l2_plane` in the multi-planar API case). The 3754f38fcaSMauro Carvalho Chehabdriver must be switched into DMABUF I/O mode by calling the 3854f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>` with the desired buffer type. 3954f38fcaSMauro Carvalho Chehab 4054f38fcaSMauro Carvalho ChehabExample: Initiating streaming I/O with DMABUF file descriptors 4154f38fcaSMauro Carvalho Chehab============================================================== 4254f38fcaSMauro Carvalho Chehab 4354f38fcaSMauro Carvalho Chehab.. code-block:: c 4454f38fcaSMauro Carvalho Chehab 4554f38fcaSMauro Carvalho Chehab struct v4l2_requestbuffers reqbuf; 4654f38fcaSMauro Carvalho Chehab 4754f38fcaSMauro Carvalho Chehab memset(&reqbuf, 0, sizeof (reqbuf)); 4854f38fcaSMauro Carvalho Chehab reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 4954f38fcaSMauro Carvalho Chehab reqbuf.memory = V4L2_MEMORY_DMABUF; 5054f38fcaSMauro Carvalho Chehab reqbuf.count = 1; 5154f38fcaSMauro Carvalho Chehab 5254f38fcaSMauro Carvalho Chehab if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) { 5354f38fcaSMauro Carvalho Chehab if (errno == EINVAL) 5454f38fcaSMauro Carvalho Chehab printf("Video capturing or DMABUF streaming is not supported\\n"); 5554f38fcaSMauro Carvalho Chehab else 5654f38fcaSMauro Carvalho Chehab perror("VIDIOC_REQBUFS"); 5754f38fcaSMauro Carvalho Chehab 5854f38fcaSMauro Carvalho Chehab exit(EXIT_FAILURE); 5954f38fcaSMauro Carvalho Chehab } 6054f38fcaSMauro Carvalho Chehab 6154f38fcaSMauro Carvalho ChehabThe buffer (plane) file descriptor is passed on the fly with the 6254f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_QBUF <VIDIOC_QBUF>` ioctl. In case of multiplanar 6354f38fcaSMauro Carvalho Chehabbuffers, every plane can be associated with a different DMABUF 6454f38fcaSMauro Carvalho Chehabdescriptor. Although buffers are commonly cycled, applications can pass 6554f38fcaSMauro Carvalho Chehaba different DMABUF descriptor at each :ref:`VIDIOC_QBUF <VIDIOC_QBUF>` call. 6654f38fcaSMauro Carvalho Chehab 6754f38fcaSMauro Carvalho ChehabExample: Queueing DMABUF using single plane API 6854f38fcaSMauro Carvalho Chehab=============================================== 6954f38fcaSMauro Carvalho Chehab 7054f38fcaSMauro Carvalho Chehab.. code-block:: c 7154f38fcaSMauro Carvalho Chehab 7254f38fcaSMauro Carvalho Chehab int buffer_queue(int v4lfd, int index, int dmafd) 7354f38fcaSMauro Carvalho Chehab { 7454f38fcaSMauro Carvalho Chehab struct v4l2_buffer buf; 7554f38fcaSMauro Carvalho Chehab 7654f38fcaSMauro Carvalho Chehab memset(&buf, 0, sizeof buf); 7754f38fcaSMauro Carvalho Chehab buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 7854f38fcaSMauro Carvalho Chehab buf.memory = V4L2_MEMORY_DMABUF; 7954f38fcaSMauro Carvalho Chehab buf.index = index; 8054f38fcaSMauro Carvalho Chehab buf.m.fd = dmafd; 8154f38fcaSMauro Carvalho Chehab 8254f38fcaSMauro Carvalho Chehab if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) { 8354f38fcaSMauro Carvalho Chehab perror("VIDIOC_QBUF"); 8454f38fcaSMauro Carvalho Chehab return -1; 8554f38fcaSMauro Carvalho Chehab } 8654f38fcaSMauro Carvalho Chehab 8754f38fcaSMauro Carvalho Chehab return 0; 8854f38fcaSMauro Carvalho Chehab } 8954f38fcaSMauro Carvalho Chehab 9054f38fcaSMauro Carvalho ChehabExample 3.6. Queueing DMABUF using multi plane API 9154f38fcaSMauro Carvalho Chehab================================================== 9254f38fcaSMauro Carvalho Chehab 9354f38fcaSMauro Carvalho Chehab.. code-block:: c 9454f38fcaSMauro Carvalho Chehab 9554f38fcaSMauro Carvalho Chehab int buffer_queue_mp(int v4lfd, int index, int dmafd[], int n_planes) 9654f38fcaSMauro Carvalho Chehab { 9754f38fcaSMauro Carvalho Chehab struct v4l2_buffer buf; 9854f38fcaSMauro Carvalho Chehab struct v4l2_plane planes[VIDEO_MAX_PLANES]; 9954f38fcaSMauro Carvalho Chehab int i; 10054f38fcaSMauro Carvalho Chehab 10154f38fcaSMauro Carvalho Chehab memset(&buf, 0, sizeof buf); 10254f38fcaSMauro Carvalho Chehab buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; 10354f38fcaSMauro Carvalho Chehab buf.memory = V4L2_MEMORY_DMABUF; 10454f38fcaSMauro Carvalho Chehab buf.index = index; 10554f38fcaSMauro Carvalho Chehab buf.m.planes = planes; 10654f38fcaSMauro Carvalho Chehab buf.length = n_planes; 10754f38fcaSMauro Carvalho Chehab 10854f38fcaSMauro Carvalho Chehab memset(&planes, 0, sizeof planes); 10954f38fcaSMauro Carvalho Chehab 11054f38fcaSMauro Carvalho Chehab for (i = 0; i < n_planes; ++i) 11154f38fcaSMauro Carvalho Chehab buf.m.planes[i].m.fd = dmafd[i]; 11254f38fcaSMauro Carvalho Chehab 11354f38fcaSMauro Carvalho Chehab if (ioctl(v4lfd, VIDIOC_QBUF, &buf) == -1) { 11454f38fcaSMauro Carvalho Chehab perror("VIDIOC_QBUF"); 11554f38fcaSMauro Carvalho Chehab return -1; 11654f38fcaSMauro Carvalho Chehab } 11754f38fcaSMauro Carvalho Chehab 11854f38fcaSMauro Carvalho Chehab return 0; 11954f38fcaSMauro Carvalho Chehab } 12054f38fcaSMauro Carvalho Chehab 12154f38fcaSMauro Carvalho ChehabCaptured or displayed buffers are dequeued with the 12254f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` ioctl. The driver can unlock the 12354f38fcaSMauro Carvalho Chehabbuffer at any time between the completion of the DMA and this ioctl. The 12454f38fcaSMauro Carvalho Chehabmemory is also unlocked when 12554f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` is called, 12654f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, or when the device is closed. 12754f38fcaSMauro Carvalho Chehab 12854f38fcaSMauro Carvalho ChehabFor capturing applications it is customary to enqueue a number of empty 12954f38fcaSMauro Carvalho Chehabbuffers, to start capturing and enter the read loop. Here the 13054f38fcaSMauro Carvalho Chehabapplication waits until a filled buffer can be dequeued, and re-enqueues 13154f38fcaSMauro Carvalho Chehabthe buffer when the data is no longer needed. Output applications fill 13254f38fcaSMauro Carvalho Chehaband enqueue buffers, when enough buffers are stacked up output is 13354f38fcaSMauro Carvalho Chehabstarted. In the write loop, when the application runs out of free 13454f38fcaSMauro Carvalho Chehabbuffers it must wait until an empty buffer can be dequeued and reused. 13554f38fcaSMauro Carvalho ChehabTwo methods exist to suspend execution of the application until one or 13654f38fcaSMauro Carvalho Chehabmore buffers can be dequeued. By default :ref:`VIDIOC_DQBUF 13754f38fcaSMauro Carvalho Chehab<VIDIOC_QBUF>` blocks when no buffer is in the outgoing queue. When the 138*407e84cdSMauro Carvalho Chehab``O_NONBLOCK`` flag was given to the :c:func:`open()` function, 13954f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>` returns immediately with an ``EAGAIN`` 14054f38fcaSMauro Carvalho Chehaberror code when no buffer is available. The 141*407e84cdSMauro Carvalho Chehab:c:func:`select()` and :c:func:`poll()` 14254f38fcaSMauro Carvalho Chehabfunctions are always available. 14354f38fcaSMauro Carvalho Chehab 14454f38fcaSMauro Carvalho ChehabTo start and stop capturing or displaying applications call the 14554f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_STREAMON <VIDIOC_STREAMON>` and 14654f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls. 14754f38fcaSMauro Carvalho Chehab 14854f38fcaSMauro Carvalho Chehab.. note:: 14954f38fcaSMauro Carvalho Chehab 15054f38fcaSMauro Carvalho Chehab :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` removes all buffers from 15154f38fcaSMauro Carvalho Chehab both queues and unlocks all buffers as a side effect. Since there is no 15254f38fcaSMauro Carvalho Chehab notion of doing anything "now" on a multitasking system, if an 15354f38fcaSMauro Carvalho Chehab application needs to synchronize with another event it should examine 15454f38fcaSMauro Carvalho Chehab the struct :c:type:`v4l2_buffer` ``timestamp`` of captured or 15554f38fcaSMauro Carvalho Chehab outputted buffers. 15654f38fcaSMauro Carvalho Chehab 15754f38fcaSMauro Carvalho ChehabDrivers implementing DMABUF importing I/O must support the 15854f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_REQBUFS <VIDIOC_REQBUFS>`, :ref:`VIDIOC_QBUF <VIDIOC_QBUF>`, 15954f38fcaSMauro Carvalho Chehab:ref:`VIDIOC_DQBUF <VIDIOC_QBUF>`, :ref:`VIDIOC_STREAMON 16054f38fcaSMauro Carvalho Chehab<VIDIOC_STREAMON>` and :ref:`VIDIOC_STREAMOFF <VIDIOC_STREAMON>` ioctls, 161*407e84cdSMauro Carvalho Chehaband the :c:func:`select()` and :c:func:`poll()` 16254f38fcaSMauro Carvalho Chehabfunctions. 163