fdmemory: make a base class for allocating fd-backed memory
authorWim Taymans <wtaymans@redhat.com>
Wed, 18 Mar 2015 14:12:03 +0000 (15:12 +0100)
committerWim Taymans <wtaymans@redhat.com>
Wed, 18 Mar 2015 14:12:03 +0000 (15:12 +0100)
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.

gst-libs/gst/allocators/Makefile.am
gst-libs/gst/allocators/gstdmabuf.c
gst-libs/gst/allocators/gstfdmemory.c
gst-libs/gst/allocators/gstfdmemory.h

index 1ff3800..e84ef9d 100644 (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 \
index 84e0c78..7dbceff 100644 (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);
 }
 
 /**
index 9a5c5b3..2a0e4f4 100644 (file)
 #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
 }
 
+G_DEFINE_ABSTRACT_TYPE (GstFdAllocator, gst_fd_allocator, GST_TYPE_ALLOCATOR);
+
+static void
+gst_fd_allocator_class_init (GstFdAllocatorClass * klass)
+{
+  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_class_init_allocator:
- * @allocator: a #GstAllocatorClass
+ * gst_is_fd_memory:
+ * @mem: #GstMemory
+ *
+ * Check if @mem is memory backed by an fd
  *
- * Sets up the methods to alloc and free fd backed memory created
- * with @gst_fd_memory_new by @allocator.
+ * Returns: %TRUE when @mem has an fd that can be retrieved with
+ * gst_fd_memory_get_fd().
+ *
+ * Since: 1.6
  */
-void
-__gst_fd_memory_class_init_allocator (GstAllocatorClass * allocator)
+gboolean
+gst_is_fd_memory (GstMemory * mem)
 {
-  allocator->alloc = NULL;
-  allocator->free = gst_fd_mem_free;
+  g_return_val_if_fail (mem != NULL, FALSE);
+
+  return GST_IS_FD_ALLOCATOR (mem->allocator);
 }
 
 /**
- * gst_fd_memory_init_allocator:
- * @allocator: a #GstAllocator
- * @type: the memory type
+ * gst_fd_memory_get_fd:
+ * @mem: #GstMemory
  *
- * Sets up the methods to map and unmap and share fd backed memory
- * created with @allocator.
+ * 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
  */
-void
-__gst_fd_memory_init_allocator (GstAllocator * allocator, const gchar * type)
+gint
+gst_fd_memory_get_fd (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, -1);
+  g_return_val_if_fail (GST_IS_FD_ALLOCATOR (mem->allocator), -1);
+
+  return ((GstFdMemory *) mem)->fd;
 }
index 9f28332..fdcc677 100644 (file)
  * 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__ */