xref: /OK3568_Linux_fs/kernel/Documentation/userspace-api/media/v4l/dmabuf.rst (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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