1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "config.h"
20
21 #include <fcntl.h>
22 #include <sys/mman.h>
23 #include <unistd.h>
24
25 /* This was introduced in version 4.6. And may not exist all without an
26 * optional package. So to prevent a hard dependency on needing the Linux
27 * kernel headers to compile, make this optional. */
28 #if HAVE_LINUX_DMA_BUF_H
29 #include <linux/dma-buf.h>
30 #include <sys/ioctl.h>
31 #endif
32
33 #include <drm.h>
34 #include <xf86drm.h>
35
41
42
44 {
46
48 }
49
52 {
55
56 hwctx->
fd = open(device, O_RDWR);
59
63 "from %s: probably not a DRM device?\n", device);
66 }
67
69 "version %d.%d.%d.\n", device,
version->name,
72
74
76
77 return 0;
78 }
79
81 {
85
86 frame->data[0] = (uint8_t*)
frame->buf[0]->data;
87
91
92 return 0;
93 }
94
96 // Address and length of each mmap()ed region.
103
106 {
108
109 for (
int i = 0;
i <
map->nb_regions;
i++) {
110 #if HAVE_LINUX_DMA_BUF_H
111 struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END |
map->sync_flags };
112 ioctl(
map->object[
i], DMA_BUF_IOCTL_SYNC, &sync);
113 #endif
114 munmap(
map->address[
i],
map->length[
i]);
115 }
116
118 }
119
122 {
124 #if HAVE_LINUX_DMA_BUF_H
125 struct dma_buf_sync sync_start = { 0 };
126 #endif
128 int err,
i, p, plane;
129 int mmap_prot;
130 void *addr;
131
135
136 mmap_prot = 0;
138 mmap_prot |= PROT_READ;
140 mmap_prot |= PROT_WRITE;
141
142 #if HAVE_LINUX_DMA_BUF_H
144 map->sync_flags |= DMA_BUF_SYNC_READ;
146 map->sync_flags |= DMA_BUF_SYNC_WRITE;
147 sync_start.flags = DMA_BUF_SYNC_START |
map->sync_flags;
148 #endif
149
151 for (
i = 0;
i <
desc->nb_objects;
i++) {
152 addr = mmap(
NULL,
desc->objects[
i].size, mmap_prot, MAP_SHARED,
153 desc->objects[
i].fd, 0);
154 if (addr == MAP_FAILED) {
157 "memory: %d.\n",
desc->objects[
i].fd, errno);
159 }
160
161 map->address[
i] = addr;
164
165 #if HAVE_LINUX_DMA_BUF_H
166 /* We're not checking for errors here because the kernel may not
167 * support the ioctl, in which case its okay to carry on */
168 ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_SYNC, &sync_start);
169 #endif
170 }
172
173 plane = 0;
174 for (
i = 0;
i <
desc->nb_layers;
i++) {
177 dst->data[plane] =
181 ++plane;
182 }
183 }
185
186 dst->width =
src->width;
187 dst->height =
src->height;
188
191 if (err < 0)
193
194 return 0;
195
197 for (
i = 0;
i <
desc->nb_objects;
i++) {
199 munmap(
map->address[
i],
map->length[
i]);
200 }
202 return err;
203 }
204
208 {
210
214
217
219 return 0;
220 }
221
224 {
226 int err;
227
230
235
237 if (err)
239
242
244 if (err)
246
247 err = 0;
250 return err;
251 }
252
255 {
257 int err;
258
261
265 map->format =
src->format;
266
269 if (err)
271
273 map->height =
src->height;
274
276 if (err)
278
279 err = 0;
282 return err;
283 }
284
287 {
288 int err;
289
292
294 if (err)
295 return err;
296
298 if (err)
299 return err;
300
301 return 0;
302 }
303
306 .name = "DRM",
307
309
311
313
318
322 },
323 };