From 408df31a482543ab67532e5fe21e660d75d3c1d6 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 6 Jul 2012 17:19:21 +0200 Subject: [PATCH] memory: expose the GstAllocation structure 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 | 90 +++++++++---------------------- gst/gstmemory.h | 42 ++++++++++++--- tests/examples/memory/my-memory.c | 9 +++- tests/examples/memory/my-vidmem.c | 9 +++- 4 files changed, 74 insertions(+), 76 deletions(-) diff --git a/gst/gstmemory.c b/gst/gstmemory.c index da93ecea8e..a784c92e94 100644 --- a/gst/gstmemory.c +++ b/gst/gstmemory.c @@ -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_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); - 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); - - 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; } diff --git a/gst/gstmemory.h b/gst/gstmemory.h index f23da2a0ad..fe093e3778 100644 --- a/gst/gstmemory.h +++ b/gst/gstmemory.h @@ -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() */ @@ -331,6 +331,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 @@ -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: diff --git a/tests/examples/memory/my-memory.c b/tests/examples/memory/my-memory.c index 6e3e89f34f..15ab973ff1 100644 --- a/tests/examples/memory/my-memory.c +++ b/tests/examples/memory/my-memory.c @@ -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)); } diff --git a/tests/examples/memory/my-vidmem.c b/tests/examples/memory/my-vidmem.c index b254678996..996fee2150 100644 --- a/tests/examples/memory/my-vidmem.c +++ b/tests/examples/memory/my-vidmem.c @@ -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)); }