memory: make the allocator refcounted

Add refcounting to the GstAllocator object.
Remove const from functions because the allocator is refcounted now.
Rename the vmethods for consistency
Expose the constructor for GstAllocator and add a destroy notify for the
user_data. This should make it possible to create allocators that are not
registered and shared globally along with the possibility to destroy them
properly.
Update defs with new symbols.
This commit is contained in:
Wim Taymans 2012-01-30 13:02:13 +01:00
parent d9577f2696
commit af2fc026fc
7 changed files with 175 additions and 79 deletions

View file

@ -479,8 +479,7 @@ gst_buffer_new (void)
* be allocated. * be allocated.
*/ */
GstBuffer * GstBuffer *
gst_buffer_new_allocate (const GstAllocator * allocator, gsize size, gst_buffer_new_allocate (GstAllocator * allocator, gsize size, gsize align)
gsize align)
{ {
GstBuffer *newbuf; GstBuffer *newbuf;
GstMemory *mem; GstMemory *mem;

View file

@ -266,7 +266,7 @@ GType gst_buffer_get_type (void);
/* allocation */ /* allocation */
GstBuffer * gst_buffer_new (void); GstBuffer * gst_buffer_new (void);
GstBuffer * gst_buffer_new_allocate (const GstAllocator * allocator, gsize size, gsize align); GstBuffer * gst_buffer_new_allocate (GstAllocator * allocator, gsize size, gsize align);
GstBuffer * gst_buffer_new_wrapped_full (gpointer data, GFreeFunc free_func, gsize offset, gsize size); GstBuffer * gst_buffer_new_wrapped_full (gpointer data, GFreeFunc free_func, gsize offset, gsize size);
GstBuffer * gst_buffer_new_wrapped (gpointer data, gsize size); GstBuffer * gst_buffer_new_wrapped (gpointer data, gsize size);

View file

@ -93,9 +93,12 @@ size_t gst_memory_alignment = 0;
struct _GstAllocator struct _GstAllocator
{ {
GQuark name; gint refcount;
GstMemoryInfo info; GstMemoryInfo info;
gpointer user_data;
GDestroyNotify notify;
}; };
/* default memory implementation */ /* default memory implementation */
@ -108,10 +111,10 @@ typedef struct
} GstMemoryDefault; } GstMemoryDefault;
/* the default allocator */ /* the default allocator */
static const GstAllocator *_default_allocator; static GstAllocator *_default_allocator;
/* our predefined allocators */ /* our predefined allocators */
static const GstAllocator *_default_mem_impl; static GstAllocator *_default_mem_impl;
/* initialize the fields */ /* initialize the fields */
static void static void
@ -182,7 +185,8 @@ _default_mem_new_block (gsize maxsize, gsize align, gsize offset, gsize size)
} }
static GstMemory * static GstMemory *
_default_mem_alloc (const GstAllocator * allocator, gsize maxsize, gsize align) _default_alloc_alloc (GstAllocator * allocator, gsize maxsize, gsize align,
gpointer user_data)
{ {
return (GstMemory *) _default_mem_new_block (maxsize, align, 0, maxsize); return (GstMemory *) _default_mem_new_block (maxsize, align, 0, maxsize);
} }
@ -268,7 +272,7 @@ _default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2,
} }
static GstMemory * static GstMemory *
_fallback_copy (GstMemory * mem, gssize offset, gssize size) _fallback_mem_copy (GstMemory * mem, gssize offset, gssize size)
{ {
GstMemory *copy; GstMemory *copy;
GstMapInfo sinfo, dinfo; GstMapInfo sinfo, dinfo;
@ -295,7 +299,7 @@ _fallback_copy (GstMemory * mem, gssize offset, gssize size)
} }
static gboolean static gboolean
_fallback_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) _fallback_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
{ {
return FALSE; return FALSE;
} }
@ -303,18 +307,23 @@ _fallback_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
static GRWLock lock; static GRWLock lock;
static GHashTable *allocators; static GHashTable *allocators;
static void
_priv_sysmem_notify (gpointer user_data)
{
g_warning ("The default memory allocator was freed!");
}
void void
_priv_gst_memory_initialize (void) _priv_gst_memory_initialize (void)
{ {
static const GstMemoryInfo _mem_info = { static const GstMemoryInfo _mem_info = {
(GstMemoryAllocFunction) _default_mem_alloc, (GstAllocatorAllocFunction) _default_alloc_alloc,
(GstMemoryMapFunction) _default_mem_map, (GstMemoryMapFunction) _default_mem_map,
(GstMemoryUnmapFunction) _default_mem_unmap, (GstMemoryUnmapFunction) _default_mem_unmap,
(GstMemoryFreeFunction) _default_mem_free, (GstMemoryFreeFunction) _default_mem_free,
(GstMemoryCopyFunction) _default_mem_copy, (GstMemoryCopyFunction) _default_mem_copy,
(GstMemoryShareFunction) _default_mem_share, (GstMemoryShareFunction) _default_mem_share,
(GstMemoryIsSpanFunction) _default_mem_is_span, (GstMemoryIsSpanFunction) _default_mem_is_span,
NULL
}; };
g_rw_lock_init (&lock); g_rw_lock_init (&lock);
@ -328,9 +337,11 @@ _priv_gst_memory_initialize (void)
GST_DEBUG ("memory alignment: %" G_GSIZE_FORMAT, gst_memory_alignment); GST_DEBUG ("memory alignment: %" G_GSIZE_FORMAT, gst_memory_alignment);
_default_mem_impl = gst_allocator_register (GST_ALLOCATOR_SYSMEM, &_mem_info); _default_mem_impl = gst_allocator_new (&_mem_info, NULL, _priv_sysmem_notify);
_default_allocator = _default_mem_impl; _default_allocator = gst_allocator_ref (_default_mem_impl);
gst_allocator_register (GST_ALLOCATOR_SYSMEM,
gst_allocator_ref (_default_mem_impl));
} }
/** /**
@ -396,7 +407,7 @@ gst_memory_unref (GstMemory * mem)
GST_DEBUG ("memory %p, %d->%d", mem, mem->refcount, mem->refcount - 1); GST_DEBUG ("memory %p, %d->%d", mem, mem->refcount, mem->refcount - 1);
if (g_atomic_int_dec_and_test (&mem->refcount)) if (g_atomic_int_dec_and_test (&mem->refcount))
mem->allocator->info.free (mem); mem->allocator->info.mem_free (mem);
} }
/** /**
@ -587,7 +598,7 @@ gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags)
if (!gst_memory_lock (mem, flags)) if (!gst_memory_lock (mem, flags))
goto lock_failed; goto lock_failed;
info->data = mem->allocator->info.map (mem, mem->maxsize, flags); info->data = mem->allocator->info.mem_map (mem, mem->maxsize, flags);
if (G_UNLIKELY (info->data == NULL)) if (G_UNLIKELY (info->data == NULL))
goto error; goto error;
@ -631,7 +642,7 @@ gst_memory_unmap (GstMemory * mem, GstMapInfo * info)
/* there must be a ref */ /* there must be a ref */
g_return_if_fail (g_atomic_int_get (&mem->state) >= 4); g_return_if_fail (g_atomic_int_get (&mem->state) >= 4);
mem->allocator->info.unmap (mem); mem->allocator->info.mem_unmap (mem);
gst_memory_unlock (mem); gst_memory_unlock (mem);
} }
@ -655,7 +666,7 @@ gst_memory_copy (GstMemory * mem, gssize offset, gssize size)
g_return_val_if_fail (mem != NULL, NULL); g_return_val_if_fail (mem != NULL, NULL);
g_return_val_if_fail (gst_memory_lock (mem, GST_MAP_READ), NULL); g_return_val_if_fail (gst_memory_lock (mem, GST_MAP_READ), NULL);
copy = mem->allocator->info.copy (mem, offset, size); copy = mem->allocator->info.mem_copy (mem, offset, size);
gst_memory_unlock (mem); gst_memory_unlock (mem);
@ -680,7 +691,7 @@ gst_memory_share (GstMemory * mem, gssize offset, gssize size)
{ {
g_return_val_if_fail (mem != NULL, NULL); g_return_val_if_fail (mem != NULL, NULL);
return mem->allocator->info.share (mem, offset, size); return mem->allocator->info.mem_share (mem, offset, size);
} }
/** /**
@ -713,7 +724,7 @@ gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
return FALSE; return FALSE;
/* and memory is contiguous */ /* and memory is contiguous */
if (!mem1->allocator->info.is_span (mem1, mem2, offset)) if (!mem1->allocator->info.mem_is_span (mem1, mem2, offset))
return FALSE; return FALSE;
return TRUE; return TRUE;
@ -721,50 +732,112 @@ gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
/** /**
* gst_allocator_register: * gst_allocator_register:
* @name: the name of the allocator * @info: a #GstMemoryInfo
* @info: #GstMemoryInfo * @user_data: user data
* @notify: a #GDestroyNotify for @user_data
* *
* Registers the memory allocator with @name and implementation functions * Create a new memory allocator with @info and @user_data.
* @info.
* *
* All functions in @info are mandatory exept the copy and is_span * All functions in @info are mandatory exept the copy and is_span
* functions, which will have a default implementation when left NULL. * functions, which will have a default implementation when left NULL.
* *
* The user_data field in @info will be passed to all calls of the alloc * The @user_data will be passed to all calls of the alloc function and the
* function. * @notify function.
* *
* Returns: a new #GstAllocator. * Returns: a new #GstAllocator.
*/ */
const GstAllocator * GstAllocator *
gst_allocator_register (const gchar * name, const GstMemoryInfo * info) gst_allocator_new (const GstMemoryInfo * info, gpointer user_data,
GDestroyNotify notify)
{ {
GstAllocator *allocator; GstAllocator *allocator;
#define INSTALL_FALLBACK(_t) \ #define INSTALL_FALLBACK(_t) \
if (allocator->info._t == NULL) allocator->info._t = _fallback_ ##_t; if (allocator->info._t == NULL) allocator->info._t = _fallback_ ##_t;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (info != NULL, NULL); g_return_val_if_fail (info != NULL, NULL);
g_return_val_if_fail (info->alloc != NULL, NULL); g_return_val_if_fail (info->alloc != NULL, NULL);
g_return_val_if_fail (info->map != NULL, NULL); g_return_val_if_fail (info->mem_map != NULL, NULL);
g_return_val_if_fail (info->unmap != NULL, NULL); g_return_val_if_fail (info->mem_unmap != NULL, NULL);
g_return_val_if_fail (info->free != NULL, NULL); g_return_val_if_fail (info->mem_free != NULL, NULL);
g_return_val_if_fail (info->share != NULL, NULL); g_return_val_if_fail (info->mem_share != NULL, NULL);
allocator = g_slice_new (GstAllocator); allocator = g_slice_new (GstAllocator);
allocator->name = g_quark_from_string (name); allocator->refcount = 1;
allocator->info = *info; allocator->info = *info;
INSTALL_FALLBACK (copy); allocator->user_data = user_data;
INSTALL_FALLBACK (is_span); allocator->notify = notify;
INSTALL_FALLBACK (mem_copy);
INSTALL_FALLBACK (mem_is_span);
#undef INSTALL_FALLBACK #undef INSTALL_FALLBACK
GST_DEBUG ("registering allocator \"%s\"", name); GST_DEBUG ("new allocator %p", allocator);
return allocator;
}
/**
* gst_alocator_ref:
* @allocator: a #GstAllocator
*
* Increases the refcount of @allocator.
*
* Returns: @allocator with increased refcount
*/
GstAllocator *
gst_allocator_ref (GstAllocator * allocator)
{
g_return_val_if_fail (allocator != NULL, NULL);
GST_DEBUG ("alocator %p, %d->%d", allocator, allocator->refcount,
allocator->refcount + 1);
g_atomic_int_inc (&allocator->refcount);
return allocator;
}
/**
* gst_allocator_unref:
* @allocator: a #GstAllocator
*
* Decreases the refcount of @allocator. When the refcount reaches 0, the free
* function of @allocator will be called.
*/
void
gst_allocator_unref (GstAllocator * allocator)
{
g_return_if_fail (allocator != NULL);
GST_DEBUG ("allocator %p, %d->%d", allocator, allocator->refcount,
allocator->refcount - 1);
if (g_atomic_int_dec_and_test (&allocator->refcount)) {
if (allocator->notify)
allocator->notify (allocator->user_data);
g_slice_free1 (sizeof (GstAllocator), allocator);
}
}
/**
* gst_allocator_register:
* @name: the name of the allocator
* @allocator: (transfer full): #GstAllocator
*
* Registers the memory @allocator with @name. This function takes ownership of
* @allocator.
*/
void
gst_allocator_register (const gchar * name, GstAllocator * allocator)
{
g_return_if_fail (name != NULL);
g_return_if_fail (allocator != NULL);
GST_DEBUG ("registering allocator %p with name \"%s\"", allocator, name);
g_rw_lock_writer_lock (&lock); g_rw_lock_writer_lock (&lock);
g_hash_table_insert (allocators, (gpointer) name, (gpointer) allocator); g_hash_table_insert (allocators, (gpointer) name, (gpointer) allocator);
g_rw_lock_writer_unlock (&lock); g_rw_lock_writer_unlock (&lock);
return allocator;
} }
/** /**
@ -774,13 +847,13 @@ gst_allocator_register (const gchar * name, const GstMemoryInfo * info)
* Find a previously registered allocator with @name. When @name is NULL, the * Find a previously registered allocator with @name. When @name is NULL, the
* default allocator will be returned. * default allocator will be returned.
* *
* Returns: a #GstAllocator or NULL when the allocator with @name was not * Returns: (transfer full): a #GstAllocator or NULL when the allocator with @name was not
* registered. * registered. Use gst_allocator_unref() to release the allocator after usage.
*/ */
const GstAllocator * GstAllocator *
gst_allocator_find (const gchar * name) gst_allocator_find (const gchar * name)
{ {
const GstAllocator *allocator; GstAllocator *allocator;
g_rw_lock_reader_lock (&lock); g_rw_lock_reader_lock (&lock);
if (name) { if (name) {
@ -788,6 +861,8 @@ gst_allocator_find (const gchar * name)
} else { } else {
allocator = _default_allocator; allocator = _default_allocator;
} }
if (allocator)
gst_allocator_ref (allocator);
g_rw_lock_reader_unlock (&lock); g_rw_lock_reader_unlock (&lock);
return allocator; return allocator;
@ -795,18 +870,23 @@ gst_allocator_find (const gchar * name)
/** /**
* gst_allocator_set_default: * gst_allocator_set_default:
* @allocator: a #GstAllocator * @allocator: (transfer full): a #GstAllocator
* *
* Set the default allocator. * Set the default allocator. This function takes ownership of @allocator.
*/ */
void void
gst_allocator_set_default (const GstAllocator * allocator) gst_allocator_set_default (GstAllocator * allocator)
{ {
GstAllocator *old;
g_return_if_fail (allocator != NULL); g_return_if_fail (allocator != NULL);
g_rw_lock_writer_lock (&lock); g_rw_lock_writer_lock (&lock);
old = _default_allocator;
_default_allocator = allocator; _default_allocator = allocator;
g_rw_lock_writer_unlock (&lock); g_rw_lock_writer_unlock (&lock);
if (old)
gst_allocator_unref (old);
} }
/** /**
@ -826,7 +906,7 @@ gst_allocator_set_default (const GstAllocator * allocator)
* Returns: (transfer full): a new #GstMemory. * Returns: (transfer full): a new #GstMemory.
*/ */
GstMemory * GstMemory *
gst_allocator_alloc (const GstAllocator * allocator, gsize maxsize, gsize align) gst_allocator_alloc (GstAllocator * allocator, gsize maxsize, gsize align)
{ {
g_return_val_if_fail (((align + 1) & align) == 0, NULL); g_return_val_if_fail (((align + 1) & align) == 0, NULL);
@ -834,5 +914,5 @@ gst_allocator_alloc (const GstAllocator * allocator, gsize maxsize, gsize align)
allocator = _default_allocator; allocator = _default_allocator;
return allocator->info.alloc (allocator, maxsize, align, return allocator->info.alloc (allocator, maxsize, align,
allocator->info.user_data); allocator->user_data);
} }

View file

@ -71,7 +71,7 @@ typedef enum {
* as the first member of their structure. * as the first member of their structure.
*/ */
struct _GstMemory { struct _GstMemory {
const GstAllocator *allocator; GstAllocator *allocator;
GstMemoryFlags flags; GstMemoryFlags flags;
gint refcount; gint refcount;
@ -134,7 +134,7 @@ typedef struct {
#define GST_ALLOCATOR_SYSMEM "SystemMemory" #define GST_ALLOCATOR_SYSMEM "SystemMemory"
/** /**
* GstMemoryAllocFunction: * GstAllocatorAllocFunction:
* @allocator: a #GstAllocator * @allocator: a #GstAllocator
* @maxsize: the maxsize * @maxsize: the maxsize
* @align: the alignment * @align: the alignment
@ -143,11 +143,11 @@ typedef struct {
* Allocate a new #GstMemory from @allocator that can hold at least @maxsize bytes * Allocate a new #GstMemory from @allocator that can hold at least @maxsize bytes
* and is aligned to (@align + 1) bytes. * and is aligned to (@align + 1) bytes.
* *
* @user_data is the data that was used when registering @allocator. * @user_data is the data that was used when creating @allocator.
* *
* Returns: a newly allocated #GstMemory. Free with gst_memory_unref() * Returns: a newly allocated #GstMemory. Free with gst_memory_unref()
*/ */
typedef GstMemory * (*GstMemoryAllocFunction) (const GstAllocator *allocator, typedef GstMemory * (*GstAllocatorAllocFunction) (GstAllocator *allocator,
gsize maxsize, gsize align, gsize maxsize, gsize align,
gpointer user_data); gpointer user_data);
@ -229,42 +229,46 @@ typedef gboolean (*GstMemoryIsSpanFunction) (GstMemory *mem1, GstMemory *m
/** /**
* GstMemoryInfo: * GstMemoryInfo:
* @alloc: the implementation of the GstMemoryAllocFunction * @alloc: the implementation of the GstAllocatorAllocFunction
* @map: the implementation of the GstMemoryMapFunction * @mem_map: the implementation of the GstMemoryMapFunction
* @unmap: the implementation of the GstMemoryUnmapFunction * @mem_unmap: the implementation of the GstMemoryUnmapFunction
* @free: the implementation of the GstMemoryFreeFunction * @mem_free: the implementation of the GstMemoryFreeFunction
* @copy: the implementation of the GstMemoryCopyFunction * @mem_copy: the implementation of the GstMemoryCopyFunction
* @share: the implementation of the GstMemoryShareFunction * @mem_share: the implementation of the GstMemoryShareFunction
* @is_span: the implementation of the GstMemoryIsSpanFunction * @mem_is_span: the implementation of the GstMemoryIsSpanFunction
* @user_data: generic user data for the allocator
* *
* The #GstMemoryInfo is used to register new memory allocators and contain * The #GstMemoryInfo is used to register new memory allocators and contain
* the implementations for various memory operations. * the implementations for various memory operations.
*/ */
struct _GstMemoryInfo { struct _GstMemoryInfo {
GstMemoryAllocFunction alloc; GstAllocatorAllocFunction alloc;
GstMemoryMapFunction map;
GstMemoryUnmapFunction unmap;
GstMemoryFreeFunction free;
GstMemoryCopyFunction copy; GstMemoryMapFunction mem_map;
GstMemoryShareFunction share; GstMemoryUnmapFunction mem_unmap;
GstMemoryIsSpanFunction is_span; GstMemoryFreeFunction mem_free;
gpointer user_data; GstMemoryCopyFunction mem_copy;
GstMemoryShareFunction mem_share;
GstMemoryIsSpanFunction mem_is_span;
/*< private >*/ /*< private >*/
gpointer _gst_reserved[GST_PADDING]; gpointer _gst_reserved[GST_PADDING];
}; };
/* allocators */ /* allocators */
const GstAllocator * gst_allocator_register (const gchar *name, const GstMemoryInfo *info); GstAllocator * gst_allocator_new (const GstMemoryInfo * info,
const GstAllocator * gst_allocator_find (const gchar *name); gpointer user_data, GDestroyNotify notify);
void gst_allocator_set_default (const GstAllocator * allocator); GstAllocator * gst_allocator_ref (GstAllocator * allocator);
void gst_allocator_unref (GstAllocator * allocator);
void gst_allocator_register (const gchar *name, GstAllocator *alloc);
GstAllocator * gst_allocator_find (const gchar *name);
void gst_allocator_set_default (GstAllocator * allocator);
/* allocating memory blocks */ /* allocating memory blocks */
GstMemory * gst_allocator_alloc (const GstAllocator * allocator, GstMemory * gst_allocator_alloc (GstAllocator * allocator,
gsize maxsize, gsize align); gsize maxsize, gsize align);
GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, GFreeFunc free_func, GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, GFreeFunc free_func,

View file

@ -246,7 +246,7 @@ struct _GstBaseSrcPrivate
GstClockTime earliest_time; GstClockTime earliest_time;
GstBufferPool *pool; GstBufferPool *pool;
const GstAllocator *allocator; GstAllocator *allocator;
guint prefix; guint prefix;
guint alignment; guint alignment;
}; };
@ -2701,8 +2701,9 @@ null_buffer:
static gboolean static gboolean
gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool, gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool,
const GstAllocator * allocator, guint prefix, guint alignment) GstAllocator * allocator, guint prefix, guint alignment)
{ {
GstAllocator *oldalloc;
GstBufferPool *oldpool; GstBufferPool *oldpool;
GstBaseSrcPrivate *priv = basesrc->priv; GstBaseSrcPrivate *priv = basesrc->priv;
@ -2716,6 +2717,7 @@ gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool,
oldpool = priv->pool; oldpool = priv->pool;
priv->pool = pool; priv->pool = pool;
oldalloc = priv->allocator;
priv->allocator = allocator; priv->allocator = allocator;
priv->prefix = prefix; priv->prefix = prefix;
@ -2730,6 +2732,9 @@ gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool,
} }
gst_object_unref (oldpool); gst_object_unref (oldpool);
} }
if (oldalloc) {
gst_allocator_unref (oldalloc);
}
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */
@ -2766,7 +2771,7 @@ gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps)
gboolean result = TRUE; gboolean result = TRUE;
GstQuery *query; GstQuery *query;
GstBufferPool *pool = NULL; GstBufferPool *pool = NULL;
const GstAllocator *allocator = NULL; GstAllocator *allocator = NULL;
guint size, min, max, prefix, alignment; guint size, min, max, prefix, alignment;
bclass = GST_BASE_SRC_GET_CLASS (basesrc); bclass = GST_BASE_SRC_GET_CLASS (basesrc);

View file

@ -254,7 +254,7 @@ struct _GstBaseTransformPrivate
GstClockTime position_out; GstClockTime position_out;
GstBufferPool *pool; GstBufferPool *pool;
const GstAllocator *allocator; GstAllocator *allocator;
guint prefix; guint prefix;
guint alignment; guint alignment;
}; };
@ -747,9 +747,10 @@ done:
static gboolean static gboolean
gst_base_transform_set_allocation (GstBaseTransform * trans, gst_base_transform_set_allocation (GstBaseTransform * trans,
GstBufferPool * pool, const GstAllocator * allocator, guint prefix, GstBufferPool * pool, GstAllocator * allocator, guint prefix,
guint alignment) guint alignment)
{ {
GstAllocator *oldalloc;
GstBufferPool *oldpool; GstBufferPool *oldpool;
GstBaseTransformPrivate *priv = trans->priv; GstBaseTransformPrivate *priv = trans->priv;
@ -763,6 +764,7 @@ gst_base_transform_set_allocation (GstBaseTransform * trans,
GST_OBJECT_LOCK (trans); GST_OBJECT_LOCK (trans);
oldpool = priv->pool; oldpool = priv->pool;
priv->pool = pool; priv->pool = pool;
oldalloc = priv->allocator;
priv->allocator = allocator; priv->allocator = allocator;
priv->prefix = prefix; priv->prefix = prefix;
priv->alignment = alignment; priv->alignment = alignment;
@ -773,6 +775,9 @@ gst_base_transform_set_allocation (GstBaseTransform * trans,
gst_buffer_pool_set_active (oldpool, FALSE); gst_buffer_pool_set_active (oldpool, FALSE);
gst_object_unref (oldpool); gst_object_unref (oldpool);
} }
if (oldalloc) {
gst_allocator_unref (oldalloc);
}
return TRUE; return TRUE;
/* ERRORS */ /* ERRORS */
@ -791,7 +796,7 @@ gst_base_transform_do_bufferpool (GstBaseTransform * trans, GstCaps * outcaps)
GstBufferPool *pool = NULL, *oldpool; GstBufferPool *pool = NULL, *oldpool;
guint size, min, max, prefix, alignment; guint size, min, max, prefix, alignment;
GstBaseTransformClass *klass; GstBaseTransformClass *klass;
const GstAllocator *allocator = NULL; GstAllocator *allocator = NULL;
/* there are these possibilities: /* there are these possibilities:
* *

View file

@ -51,8 +51,11 @@ EXPORTS
_gst_trace_mutex DATA _gst_trace_mutex DATA
gst_allocator_alloc gst_allocator_alloc
gst_allocator_find gst_allocator_find
gst_allocator_new
gst_allocator_ref
gst_allocator_register gst_allocator_register
gst_allocator_set_default gst_allocator_set_default
gst_allocator_unref
gst_atomic_queue_length gst_atomic_queue_length
gst_atomic_queue_new gst_atomic_queue_new
gst_atomic_queue_peek gst_atomic_queue_peek