fdmemory: add flags to control behaviour

Add some flags to the GstFdMemory to control how memory is mapped and
unmapped.
This commit is contained in:
Wim Taymans 2015-03-15 17:27:33 +01:00
parent fabf4890b8
commit e6cb520036
3 changed files with 40 additions and 9 deletions

View file

@ -120,7 +120,7 @@ gst_dmabuf_allocator_alloc (GstAllocator * allocator, gint fd, gsize size)
} }
GST_DEBUG ("alloc from allocator %p", allocator); 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 */ #else /* !HAVE_MMAP */
return NULL; return NULL;
#endif #endif

View file

@ -36,7 +36,10 @@ gst_fd_mem_free (GstAllocator * allocator, GstMemory * gmem)
GstFdMemory *mem = (GstFdMemory *) gmem; GstFdMemory *mem = (GstFdMemory *) gmem;
if (mem->data) { 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); munmap ((void *) mem->data, gmem->maxsize);
} }
if (mem->fd >= 0 && gmem->parent == NULL) if (mem->fd >= 0 && gmem->parent == NULL)
@ -58,11 +61,10 @@ gst_fd_mem_map (GstMemory * gmem, gsize maxsize, GstMapFlags flags)
if (gmem->parent) if (gmem->parent)
return gst_fd_mem_map (gmem->parent, maxsize, flags); 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_READ ? PROT_READ : 0;
prot |= flags & GST_MAP_WRITE ? PROT_WRITE : 0; prot |= flags & GST_MAP_WRITE ? PROT_WRITE : 0;
g_mutex_lock (&mem->lock);
/* do not mmap twice the buffer */ /* do not mmap twice the buffer */
if (mem->data) { if (mem->data) {
/* only return address if mapping flags are a subset /* 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) { 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) { if (mem->data == MAP_FAILED) {
mem->data = NULL; mem->data = NULL;
GST_ERROR ("%p: fd %d: mmap failed: %s", mem, mem->fd, GST_ERROR ("%p: fd %d: mmap failed: %s", mem, mem->fd,
@ -110,8 +118,10 @@ gst_fd_mem_unmap (GstMemory * gmem)
if (gmem->parent) if (gmem->parent)
return gst_fd_mem_unmap (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)) { if (mem->data && !(--mem->mmap_count)) {
munmap ((void *) mem->data, gmem->maxsize); munmap ((void *) mem->data, gmem->maxsize);
mem->data = NULL; 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 * @allocator: allocator to be used for this memory
* @fd: file descriptor * @fd: file descriptor
* @size: memory size * @size: memory size
* @flags: extra #GstFdMemoryFlags
* *
* Return a %GstMemory that wraps a file descriptor. * 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 * Since: 1.2
*/ */
GstMemory * 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 #ifdef HAVE_MMAP
GstFdMemory *mem; GstFdMemory *mem;
@ -178,6 +190,7 @@ __gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size)
mem = g_slice_new0 (GstFdMemory); mem = g_slice_new0 (GstFdMemory);
gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, NULL, size, 0, 0, size); gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, NULL, size, 0, 0, size);
mem->flags = flags;
mem->fd = fd; mem->fd = fd;
g_mutex_init (&mem->lock); g_mutex_init (&mem->lock);

View file

@ -25,8 +25,24 @@
G_BEGIN_DECLS 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 * @fd: the file descriptor associated this memory
* @data: mmapped address * @data: mmapped address
* @mmapping_flags: mmapping flags * @mmapping_flags: mmapping flags
@ -37,6 +53,7 @@ typedef struct
{ {
GstMemory mem; GstMemory mem;
GstFdMemoryFlags flags;
gint fd; gint fd;
gpointer data; gpointer data;
gint mmapping_flags; gint mmapping_flags;
@ -47,7 +64,8 @@ typedef struct
void __gst_fd_memory_class_init_allocator (GstAllocatorClass * allocator); void __gst_fd_memory_class_init_allocator (GstAllocatorClass * allocator);
void __gst_fd_memory_init_allocator (GstAllocator * allocator, const gchar *type); 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 G_END_DECLS