* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include "config.h"
+
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
+/* This was introduced in version 4.6. And may not exist all without an
+ * optional package. So to prevent a hard dependency on needing the Linux
+ * kernel headers to compile, make this optional. */
+#if HAVE_LINUX_DMA_BUF_H
+#include <linux/dma-buf.h>
+#include <sys/ioctl.h>
+#endif
+
#include <drm.h>
#include <xf86drm.h>
typedef struct DRMMapping {
// Address and length of each mmap()ed region.
int nb_regions;
+ int sync_flags;
+ int object[AV_DRM_MAX_PLANES];
void *address[AV_DRM_MAX_PLANES];
size_t length[AV_DRM_MAX_PLANES];
} DRMMapping;
HWMapDescriptor *hwmap)
{
DRMMapping *map = hwmap->priv;
- int i;
- for (i = 0; i < map->nb_regions; i++)
+ for (int i = 0; i < map->nb_regions; i++) {
+#if HAVE_LINUX_DMA_BUF_H
+ struct dma_buf_sync sync = { .flags = DMA_BUF_SYNC_END | map->sync_flags };
+ ioctl(map->object[i], DMA_BUF_IOCTL_SYNC, &sync);
+#endif
munmap(map->address[i], map->length[i]);
+ }
av_free(map);
}
AVFrame *dst, const AVFrame *src, int flags)
{
const AVDRMFrameDescriptor *desc = (AVDRMFrameDescriptor*)src->data[0];
+#if HAVE_LINUX_DMA_BUF_H
+ struct dma_buf_sync sync_start = { 0 };
+#endif
DRMMapping *map;
int err, i, p, plane;
int mmap_prot;
if (flags & AV_HWFRAME_MAP_WRITE)
mmap_prot |= PROT_WRITE;
+#if HAVE_LINUX_DMA_BUF_H
+ if (flags & AV_HWFRAME_MAP_READ)
+ map->sync_flags |= DMA_BUF_SYNC_READ;
+ if (flags & AV_HWFRAME_MAP_WRITE)
+ map->sync_flags |= DMA_BUF_SYNC_WRITE;
+ sync_start.flags = DMA_BUF_SYNC_START | map->sync_flags;
+#endif
+
av_assert0(desc->nb_objects <= AV_DRM_MAX_PLANES);
for (i = 0; i < desc->nb_objects; i++) {
addr = mmap(NULL, desc->objects[i].size, mmap_prot, MAP_SHARED,
map->address[i] = addr;
map->length[i] = desc->objects[i].size;
+ map->object[i] = desc->objects[i].fd;
+
+#if HAVE_LINUX_DMA_BUF_H
+ /* We're not checking for errors here because the kernel may not
+ * support the ioctl, in which case its okay to carry on */
+ ioctl(desc->objects[i].fd, DMA_BUF_IOCTL_SYNC, &sync_start);
+#endif
}
map->nb_regions = i;