X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstmemory.c;h=5a7f289ea54f00d1dd8bbdcdcc029bf135d09d6f;hb=1074a4e99a473efd5ee690da9ecd797c55cec23a;hp=2cc37f60d999cc27834545f282bcfdc2d69f50e4;hpb=d09073b755b90149345d413fc0cdc346dcc2cbd1;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstmemory.c b/gst/gstmemory.c index 2cc37f6..5a7f289 100644 --- a/gst/gstmemory.c +++ b/gst/gstmemory.c @@ -38,7 +38,8 @@ * * New allocators can be registered with gst_allocator_register(). * Allocators are identified by name and can be retrieved with - * gst_allocator_find(). + * gst_allocator_find(). gst_allocator_set_default() can be used to change the + * default allocator. * * New memory can be created with gst_memory_new_wrapped() that wraps the memory * allocated elsewhere. @@ -53,14 +54,14 @@ * The call will return a pointer to offset bytes into the region of memory. * After the memory access is completed, gst_memory_unmap() should be called. * - * Memory can be copied with gst_memory_copy(), which will returnn a writable + * Memory can be copied with gst_memory_copy(), which will return a writable * copy. gst_memory_share() will create a new memory block that shares the * memory with an existing memory block at a custom offset and with a custom * size. * * Memory can be efficiently merged when gst_memory_is_span() returns TRUE. * - * Last reviewed on 2011-06-08 (0.11.0) + * Last reviewed on 2012-03-28 (0.11.3) */ #ifdef HAVE_CONFIG_H @@ -82,12 +83,10 @@ G_DEFINE_BOXED_TYPE (GstMemory, gst_memory, (GBoxedCopyFunc) gst_memory_ref, G_DEFINE_BOXED_TYPE (GstAllocator, gst_allocator, (GBoxedCopyFunc) gst_allocator_ref, (GBoxedFreeFunc) gst_allocator_unref); -/** - * gst_memory_alignment: - * - * The default memory alignment in bytes - 1 - * an alignment of 7 would be the same as what malloc() guarantees. - */ +G_DEFINE_BOXED_TYPE (GstAllocationParams, gst_allocation_params, + (GBoxedCopyFunc) gst_allocation_params_copy, + (GBoxedFreeFunc) gst_allocation_params_free); + #if defined(MEMORY_ALIGNMENT_MALLOC) size_t gst_memory_alignment = 7; #elif defined(MEMORY_ALIGNMENT_PAGESIZE) @@ -116,7 +115,8 @@ typedef struct GstMemory mem; gsize slice_size; guint8 *data; - GFreeFunc free_func; + gpointer user_data; + GDestroyNotify notify; } GstMemoryDefault; /* the default allocator */ @@ -129,7 +129,8 @@ static GstAllocator *_default_mem_impl; static void _default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags, GstMemory * parent, gsize slice_size, gpointer data, - GFreeFunc free_func, gsize maxsize, gsize offset, gsize size) + gsize maxsize, gsize offset, gsize size, gsize align, + gpointer user_data, GDestroyNotify notify) { mem->mem.allocator = _default_mem_impl; mem->mem.flags = flags; @@ -137,19 +138,24 @@ _default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags, mem->mem.parent = parent ? gst_memory_ref (parent) : NULL; mem->mem.state = (flags & GST_MEMORY_FLAG_READONLY ? 0x1 : 0); mem->mem.maxsize = maxsize; + mem->mem.align = align; mem->mem.offset = offset; mem->mem.size = size; mem->slice_size = slice_size; mem->data = data; - mem->free_func = free_func; + mem->user_data = user_data; + mem->notify = notify; - GST_CAT_DEBUG (GST_CAT_MEMORY, "new memory %p", mem); + GST_CAT_DEBUG (GST_CAT_MEMORY, "new memory %p, maxsize:%" G_GSIZE_FORMAT + " offset:%" G_GSIZE_FORMAT " size:%" G_GSIZE_FORMAT, mem, maxsize, + offset, size); } /* create a new memory block that manages the given memory */ static GstMemoryDefault * _default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data, - GFreeFunc free_func, gsize maxsize, gsize offset, gsize size) + gsize maxsize, gsize offset, gsize size, gsize align, gpointer user_data, + GDestroyNotify notify) { GstMemoryDefault *mem; gsize slice_size; @@ -158,17 +164,18 @@ _default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data, mem = g_slice_alloc (slice_size); _default_mem_init (mem, flags, parent, slice_size, - data, free_func, maxsize, offset, size); + data, maxsize, offset, size, align, user_data, notify); return mem; } /* allocate the memory and structure in one block */ static GstMemoryDefault * -_default_mem_new_block (gsize maxsize, gsize align, gsize offset, gsize size) +_default_mem_new_block (GstMemoryFlags flags, gsize maxsize, gsize align, + gsize offset, gsize size) { GstMemoryDefault *mem; - gsize aoffset, slice_size; + gsize aoffset, slice_size, padding; guint8 *data; /* ensure configured alignment */ @@ -184,20 +191,34 @@ _default_mem_new_block (gsize maxsize, gsize align, gsize offset, gsize size) data = (guint8 *) mem + sizeof (GstMemoryDefault); - if ((aoffset = ((guintptr) data & align))) + /* do alignment */ + if ((aoffset = ((guintptr) data & align))) { aoffset = (align + 1) - aoffset; + data += aoffset; + maxsize -= aoffset; + } + + if (offset && (flags & GST_MEMORY_FLAG_ZERO_PREFIXED)) + memset (data, 0, offset); + + padding = maxsize - (offset + size); + if (padding && (flags & GST_MEMORY_FLAG_ZERO_PADDED)) + memset (data + offset + size, 0, padding); - _default_mem_init (mem, 0, NULL, slice_size, data, NULL, maxsize, - aoffset + offset, size); + _default_mem_init (mem, flags, NULL, slice_size, data, maxsize, + offset, size, align, NULL, NULL); return mem; } static GstMemory * -_default_alloc_alloc (GstAllocator * allocator, gsize maxsize, gsize align, - gpointer user_data) +_default_alloc_alloc (GstAllocator * allocator, gsize size, + GstAllocationParams * params, gpointer user_data) { - return (GstMemory *) _default_mem_new_block (maxsize, align, 0, maxsize); + gsize maxsize = size + params->prefix + params->padding; + + return (GstMemory *) _default_mem_new_block (params->flags, + maxsize, params->align, params->prefix, size); } static gpointer @@ -220,8 +241,8 @@ _default_mem_free (GstMemoryDefault * mem) if (mem->mem.parent) gst_memory_unref (mem->mem.parent); - if (mem->free_func) - mem->free_func (mem->data); + if (mem->notify) + mem->notify (mem->user_data); g_slice_free1 (mem->slice_size, mem); } @@ -235,7 +256,7 @@ _default_mem_copy (GstMemoryDefault * mem, gssize offset, gsize size) size = mem->mem.size > offset ? mem->mem.size - offset : 0; copy = - _default_mem_new_block (mem->mem.maxsize, 0, mem->mem.offset + offset, + _default_mem_new_block (0, mem->mem.maxsize, 0, mem->mem.offset + offset, size); memcpy (copy->data, mem->data, mem->mem.maxsize); GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy memory %p -> %p", mem, copy); @@ -257,8 +278,9 @@ _default_mem_share (GstMemoryDefault * mem, gssize offset, gsize size) size = mem->mem.size - offset; sub = - _default_mem_new (parent->flags, parent, mem->data, NULL, - mem->mem.maxsize, mem->mem.offset + offset, size); + _default_mem_new (parent->flags, parent, mem->data, + mem->mem.maxsize, mem->mem.offset + offset, size, mem->mem.align, NULL, + NULL); return sub; } @@ -286,6 +308,7 @@ _fallback_mem_copy (GstMemory * mem, gssize offset, gssize size) { GstMemory *copy; GstMapInfo sinfo, dinfo; + GstAllocationParams params = { 0, 0, 0, mem->align, }; if (!gst_memory_map (mem, &sinfo, GST_MAP_READ)) return NULL; @@ -294,7 +317,7 @@ _fallback_mem_copy (GstMemory * mem, gssize offset, gssize size) size = sinfo.size > offset ? sinfo.size - offset : 0; /* use the same allocator as the memory we copy */ - copy = gst_allocator_alloc (mem->allocator, size, mem->align); + copy = gst_allocator_alloc (mem->allocator, size, ¶ms); if (!gst_memory_map (copy, &dinfo, GST_MAP_WRITE)) { GST_CAT_WARNING (GST_CAT_MEMORY, "could not write map memory %p", copy); gst_memory_unmap (mem, &sinfo); @@ -366,25 +389,32 @@ _priv_gst_memory_initialize (void) * gst_memory_new_wrapped: * @flags: #GstMemoryFlags * @data: data to wrap - * @free_func: function to free @data * @maxsize: allocated size of @data * @offset: offset in @data * @size: size of valid data + * @user_data: user_data + * @notify: called with @user_data when the memory is freed * * Allocate a new memory block that wraps the given @data. * + * The prefix/padding must be filled with 0 if @flags contains + * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED respectively. + * * Returns: a new #GstMemory. */ GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, - GFreeFunc free_func, gsize maxsize, gsize offset, gsize size) + gsize maxsize, gsize offset, gsize size, gpointer user_data, + GDestroyNotify notify) { GstMemoryDefault *mem; g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (offset + size <= maxsize, NULL); - mem = _default_mem_new (flags, NULL, data, free_func, maxsize, offset, size); + mem = + _default_mem_new (flags, NULL, data, maxsize, offset, size, 0, user_data, + notify); #ifndef GST_DISABLE_TRACE _gst_alloc_trace_new (_gst_memory_trace, mem); @@ -431,6 +461,7 @@ gst_memory_unref (GstMemory * mem) mem->refcount - 1); if (g_atomic_int_dec_and_test (&mem->refcount)) { + /* there should be no outstanding mappings */ g_return_if_fail (g_atomic_int_get (&mem->state) < 4); #ifndef GST_DISABLE_TRACE _gst_alloc_trace_free (_gst_memory_trace, mem); @@ -485,6 +516,9 @@ gst_memory_get_sizes (GstMemory * mem, gsize * offset, gsize * maxsize) * * Resize the memory region. @mem should be writable and offset + size should be * less than the maxsize of @mem. + * + * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED will be + * cleared when offset or padding is increased respectively. */ void gst_memory_resize (GstMemory * mem, gssize offset, gsize size) @@ -493,6 +527,14 @@ gst_memory_resize (GstMemory * mem, gssize offset, gsize size) g_return_if_fail (offset >= 0 || mem->offset >= -offset); g_return_if_fail (size + mem->offset + offset <= mem->maxsize); + /* if we increase the prefix, we can't guarantee it is still 0 filled */ + if ((offset > 0) && GST_MEMORY_IS_ZERO_PREFIXED (mem)) + GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_ZERO_PREFIXED); + + /* if we increase the padding, we can't guarantee it is still 0 filled */ + if ((offset + size < mem->size) && GST_MEMORY_IS_ZERO_PADDED (mem)) + GST_MEMORY_FLAG_UNSET (mem, GST_MEMORY_FLAG_ZERO_PADDED); + mem->offset += offset; mem->size = size; } @@ -768,7 +810,7 @@ gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) } /** - * gst_allocator_register: + * gst_allocator_new: * @info: a #GstMemoryInfo * @user_data: user data * @notify: a #GDestroyNotify for @user_data @@ -818,7 +860,7 @@ gst_allocator_new (const GstMemoryInfo * info, gpointer user_data, } /** - * gst_alocator_get_memory_type: + * gst_allocator_get_memory_type: * @allocator: a #GstAllocator * * Get the memory type allocated by this allocator @@ -834,7 +876,7 @@ gst_allocator_get_memory_type (GstAllocator * allocator) } /** - * gst_alocator_ref: + * gst_allocator_ref: * @allocator: a #GstAllocator * * Increases the refcount of @allocator. @@ -846,7 +888,7 @@ gst_allocator_ref (GstAllocator * allocator) { g_return_val_if_fail (allocator != NULL, NULL); - GST_CAT_TRACE (GST_CAT_MEMORY, "alocator %p, %d->%d", allocator, + GST_CAT_TRACE (GST_CAT_MEMORY, "allocator %p, %d->%d", allocator, allocator->refcount, allocator->refcount + 1); g_atomic_int_inc (&allocator->refcount); @@ -951,32 +993,97 @@ gst_allocator_set_default (GstAllocator * allocator) } /** + * gst_allocation_params_init: + * @params: a #GstAllocationParams + * + * Initialize @params to its default values + */ +void +gst_allocation_params_init (GstAllocationParams * params) +{ + g_return_if_fail (params != NULL); + + memset (params, 0, sizeof (GstAllocationParams)); +} + +/** + * gst_allocation_params_copy: + * @params: (transfer none): a #GstAllocationParams + * + * Create a copy of @params. + * + * Free-function: gst_allocation_params_free + * + * Returns: (transfer full): a new ##GstAllocationParams, free with + * gst_allocation_params_free(). + */ +GstAllocationParams * +gst_allocation_params_copy (const GstAllocationParams * params) +{ + GstAllocationParams *result = NULL; + + if (params) { + result = + (GstAllocationParams *) g_slice_copy (sizeof (GstAllocationParams), + params); + } + return result; +} + +/** + * gst_allocation_params_free: + * @params: (in) (transfer full): a #GstAllocationParams + * + * Free @params + */ +void +gst_allocation_params_free (GstAllocationParams * params) +{ + g_slice_free (GstAllocationParams, params); +} + +/** * gst_allocator_alloc: * @allocator: (transfer none) (allow-none): a #GstAllocator to use - * @maxsize: allocated size of @data - * @align: alignment for the data + * @size: size of the visible memory area + * @params: (transfer none) (allow-none): optional parameters * * Use @allocator to allocate a new memory block with memory that is at least - * @maxsize big and has the given alignment. + * @size big. + * + * The optional @params can specify the prefix and padding for the memory. If + * NULL is passed, no flags, no extra prefix/padding and a default alignment is + * used. + * + * The prefix/padding will be filled with 0 if flags contains + * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED respectively. * * When @allocator is NULL, the default allocator will be used. * - * @align is given as a bitmask so that @align + 1 equals the amount of bytes to - * align to. For example, to align to 8 bytes, use an alignment of 7. + * The alignment in @params is given as a bitmask so that @align + 1 equals + * the amount of bytes to align to. For example, to align to 8 bytes, + * use an alignment of 7. * * Returns: (transfer full): a new #GstMemory. */ GstMemory * -gst_allocator_alloc (GstAllocator * allocator, gsize maxsize, gsize align) +gst_allocator_alloc (GstAllocator * allocator, gsize size, + GstAllocationParams * params) { GstMemory *mem; + static GstAllocationParams defparams = { 0, 0, 0, 0, }; - g_return_val_if_fail (((align + 1) & align) == 0, NULL); + if (params) { + g_return_val_if_fail (((params->align + 1) & params->align) == 0, NULL); + } else { + params = &defparams; + } if (allocator == NULL) allocator = _default_allocator; - mem = allocator->info.alloc (allocator, maxsize, align, allocator->user_data); + mem = allocator->info.alloc (allocator, size, params, allocator->user_data); + #ifndef GST_DISABLE_TRACE _gst_alloc_trace_new (_gst_memory_trace, mem); #endif