memory: expose the GstAllocation structure
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 6 Jul 2012 15:19:21 +0000 (17:19 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 6 Jul 2012 15:24:32 +0000 (17:24 +0200)
Expose the GstAllocation structure and provide an _init function. This makes it
easier to make 'subclasses' of the allocator that contain more info.
It also allows us to expose the flags on the allocator miniobject.
Make a flag to note that the allocator uses a custom alloc function.

gst/gstmemory.c
gst/gstmemory.h
tests/examples/memory/my-memory.c
tests/examples/memory/my-vidmem.c

index da93ece..a784c92 100644 (file)
@@ -91,16 +91,6 @@ size_t gst_memory_alignment = MEMORY_ALIGNMENT - 1;
 size_t gst_memory_alignment = 0;
 #endif
 
-struct _GstAllocator
-{
-  GstMiniObject mini_object;
-
-  GstMemoryInfo info;
-
-  gpointer user_data;
-  GDestroyNotify notify;
-};
-
 /* default memory implementation */
 typedef struct
 {
@@ -390,7 +380,7 @@ static GRWLock lock;
 static GHashTable *allocators;
 
 static void
-_priv_sysmem_notify (gpointer user_data)
+_priv_sysmem_free (GstMiniObject * obj)
 {
   g_warning ("The default memory allocator was freed!");
 }
@@ -421,7 +411,8 @@ _priv_gst_memory_initialize (void)
   GST_CAT_DEBUG (GST_CAT_MEMORY, "memory alignment: %" G_GSIZE_FORMAT,
       gst_memory_alignment);
 
-  _default_mem_impl = gst_allocator_new (&_mem_info, NULL, _priv_sysmem_notify);
+  _default_mem_impl = g_slice_new (GstAllocator);
+  gst_allocator_init (_default_mem_impl, 0, &_mem_info, _priv_sysmem_free);
 
   _default_allocator = gst_allocator_ref (_default_mem_impl);
   gst_allocator_register (GST_ALLOCATOR_SYSMEM,
@@ -729,15 +720,6 @@ gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
   return TRUE;
 }
 
-static void
-_gst_allocator_free (GstAllocator * allocator)
-{
-  if (allocator->notify)
-    allocator->notify (allocator->user_data);
-
-  g_slice_free1 (sizeof (GstAllocator), allocator);
-}
-
 static GstAllocator *
 _gst_allocator_copy (GstAllocator * allocator)
 {
@@ -745,43 +727,37 @@ _gst_allocator_copy (GstAllocator * allocator)
 }
 
 /**
- * gst_allocator_new:
+ * gst_allocator_init:
+ * @allocator: a #GstAllocator
+ * @flags: #GstAllocatorFlags
  * @info: a #GstMemoryInfo
- * @user_data: user data
- * @notify: a #GDestroyNotify for @user_data
+ * @free_func: a function to free @allocator
  *
- * Create a new memory allocator with @info and @user_data.
+ * Initialize a new memory allocator. The caller should have allocated the
+ * memory to hold at least sizeof (GstAllocator) bytes.
  *
  * All functions in @info are mandatory exept the copy and is_span
  * functions, which will have a default implementation when left NULL.
  *
- * The @user_data will be passed to all calls of the alloc function. @notify
- * will be called with @user_data when the allocator is freed.
- *
  * Returns: a new #GstAllocator.
  */
-GstAllocator *
-gst_allocator_new (const GstMemoryInfo * info, gpointer user_data,
-    GDestroyNotify notify)
+void
+gst_allocator_init (GstAllocator * allocator, GstAllocatorFlags flags,
+    const GstMemoryInfo * info, GstMiniObjectFreeFunction free_func)
 {
-  GstAllocator *allocator;
-
-  g_return_val_if_fail (info != NULL, NULL);
-  g_return_val_if_fail (info->alloc != NULL, NULL);
-  g_return_val_if_fail (info->mem_map != NULL, NULL);
-  g_return_val_if_fail (info->mem_unmap != NULL, NULL);
-  g_return_val_if_fail (info->mem_free != NULL, NULL);
-  g_return_val_if_fail (info->mem_share != NULL, NULL);
-
-  allocator = g_slice_new0 (GstAllocator);
+  g_return_if_fail (allocator != NULL);
+  g_return_if_fail (info != NULL);
+  g_return_if_fail (info->alloc != NULL);
+  g_return_if_fail (info->mem_map != NULL);
+  g_return_if_fail (info->mem_unmap != NULL);
+  g_return_if_fail (info->mem_free != NULL);
+  g_return_if_fail (info->mem_share != NULL);
 
-  gst_mini_object_init (GST_MINI_OBJECT_CAST (allocator), 0, GST_TYPE_ALLOCATOR,
-      (GstMiniObjectCopyFunction) _gst_allocator_copy, NULL,
-      (GstMiniObjectFreeFunction) _gst_allocator_free);
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (allocator), flags,
+      GST_TYPE_ALLOCATOR, (GstMiniObjectCopyFunction) _gst_allocator_copy, NULL,
+      (GstMiniObjectFreeFunction) free_func);
 
   allocator->info = *info;
-  allocator->user_data = user_data;
-  allocator->notify = notify;
 
 #define INSTALL_FALLBACK(_t) \
   if (allocator->info._t == NULL) allocator->info._t = _fallback_ ##_t;
@@ -789,25 +765,7 @@ gst_allocator_new (const GstMemoryInfo * info, gpointer user_data,
   INSTALL_FALLBACK (mem_is_span);
 #undef INSTALL_FALLBACK
 
-  GST_CAT_DEBUG (GST_CAT_MEMORY, "new allocator %p", allocator);
-
-  return allocator;
-}
-
-/**
- * gst_allocator_get_memory_type:
- * @allocator: a #GstAllocator
- *
- * Get the memory type allocated by this allocator
- *
- * Returns: the memory type provided by @allocator
- */
-const gchar *
-gst_allocator_get_memory_type (GstAllocator * allocator)
-{
-  g_return_val_if_fail (allocator != NULL, NULL);
-
-  return allocator->info.mem_type;
+  GST_CAT_DEBUG (GST_CAT_MEMORY, "init allocator %p", allocator);
 }
 
 /**
@@ -971,7 +929,7 @@ gst_allocator_alloc (GstAllocator * allocator, gsize size,
   if (allocator == NULL)
     allocator = _default_allocator;
 
-  mem = allocator->info.alloc (allocator, size, params, allocator->user_data);
+  mem = allocator->info.alloc (allocator, size, params, NULL);
 
   return mem;
 }
index f23da2a..fe093e3 100644 (file)
@@ -246,8 +246,8 @@ struct _GstAllocationParams {
  * #GST_MEMORY_FLAG_ZERO_PADDED respectively.
  *
  * @user_data is extra data passed to this function. The default
- * gst_allocator_alloc() passes the user_data that was used when creating
- * @allocator.
+ * gst_allocator_alloc() passes the NULL but other implementations could pass
+ * custom data.
  *
  * Returns: a newly allocated #GstMemory. Free with gst_memory_unref()
  */
@@ -332,6 +332,20 @@ typedef GstMemory * (*GstMemoryShareFunction)     (GstMemory *mem, gssize offset
 typedef gboolean    (*GstMemoryIsSpanFunction)    (GstMemory *mem1, GstMemory *mem2, gsize *offset);
 
 /**
+ * GstAllocatorFlags:
+ * @GST_ALLOCATOR_CUSTOM_ALLOC: The allocator has a custom alloc function.
+ * @GST_ALLOCATOR_FLAG_LAST: first flag that can be used for custom purposes
+ *
+ * Flags for allocators.
+ */
+typedef enum {
+  GST_ALLOCATOR_FLAG_CUSTOM_ALLOC  = (GST_MINI_OBJECT_FLAG_LAST << 0),
+
+  GST_ALLOCATOR_FLAG_LAST          = (GST_MINI_OBJECT_FLAG_LAST << 16)
+} GstAllocatorFlags;
+
+
+/**
  * GstMemoryInfo:
  * @mem_type: the memory type this allocator provides
  * @alloc: the implementation of the GstAllocatorAllocFunction
@@ -342,7 +356,7 @@ typedef gboolean    (*GstMemoryIsSpanFunction)    (GstMemory *mem1, GstMemory *m
  * @mem_share: the implementation of the GstMemoryShareFunction
  * @mem_is_span: the implementation of the GstMemoryIsSpanFunction
  *
- * The #GstMemoryInfo is used to register new memory allocators and contain
+ * The #GstMemoryInfo is used to initialize new memory allocators and contain
  * the implementations for various memory operations.
  */
 struct _GstMemoryInfo {
@@ -364,15 +378,27 @@ struct _GstMemoryInfo {
 
 /**
  * GstAllocator:
+ * @mini_object: parent structure
+ * @info: a #GstMemoryInfo with the implementation
  *
- * An opaque type returned from gst_allocator_new() or gst_allocator_find()
- * that can be used to allocator memory.
+ * The #GstAllocator is used to create new memory and should be
+ * initialized with gst_allocator_init().
  */
+struct _GstAllocator
+{
+  GstMiniObject  mini_object;
+
+  GstMemoryInfo  info;
+
+  /*< private >*/
+  gpointer _gst_reserved[GST_PADDING];
+};
 
 /* allocators */
-GstAllocator * gst_allocator_new             (const GstMemoryInfo * info,
-                                              gpointer user_data, GDestroyNotify notify);
-const gchar *  gst_allocator_get_memory_type (GstAllocator * allocator);
+void           gst_allocator_init            (GstAllocator * allocator,
+                                              GstAllocatorFlags flags,
+                                              const GstMemoryInfo *info,
+                                              GstMiniObjectFreeFunction free_func);
 
 /**
  * gst_allocator_ref:
index 6e3e89f..15ab973 100644 (file)
@@ -113,6 +113,12 @@ _my_mem_share (MyMemory * mem, gssize offset, gsize size)
   return sub;
 }
 
+static void
+free_allocator (GstMiniObject * obj)
+{
+  g_slice_free (GstAllocator, (GstAllocator *) obj);
+}
+
 void
 my_memory_init (void)
 {
@@ -127,7 +133,8 @@ my_memory_init (void)
     (GstMemoryIsSpanFunction) NULL,
   };
 
-  _my_allocator = gst_allocator_new (&info, NULL, NULL);
+  _my_allocator = g_slice_new (GstAllocator);
+  gst_allocator_init (_my_allocator, 0, &info, free_allocator);
 
   gst_allocator_register ("MyMemory", gst_allocator_ref (_my_allocator));
 }
index b254678..996fee2 100644 (file)
@@ -106,6 +106,12 @@ _my_vidmem_share (MyVidmem * mem, gssize offset, gsize size)
   return sub;
 }
 
+static void
+free_allocator (GstMiniObject * obj)
+{
+  g_slice_free (GstAllocator, (GstAllocator *) obj);
+}
+
 void
 my_vidmem_init (void)
 {
@@ -120,7 +126,8 @@ my_vidmem_init (void)
     (GstMemoryIsSpanFunction) NULL,
   };
 
-  _my_allocator = gst_allocator_new (&info, NULL, NULL);
+  _my_allocator = g_slice_new (GstAllocator);
+  gst_allocator_init (_my_allocator, 0, &info, free_allocator);
 
   gst_allocator_register ("MyVidmem", gst_allocator_ref (_my_allocator));
 }