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
42
43
45 {
47
49 }
50
53 {
56
57 hwctx->
fd = open(device, O_RDWR);
60
64 "from %s: probably not a DRM device?\n", device);
67 }
68
70 "version %d.%d.%d.\n", device,
version->name,
73
75
77
78 return 0;
79 }
80
82 {
86
87 frame->data[0] = (uint8_t*)
frame->buf[0]->data;
88
92
93 return 0;
94 }
95
97 // Address and length of each mmap()ed region.
104
107 {
109
110 for (
int i = 0;
i <
map->nb_regions;
i++) {
111 #if HAVE_LINUX_DMA_BUF_H
112 struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END |
map->sync_flags };
113 ioctl(
map->object[
i], DMA_BUF_IOCTL_SYNC, &sync);
114 #endif
115 munmap(
map->address[
i],
map->length[
i]);
116 }
117
119 }
120
123 {
125 #if HAVE_LINUX_DMA_BUF_H
126 struct dma_buf_sync sync_start = { 0 };
127 #endif
129 int err,
i, p, plane;
130 int mmap_prot;
131 void *addr;
132
136
137 mmap_prot = 0;
139 mmap_prot |= PROT_READ;
141 mmap_prot |= PROT_WRITE;
142
143 #if HAVE_LINUX_DMA_BUF_H
145 map->sync_flags |= DMA_BUF_SYNC_READ;
147 map->sync_flags |= DMA_BUF_SYNC_WRITE;
148 sync_start.flags = DMA_BUF_SYNC_START |
map->sync_flags;
149 #endif
150
152 for (
i = 0;
i <
desc->nb_objects;
i++) {
153 addr = mmap(
NULL,
desc->objects[
i].size, mmap_prot, MAP_SHARED,
154 desc->objects[
i].fd, 0);
155 if (addr == MAP_FAILED) {
158 "memory: %d.\n",
desc->objects[
i].fd, errno);
160 }
161
162 map->address[
i] = addr;
165
166 #if HAVE_LINUX_DMA_BUF_H
167 /* We're not checking for errors here because the kernel may not
168 * support the ioctl, in which case its okay to carry on */
169 ioctl(
desc->objects[
i].fd, DMA_BUF_IOCTL_SYNC, &sync_start);
170 #endif
171 }
173
174 plane = 0;
175 for (
i = 0;
i <
desc->nb_layers;
i++) {
182 ++plane;
183 }
184 }
186
188 dst->height =
src->height;
189
192 if (err < 0)
194
195 return 0;
196
198 for (
i = 0;
i <
desc->nb_objects;
i++) {
200 munmap(
map->address[
i],
map->length[
i]);
201 }
203 return err;
204 }
205
209 {
211
215
218
220 return 0;
221 }
222
225 {
227 int err;
228
231
235 map->format =
dst->format;
236
238 if (err)
240
242 map->height =
dst->height;
243
245 if (err)
247
248 err = 0;
251 return err;
252 }
253
256 {
258 int err;
259
262
266 map->format =
src->format;
267
270 if (err)
272
274 map->height =
src->height;
275
277 if (err)
279
280 err = 0;
283 return err;
284 }
285
288 {
289 int err;
290
293
295 if (err)
296 return err;
297
299 if (err)
300 return err;
301
302 return 0;
303 }
304
307 .name = "DRM",
308
310
312
314
319
323 },
324 };