diff --git a/configure.ac b/configure.ac index 67ebb75325..cca8233d0d 100644 --- a/configure.ac +++ b/configure.ac @@ -486,6 +486,9 @@ esac dnl Check for mmap (needed by allocators library) AC_CHECK_FUNC([mmap], [AC_DEFINE(HAVE_MMAP, 1, [Defined if mmap is supported])]) +dnl Check for DMABuf synchronization ioctl (needed for DMABuf CPU access) +AC_CHECK_HEADERS([linux/dma-buf.h], []) + dnl *** plug-ins to include *** dnl these are all the gst plug-ins, compilable without additional libs diff --git a/gst-libs/gst/allocators/gstdmabuf.c b/gst-libs/gst/allocators/gstdmabuf.c index 170267be5f..e9c5dd3736 100644 --- a/gst-libs/gst/allocators/gstdmabuf.c +++ b/gst-libs/gst/allocators/gstdmabuf.c @@ -34,9 +34,9 @@ * Since: 1.2 */ -#ifdef HAVE_MMAP -#include -#include +#ifdef HAVE_LINUX_DMA_BUF_H +#include +#include #endif GST_DEBUG_CATEGORY_STATIC (dmabuf_debug); @@ -44,6 +44,57 @@ GST_DEBUG_CATEGORY_STATIC (dmabuf_debug); G_DEFINE_TYPE (GstDmaBufAllocator, gst_dmabuf_allocator, GST_TYPE_FD_ALLOCATOR); +static gpointer +gst_dmabuf_mem_map (GstMemory * gmem, GstMapInfo * info, gsize maxsize) +{ + GstAllocator *allocator = gmem->allocator; +#ifdef HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync = { DMA_BUF_SYNC_START }; + gpointer ret; + + if (info->flags & GST_MAP_READ) + sync.flags |= DMA_BUF_SYNC_READ; + + if (info->flags & GST_MAP_WRITE) + sync.flags |= DMA_BUF_SYNC_WRITE; +#endif + + ret = allocator->mem_map (gmem, maxsize, info->flags); + +#ifdef HAVE_LINUX_DMA_BUF_H + if (ret) { + if (ioctl (gst_fd_memory_get_fd (gmem), DMA_BUF_IOCTL_SYNC, &sync) < 0) + GST_WARNING_OBJECT (allocator, "Failed to synchronize DMABuf: %s (%i)", + g_strerror (errno), errno); + } +#endif + + return ret; +} + +static void +gst_dmabuf_mem_unmap (GstMemory * gmem, GstMapInfo * info) +{ + GstAllocator *allocator = gmem->allocator; +#ifdef HAVE_LINUX_DMA_BUF_H + struct dma_buf_sync sync = { DMA_BUF_SYNC_END }; + + if (info->flags & GST_MAP_READ) + sync.flags |= DMA_BUF_SYNC_READ; + + if (info->flags & GST_MAP_WRITE) + sync.flags |= DMA_BUF_SYNC_WRITE; + + if (ioctl (gst_fd_memory_get_fd (gmem), DMA_BUF_IOCTL_SYNC, &sync) < 0) + GST_WARNING_OBJECT (allocator, "Failed to synchronize DMABuf: %s (%i)", + g_strerror (errno), errno); +#else + GST_WARNING_OBJECT (allocator, "Using DMABuf without synchronization."); +#endif + + allocator->mem_unmap (gmem); +} + static void gst_dmabuf_allocator_class_init (GstDmaBufAllocatorClass * klass) { @@ -55,6 +106,8 @@ gst_dmabuf_allocator_init (GstDmaBufAllocator * allocator) GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator); alloc->mem_type = GST_ALLOCATOR_DMABUF; + alloc->mem_map_full = gst_dmabuf_mem_map; + alloc->mem_unmap_full = gst_dmabuf_mem_unmap; } /** diff --git a/meson.build b/meson.build index 344f25f8bf..5c268112b4 100644 --- a/meson.build +++ b/meson.build @@ -79,6 +79,7 @@ check_headers = [ ['HAVE_UNISTD_H', 'unistd.h'], ['HAVE_WINSOCK2_H', 'winsock2.h'], ['HAVE_XMMINTRIN_H', 'xmmintrin.h'], + ['HAVE_LINUX_DMA_BUF_H', 'linux/dma-buf.h'], ] foreach h : check_headers if cc.has_header(h.get(1))