fdmemory: make a base class for allocating fd-backed memory

Make a base class that can help with allocating fd-backed memory.
Make dmabuf extend from the base class.
We can now make methods to check if memory has an fd and get the fd for
all the different types of fd-backed memory.
This commit is contained in:
Wim Taymans 2015-03-18 15:12:03 +01:00
parent 15cc12b0b9
commit 3205e90e83
4 changed files with 120 additions and 84 deletions

View file

@ -4,9 +4,10 @@ libgstallocators_@GST_API_VERSION@_includedir = $(includedir)/gstreamer-@GST_API
libgstallocators_@GST_API_VERSION@_include_HEADERS = \
allocators.h \
gstfdmemory.h \
gstdmabuf.h
noinst_HEADERS = gstfdmemory.h
noinst_HEADERS =
libgstallocators_@GST_API_VERSION@_la_SOURCES = \
gstfdmemory.c \

View file

@ -43,16 +43,16 @@ GST_DEBUG_CATEGORY_STATIC (dmabuf_debug);
typedef struct
{
GstAllocator parent;
GstFdAllocator parent;
} GstDmaBufAllocator;
typedef struct
{
GstAllocatorClass parent_class;
GstFdAllocatorClass parent_class;
} GstDmaBufAllocatorClass;
GType dmabuf_mem_allocator_get_type (void);
G_DEFINE_TYPE (GstDmaBufAllocator, dmabuf_mem_allocator, GST_TYPE_ALLOCATOR);
G_DEFINE_TYPE (GstDmaBufAllocator, dmabuf_mem_allocator, GST_TYPE_FD_ALLOCATOR);
#define GST_TYPE_DMABUF_ALLOCATOR (dmabuf_mem_allocator_get_type())
#define GST_IS_DMABUF_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DMABUF_ALLOCATOR))
@ -60,11 +60,6 @@ G_DEFINE_TYPE (GstDmaBufAllocator, dmabuf_mem_allocator, GST_TYPE_ALLOCATOR);
static void
dmabuf_mem_allocator_class_init (GstDmaBufAllocatorClass * klass)
{
GstAllocatorClass *allocator_class;
allocator_class = (GstAllocatorClass *) klass;
__gst_fd_memory_class_init_allocator (allocator_class);
}
static void
@ -72,9 +67,7 @@ dmabuf_mem_allocator_init (GstDmaBufAllocator * allocator)
{
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
__gst_fd_memory_init_allocator (alloc, GST_ALLOCATOR_DMABUF);
GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
alloc->mem_type = GST_ALLOCATOR_DMABUF;
}
/**
@ -113,17 +106,16 @@ gst_dmabuf_allocator_new (void)
GstMemory *
gst_dmabuf_allocator_alloc (GstAllocator * allocator, gint fd, gsize size)
{
#ifdef HAVE_MMAP
GstFdAllocator *alloc = GST_FD_ALLOCATOR_CAST (allocator);
GstFdAllocatorClass *klass = GST_FD_ALLOCATOR_GET_CLASS (alloc);
if (!GST_IS_DMABUF_ALLOCATOR (allocator)) {
GST_WARNING ("it isn't the correct allocator for dmabuf");
return NULL;
}
GST_DEBUG ("alloc from allocator %p", allocator);
return __gst_fd_memory_new (allocator, fd, size, GST_FD_MEMORY_FLAG_NONE);
#else /* !HAVE_MMAP */
return NULL;
#endif
return klass->alloc (alloc, fd, size, GST_FD_MEMORY_FLAG_NONE);
}
/**
@ -141,11 +133,9 @@ gst_dmabuf_allocator_alloc (GstAllocator * allocator, gint fd, gsize size)
gint
gst_dmabuf_memory_get_fd (GstMemory * mem)
{
GstFdMemory *fdmem = (GstFdMemory *) mem;
g_return_val_if_fail (gst_is_dmabuf_memory (mem), -1);
return fdmem->fd;
return gst_fd_memory_get_fd (mem);
}
/**

View file

@ -29,6 +29,18 @@
#include <unistd.h>
#endif
typedef struct
{
GstMemory mem;
GstFdMemoryFlags flags;
gint fd;
gpointer data;
gint mmapping_flags;
gint mmap_count;
GMutex lock;
} GstFdMemory;
static void
gst_fd_mem_free (GstAllocator * allocator, GstMemory * gmem)
{
@ -165,30 +177,16 @@ gst_fd_mem_share (GstMemory * gmem, gssize offset, gssize size)
#endif
}
/**
* gst_fd_memory_new:
* @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.
*
* Returns: (transfer full): a GstMemory based on @allocator.
* When the buffer is released, @fd is closed.
* The memory is only mmapped on gst_buffer_mmap() request.
*
* Since: 1.2
*/
GstMemory *
__gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size,
static GstMemory *
gst_fd_allocator_alloc (GstFdAllocator * allocator, gint fd, gsize size,
GstFdMemoryFlags flags)
{
#ifdef HAVE_MMAP
GstFdMemory *mem;
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, GST_ALLOCATOR_CAST (allocator),
NULL, size, 0, 0, size);
mem->flags = flags;
mem->fd = fd;
@ -203,33 +201,68 @@ __gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size,
#endif
}
/**
* gst_fd_memory_class_init_allocator:
* @allocator: a #GstAllocatorClass
*
* Sets up the methods to alloc and free fd backed memory created
* with @gst_fd_memory_new by @allocator.
*/
void
__gst_fd_memory_class_init_allocator (GstAllocatorClass * allocator)
G_DEFINE_ABSTRACT_TYPE (GstFdAllocator, gst_fd_allocator, GST_TYPE_ALLOCATOR);
static void
gst_fd_allocator_class_init (GstFdAllocatorClass * klass)
{
allocator->alloc = NULL;
allocator->free = gst_fd_mem_free;
GstAllocatorClass *allocator_class;
allocator_class = (GstAllocatorClass *) klass;
allocator_class->alloc = NULL;
allocator_class->free = gst_fd_mem_free;
klass->alloc = gst_fd_allocator_alloc;
}
static void
gst_fd_allocator_init (GstFdAllocator * allocator)
{
GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
alloc->mem_map = gst_fd_mem_map;
alloc->mem_unmap = gst_fd_mem_unmap;
alloc->mem_share = gst_fd_mem_share;
GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
}
/**
* gst_fd_memory_init_allocator:
* @allocator: a #GstAllocator
* @type: the memory type
* gst_is_fd_memory:
* @mem: #GstMemory
*
* Sets up the methods to map and unmap and share fd backed memory
* created with @allocator.
* Check if @mem is memory backed by an fd
*
* Returns: %TRUE when @mem has an fd that can be retrieved with
* gst_fd_memory_get_fd().
*
* Since: 1.6
*/
void
__gst_fd_memory_init_allocator (GstAllocator * allocator, const gchar * type)
gboolean
gst_is_fd_memory (GstMemory * mem)
{
allocator->mem_type = type;
allocator->mem_map = gst_fd_mem_map;
allocator->mem_unmap = gst_fd_mem_unmap;
allocator->mem_share = gst_fd_mem_share;
g_return_val_if_fail (mem != NULL, FALSE);
return GST_IS_FD_ALLOCATOR (mem->allocator);
}
/**
* gst_fd_memory_get_fd:
* @mem: #GstMemory
*
* Get the fd from @mem. Call gst_is_fd_memory() to check if @mem has
* an fd.
*
* Returns: the fd of @mem or -1 when there is no fd on @mem
*
* Since: 1.6
*/
gint
gst_fd_memory_get_fd (GstMemory * mem)
{
g_return_val_if_fail (mem != NULL, -1);
g_return_val_if_fail (GST_IS_FD_ALLOCATOR (mem->allocator), -1);
return ((GstFdMemory *) mem)->fd;
}

View file

@ -18,13 +18,24 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_FD_MEMORY_H__
#define __GST_FD_MEMORY_H__
#ifndef __GST_FD_ALLOCATOR_H__
#define __GST_FD_ALLOCATOR_H__
#include <gst/gst.h>
G_BEGIN_DECLS
typedef struct _GstFdAllocator GstFdAllocator;
typedef struct _GstFdAllocatorClass GstFdAllocatorClass;
#define GST_TYPE_FD_ALLOCATOR (gst_fd_allocator_get_type())
#define GST_IS_FD_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_FD_ALLOCATOR))
#define GST_IS_FD_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_FD_ALLOCATOR))
#define GST_FD_ALLOCATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_FD_ALLOCATOR, GstFdAllocatorClass))
#define GST_FD_ALLOCATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_FD_ALLOCATOR, GstFdAllocator))
#define GST_FD_ALLOCATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_FD_ALLOCATOR, GstFdAllocatorClass))
#define GST_FD_ALLOCATOR_CAST(obj) ((GstFdAllocator *)(obj))
/**
* @GST_FD_MEMORY_FLAG_NONE: no flag
* @GST_FD_MEMORY_FLAG_KEEP_MAPPED: once the memory is mapped,
@ -33,6 +44,8 @@ G_BEGIN_DECLS
* the default shared mapping.
*
* Various flags to control the operation of the fd backed memory.
*
* Since: 1.6
*/
typedef enum {
GST_FD_MEMORY_FLAG_NONE = 0,
@ -40,33 +53,32 @@ typedef enum {
GST_FD_MEMORY_FLAG_MAP_PRIVATE = (1 << 1),
} GstFdMemoryFlags;
/*
* GstFdMemory
* @flags: #GstFdMemoryFlags
* @fd: the file descriptor associated this memory
* @data: mmapped address
* @mmapping_flags: mmapping flags
* @mmap_count: mmapping counter
* @lock: a mutex to make mmapping thread safe
/**
* GstFdAllocator:
*
* Base class for allocators with fd-backed memory
*
* Since: 1.6
*/
typedef struct
struct _GstFdAllocator
{
GstMemory mem;
GstAllocator parent;
};
GstFdMemoryFlags flags;
gint fd;
gpointer data;
gint mmapping_flags;
gint mmap_count;
GMutex lock;
} GstFdMemory;
struct _GstFdAllocatorClass
{
GstAllocatorClass parent_class;
void __gst_fd_memory_class_init_allocator (GstAllocatorClass * allocator);
void __gst_fd_memory_init_allocator (GstAllocator * allocator, const gchar *type);
/*< protected >*/
GstMemory * (*alloc) (GstFdAllocator *alloc, gint fd,
gsize size, GstFdMemoryFlags flags);
};
GstMemory * __gst_fd_memory_new (GstAllocator * allocator, gint fd, gsize size,
GstFdMemoryFlags flags);
GType gst_fd_allocator_get_type (void);
gboolean gst_is_fd_memory (GstMemory *mem);
gint gst_fd_memory_get_fd (GstMemory *mem);
G_END_DECLS
#endif /* __GST_FD_MEMORY_H__ */
#endif /* __GST_FD_ALLOCATOR_H__ */