From e6cb5200366a5134ffefb79f0be578237ffe5c95 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Sun, 15 Mar 2015 17:27:33 +0100 Subject: [PATCH] fdmemory: add flags to control behaviour Add some flags to the GstFdMemory to control how memory is mapped and unmapped. --- gst-libs/gst/allocators/gstdmabuf.c | 2 +- gst-libs/gst/allocators/gstfdmemory.c | 25 +++++++++++++++++++------ gst-libs/gst/allocators/gstfdmemory.h | 22 ++++++++++++++++++++-- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/gst-libs/gst/allocators/gstdmabuf.c b/gst-libs/gst/allocators/gstdmabuf.c index 76bff24707..84e0c7844c 100644 --- a/gst-libs/gst/allocators/gstdmabuf.c +++ b/gst-libs/gst/allocators/gstdmabuf.c @@ -120,7 +120,7 @@ gst_dmabuf_allocator_alloc (GstAllocator * allocator, gint fd, gsize size) } GST_DEBUG ("alloc from allocator %p", allocator); - return __gst_fd_memory_new (allocator, fd, size); + return __gst_fd_memory_new (allocator, fd, size, GST_FD_MEMORY_FLAG_NONE); #else /* !HAVE_MMAP */ return NULL; #endif diff --git a/gst-libs/gst/allocators/gstfdmemory.c b/gst-libs/gst/allocators/gstfdmemory.c index bdd95fc28e..9a5c5b3ca8 100644 --- a/gst-libs/gst/allocators/gstfdmemory.c +++ b/gst-libs/gst/allocators/gstfdmemory.c @@ -36,7 +36,10 @@ gst_fd_mem_free (GstAllocator * allocator, GstMemory * gmem) GstFdMemory *mem = (GstFdMemory *) gmem; if (mem->data) { - g_warning (G_STRLOC ":%s: Freeing memory %p still mapped", G_STRFUNC, mem); + if (!(mem->flags & GST_FD_MEMORY_FLAG_KEEP_MAPPED)) + g_warning (G_STRLOC ":%s: Freeing memory %p still mapped", G_STRFUNC, + mem); + munmap ((void *) mem->data, gmem->maxsize); } if (mem->fd >= 0 && gmem->parent == NULL) @@ -58,11 +61,10 @@ gst_fd_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags) if (gmem->parent) return gst_fd_mem_map (gmem->parent, maxsize, flags); - g_mutex_lock (&mem->lock); - prot = flags & GST_MAP_READ ? PROT_READ : 0; prot |= flags & GST_MAP_WRITE ? PROT_WRITE : 0; + g_mutex_lock (&mem->lock); /* do not mmap twice the buffer */ if (mem->data) { /* only return address if mapping flags are a subset @@ -76,7 +78,13 @@ gst_fd_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags) } if (mem->fd != -1) { - mem->data = mmap (0, gmem->maxsize, prot, MAP_SHARED, mem->fd, 0); + gint flags; + + flags = + (mem->flags & GST_FD_MEMORY_FLAG_MAP_PRIVATE) ? MAP_PRIVATE : + MAP_SHARED; + + mem->data = mmap (0, gmem->maxsize, prot, flags, mem->fd, 0); if (mem->data == MAP_FAILED) { mem->data = NULL; GST_ERROR ("%p: fd %d: mmap failed: %s", mem, mem->fd, @@ -110,8 +118,10 @@ gst_fd_mem_unmap (GstMemory * gmem) if (gmem->parent) return gst_fd_mem_unmap (gmem->parent); - g_mutex_lock (&mem->lock); + if (mem->flags & GST_FD_MEMORY_FLAG_KEEP_MAPPED) + return; + g_mutex_lock (&mem->lock); if (mem->data && !(--mem->mmap_count)) { munmap ((void *) mem->data, gmem->maxsize); mem->data = NULL; @@ -160,6 +170,7 @@ gst_fd_mem_share (GstMemory * gmem, gssize offset, gssize size) * @allocator: allocator to be used for this memory * @fd: file descriptor * @size: memory size + * @flags: extra #GstFdMemoryFlags * * Return a %GstMemory that wraps a file descriptor. * @@ -170,7 +181,8 @@ gst_fd_mem_share (GstMemory * gmem, gssize offset, gssize size) * Since: 1.2 */ GstMemory * -__gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size) +__gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size, + GstFdMemoryFlags flags) { #ifdef HAVE_MMAP GstFdMemory *mem; @@ -178,6 +190,7 @@ __gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size) mem = g_slice_new0 (GstFdMemory); gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, NULL, size, 0, 0, size); + mem->flags = flags; mem->fd = fd; g_mutex_init (&mem->lock); diff --git a/gst-libs/gst/allocators/gstfdmemory.h b/gst-libs/gst/allocators/gstfdmemory.h index d85bc43718..9f28332937 100644 --- a/gst-libs/gst/allocators/gstfdmemory.h +++ b/gst-libs/gst/allocators/gstfdmemory.h @@ -25,8 +25,24 @@ G_BEGIN_DECLS +/** + * @GST_FD_MEMORY_FLAG_NONE: no flag + * @GST_FD_MEMORY_FLAG_KEEP_MAPPED: once the memory is mapped, + * keep it mapped until the memory is destroyed. + * @GST_FD_MEMORY_FLAG_MAP_PRIVATE: do a private mapping instead of + * the default shared mapping. + * + * Various flags to control the operation of the fd backed memory. + */ +typedef enum { + GST_FD_MEMORY_FLAG_NONE = 0, + GST_FD_MEMORY_FLAG_KEEP_MAPPED = (1 << 0), + GST_FD_MEMORY_FLAG_MAP_PRIVATE = (1 << 1), +} GstFdMemoryFlags; + /* - * GstFdfMemory + * GstFdMemory + * @flags: #GstFdMemoryFlags * @fd: the file descriptor associated this memory * @data: mmapped address * @mmapping_flags: mmapping flags @@ -37,6 +53,7 @@ typedef struct { GstMemory mem; + GstFdMemoryFlags flags; gint fd; gpointer data; gint mmapping_flags; @@ -47,7 +64,8 @@ typedef struct void __gst_fd_memory_class_init_allocator (GstAllocatorClass * allocator); void __gst_fd_memory_init_allocator (GstAllocator * allocator, const gchar *type); -GstMemory * __gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size); +GstMemory * __gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size, + GstFdMemoryFlags flags); G_END_DECLS