X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gst%2Fgstmemory.c;h=a68aa47a944e149b5ca3c0dd1ac84fa4fa4937fa;hb=ce43de86902c4e9c8ed4e9682602664cb9bce2ee;hp=586da2f0e46ecdbb9a6d4d0063d8357e33a14fa9;hpb=2b84b4bd975e177c3f08274a34a1d41e9de31173;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstmemory.c b/gst/gstmemory.c index 586da2f..a68aa47 100644 --- a/gst/gstmemory.c +++ b/gst/gstmemory.c @@ -21,6 +21,7 @@ /** * SECTION:gstmemory + * @title: GstMemory * @short_description: refcounted wrapper for memory blocks * @see_also: #GstBuffer * @@ -33,7 +34,7 @@ * in the allocated region. * * Memory is usually created by allocators with a gst_allocator_alloc() - * method call. When NULL is used as the allocator, the default allocator will + * method call. When %NULL is used as the allocator, the default allocator will * be used. * * New allocators can be registered with gst_allocator_register(). @@ -59,9 +60,7 @@ * 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 2012-03-28 (0.11.3) + * Memory can be efficiently merged when gst_memory_is_span() returns %TRUE. */ #ifdef HAVE_CONFIG_H @@ -71,6 +70,7 @@ #include "gst_private.h" #include "gstmemory.h" +GType _gst_memory_type = 0; GST_DEFINE_MINI_OBJECT_TYPE (GstMemory, gst_memory); static GstMemory * @@ -95,6 +95,7 @@ _gst_memory_free (GstMemory * mem) allocator = mem->allocator; gst_allocator_free (allocator, mem); + gst_object_unref (allocator); } @@ -124,6 +125,7 @@ gst_memory_init (GstMemory * mem, GstMemoryFlags flags, mem->allocator = gst_object_ref (allocator); if (parent) { + /* FIXME 2.0: this can fail if the memory is already write locked */ gst_memory_lock (parent, GST_LOCK_FLAG_EXCLUSIVE); gst_memory_ref (parent); } @@ -162,8 +164,8 @@ gst_memory_is_type (GstMemory * mem, const gchar * mem_type) /** * gst_memory_get_sizes: * @mem: a #GstMemory - * @offset: pointer to offset - * @maxsize: pointer to maxsize + * @offset: (out) (allow-none): pointer to offset + * @maxsize: (out) (allow-none): pointer to maxsize * * Get the current @size, @offset and @maxsize of @mem. * @@ -198,6 +200,7 @@ void gst_memory_resize (GstMemory * mem, gssize offset, gsize size) { g_return_if_fail (mem != NULL); + g_return_if_fail (gst_memory_is_writable (mem)); g_return_if_fail (offset >= 0 || mem->offset >= -offset); g_return_if_fail (size + mem->offset + offset <= mem->maxsize); @@ -226,8 +229,8 @@ gst_memory_resize (GstMemory * mem, gssize offset, gsize size) * This function takes ownership of old @mem and returns a reference to a new * #GstMemory. * - * Returns: (transfer full): a #GstMemory object mapped with @flags or NULL when - * a mapping is not possible. + * Returns: (transfer full) (nullable): a #GstMemory object mapped + * with @flags or %NULL when a mapping is not possible. */ GstMemory * gst_memory_make_mapped (GstMemory * mem, GstMapInfo * info, GstMapFlags flags) @@ -293,15 +296,19 @@ gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags) if (!gst_memory_lock (mem, (GstLockFlags) flags)) goto lock_failed; - info->data = mem->allocator->mem_map (mem, mem->maxsize, flags); + info->flags = flags; + info->memory = mem; + info->size = mem->size; + info->maxsize = mem->maxsize - mem->offset; + + if (mem->allocator->mem_map_full) + info->data = mem->allocator->mem_map_full (mem, info, mem->maxsize); + else + info->data = mem->allocator->mem_map (mem, mem->maxsize, flags); if (G_UNLIKELY (info->data == NULL)) goto error; - info->memory = mem; - info->flags = flags; - info->size = mem->size; - info->maxsize = mem->maxsize - mem->offset; info->data = info->data + mem->offset; return TRUE; @@ -310,13 +317,16 @@ gst_memory_map (GstMemory * mem, GstMapInfo * info, GstMapFlags flags) lock_failed: { GST_CAT_DEBUG (GST_CAT_MEMORY, "mem %p: lock %d failed", mem, flags); + memset (info, 0, sizeof (GstMapInfo)); return FALSE; } error: { - /* something went wrong, restore the orginal state again */ - GST_CAT_ERROR (GST_CAT_MEMORY, "mem %p: subclass map failed", mem); + /* something went wrong, restore the original state again + * it is up to the subclass to log an error if needed. */ + GST_CAT_INFO (GST_CAT_MEMORY, "mem %p: subclass map failed", mem); gst_memory_unlock (mem, (GstLockFlags) flags); + memset (info, 0, sizeof (GstMapInfo)); return FALSE; } } @@ -335,19 +345,22 @@ gst_memory_unmap (GstMemory * mem, GstMapInfo * info) g_return_if_fail (info != NULL); g_return_if_fail (info->memory == mem); - mem->allocator->mem_unmap (mem); + if (mem->allocator->mem_unmap_full) + mem->allocator->mem_unmap_full (mem, info); + else + mem->allocator->mem_unmap (mem); gst_memory_unlock (mem, (GstLockFlags) info->flags); } /** * gst_memory_copy: * @mem: a #GstMemory - * @offset: an offset to copy - * @size: size to copy or -1 to copy all bytes from offset + * @offset: offset to copy from + * @size: size to copy, or -1 to copy to the end of the memory region * * Return a copy of @size bytes from @mem starting from @offset. This copy is - * guaranteed to be writable. @size can be set to -1 to return a copy all bytes - * from @offset. + * guaranteed to be writable. @size can be set to -1 to return a copy + * from @offset to the end of the memory region. * * Returns: a new #GstMemory. */ @@ -366,13 +379,13 @@ gst_memory_copy (GstMemory * mem, gssize offset, gssize size) /** * gst_memory_share: * @mem: a #GstMemory - * @offset: an offset to share - * @size: size to share or -1 to share bytes from offset + * @offset: offset to share from + * @size: size to share, or -1 to share to the end of the memory region * * Return a shared copy of @size bytes from @mem starting from @offset. No * memory copy is performed and the memory region is simply shared. The result - * is guaranteed to be not-writable. @size can be set to -1 to return a share - * all bytes from @offset. + * is guaranteed to be non-writable. @size can be set to -1 to return a shared + * copy from @offset to the end of the memory region. * * Returns: a new #GstMemory. */ @@ -385,8 +398,28 @@ gst_memory_share (GstMemory * mem, gssize offset, gssize size) g_return_val_if_fail (!GST_MEMORY_FLAG_IS_SET (mem, GST_MEMORY_FLAG_NO_SHARE), NULL); + /* whether we can lock the memory exclusively */ + /* in order to maintain backwards compatibility by not requiring subclasses + * to lock the memory themselves and propagate the possible failure in their + * mem_share implementation */ + /* FIXME 2.0: remove and fix gst_memory_init() and/or all memory subclasses + * to propagate this failure case */ + if (!gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE)) + return NULL; + + /* double lock to ensure we are not mapped writable without an + * exclusive lock. */ + if (!gst_memory_lock (mem, GST_LOCK_FLAG_EXCLUSIVE)) { + gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE); + return NULL; + } + shared = mem->allocator->mem_share (mem, offset, size); + /* unlocking before calling the subclass would be racy */ + gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE); + gst_memory_unlock (mem, GST_LOCK_FLAG_EXCLUSIVE); + return shared; } @@ -394,7 +427,7 @@ gst_memory_share (GstMemory * mem, gssize offset, gssize size) * gst_memory_is_span: * @mem1: a #GstMemory * @mem2: a #GstMemory - * @offset: a pointer to a result offset + * @offset: (out): a pointer to a result offset * * Check if @mem1 and mem2 share the memory with a common parent memory object * and that the memory is contiguous. @@ -425,3 +458,9 @@ gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset) return TRUE; } + +void +_priv_gst_memory_initialize (void) +{ + _gst_memory_type = gst_memory_get_type (); +}