gstpad: Probes that return HANDLED can reset the data info field
[platform/upstream/gstreamer.git] / gst / gstallocator.c
index c4b21b3..20ced48 100644 (file)
 
 /**
  * SECTION:gstallocator
+ * @title: GstAllocator
  * @short_description: allocate memory blocks
  * @see_also: #GstMemory
  *
  * 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().
@@ -35,8 +36,6 @@
  *
  * New memory can be created with gst_memory_new_wrapped() that wraps the memory
  * allocated elsewhere.
- *
- * Last reviewed on 2012-07-09 (0.11.3)
  */
 
 #ifdef HAVE_CONFIG_H
 GST_DEBUG_CATEGORY_STATIC (gst_allocator_debug);
 #define GST_CAT_DEFAULT gst_allocator_debug
 
-#define GST_ALLOCATOR_GET_PRIVATE(obj)  \
-     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_ALLOCATOR, GstAllocatorPrivate))
-
 struct _GstAllocatorPrivate
 {
   gpointer dummy;
 };
 
 #if defined(MEMORY_ALIGNMENT_MALLOC)
-size_t gst_memory_alignment = 7;
+gsize gst_memory_alignment = 7;
 #elif defined(MEMORY_ALIGNMENT_PAGESIZE)
 /* we fill this in in the _init method */
-size_t gst_memory_alignment = 0;
+gsize gst_memory_alignment = 0;
 #elif defined(MEMORY_ALIGNMENT)
-size_t gst_memory_alignment = MEMORY_ALIGNMENT - 1;
+gsize gst_memory_alignment = MEMORY_ALIGNMENT - 1;
 #else
 #error "No memory alignment configured"
-size_t gst_memory_alignment = 0;
+gsize gst_memory_alignment = 0;
 #endif
 
 /* the default allocator */
@@ -78,13 +74,12 @@ static GstAllocator *_sysmem_allocator;
 static GRWLock lock;
 static GHashTable *allocators;
 
-G_DEFINE_ABSTRACT_TYPE (GstAllocator, gst_allocator, GST_TYPE_OBJECT);
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GstAllocator, gst_allocator,
+    GST_TYPE_OBJECT);
 
 static void
 gst_allocator_class_init (GstAllocatorClass * klass)
 {
-  g_type_class_add_private (klass, sizeof (GstAllocatorPrivate));
-
   GST_DEBUG_CATEGORY_INIT (gst_allocator_debug, "allocator", 0,
       "allocator debug");
 }
@@ -134,7 +129,7 @@ _fallback_mem_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
 static void
 gst_allocator_init (GstAllocator * allocator)
 {
-  allocator->priv = GST_ALLOCATOR_GET_PRIVATE (allocator);
+  allocator->priv = gst_allocator_get_instance_private (allocator);
 
   allocator->mem_copy = _fallback_mem_copy;
   allocator->mem_is_span = _fallback_mem_is_span;
@@ -160,13 +155,13 @@ gst_allocation_params_init (GstAllocationParams * params)
 
 /**
  * gst_allocation_params_copy:
- * @params: (transfer none): a #GstAllocationParams
+ * @params: (transfer none) (nullable): a #GstAllocationParams
  *
  * Create a copy of @params.
  *
  * Free-function: gst_allocation_params_free
  *
- * Returns: (transfer full): a new ##GstAllocationParams, free with
+ * Returns: (transfer full) (nullable): a new ##GstAllocationParams, free with
  * gst_allocation_params_free().
  */
 GstAllocationParams *
@@ -212,19 +207,22 @@ gst_allocator_register (const gchar * name, GstAllocator * allocator)
       allocator, name);
 
   g_rw_lock_writer_lock (&lock);
+  /* The ref will never be released */
+  GST_OBJECT_FLAG_SET (allocator, GST_OBJECT_FLAG_MAY_BE_LEAKED);
   g_hash_table_insert (allocators, (gpointer) name, (gpointer) allocator);
   g_rw_lock_writer_unlock (&lock);
 }
 
 /**
  * gst_allocator_find:
- * @name: the name of the allocator
+ * @name: (allow-none): the name of the allocator
  *
- * 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.
  *
- * Returns: (transfer full): a #GstAllocator or NULL when the allocator with @name was not
- * registered. Use gst_object_unref() to release the allocator after usage.
+ * Returns: (transfer full) (nullable): a #GstAllocator or %NULL when
+ * the allocator with @name was not registered. Use gst_object_unref()
+ * to release the allocator after usage.
  */
 GstAllocator *
 gst_allocator_find (const gchar * name)
@@ -276,19 +274,19 @@ gst_allocator_set_default (GstAllocator * allocator)
  * @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
+ * %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.
+ * When @allocator is %NULL, the default allocator will be used.
  *
  * 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.
+ * Returns: (transfer full) (nullable): a new #GstMemory.
  */
 GstMemory *
 gst_allocator_alloc (GstAllocator * allocator, gsize size,
@@ -359,7 +357,7 @@ typedef struct
   GstAllocatorClass parent_class;
 } GstAllocatorSysmemClass;
 
-GType gst_allocator_sysmem_get_type (void);
+static GType gst_allocator_sysmem_get_type (void);
 G_DEFINE_TYPE (GstAllocatorSysmem, gst_allocator_sysmem, GST_TYPE_ALLOCATOR);
 
 /* initialize the fields */
@@ -458,13 +456,10 @@ _sysmem_copy (GstMemorySystem * mem, gssize offset, gsize size)
   if (size == -1)
     size = mem->mem.size > offset ? mem->mem.size - offset : 0;
 
-  copy =
-      _sysmem_new_block (0, mem->mem.maxsize, mem->mem.align,
-      mem->mem.offset + offset, size);
+  copy = _sysmem_new_block (0, size, mem->mem.align, 0, size);
   GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
-      "memcpy %" G_GSIZE_FORMAT " memory %p -> %p", mem->mem.maxsize, mem,
-      copy);
-  memcpy (copy->data, mem->data, mem->mem.maxsize);
+      "memcpy %" G_GSIZE_FORMAT " memory %p -> %p", size, mem, copy);
+  memcpy (copy->data, mem->data + mem->mem.offset + offset, size);
 
   return copy;
 }
@@ -540,7 +535,11 @@ default_free (GstAllocator * allocator, GstMemory * mem)
 static void
 gst_allocator_sysmem_finalize (GObject * obj)
 {
-  g_warning ("The default memory allocator was freed!");
+  /* Don't raise warnings if we are shutting down */
+  if (_default_allocator)
+    g_warning ("The default memory allocator was freed!");
+
+  ((GObjectClass *) gst_allocator_sysmem_parent_class)->finalize (obj);
 }
 
 static void
@@ -574,10 +573,11 @@ gst_allocator_sysmem_init (GstAllocatorSysmem * allocator)
 }
 
 void
-_priv_gst_memory_initialize (void)
+_priv_gst_allocator_initialize (void)
 {
   g_rw_lock_init (&lock);
-  allocators = g_hash_table_new (g_str_hash, g_str_equal);
+  allocators = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+      gst_object_unref);
 
 #ifdef HAVE_GETPAGESIZE
 #ifdef MEMORY_ALIGNMENT_PAGESIZE
@@ -590,12 +590,27 @@ _priv_gst_memory_initialize (void)
 
   _sysmem_allocator = g_object_new (gst_allocator_sysmem_get_type (), NULL);
 
+  /* Clear floating flag */
+  gst_object_ref_sink (_sysmem_allocator);
+
   gst_allocator_register (GST_ALLOCATOR_SYSMEM,
       gst_object_ref (_sysmem_allocator));
 
   _default_allocator = gst_object_ref (_sysmem_allocator);
 }
 
+void
+_priv_gst_allocator_cleanup (void)
+{
+  gst_object_unref (_sysmem_allocator);
+  _sysmem_allocator = NULL;
+
+  gst_object_unref (_default_allocator);
+  _default_allocator = NULL;
+
+  g_clear_pointer (&allocators, g_hash_table_unref);
+}
+
 /**
  * gst_memory_new_wrapped:
  * @flags: #GstMemoryFlags
@@ -612,7 +627,7 @@ _priv_gst_memory_initialize (void)
  * The prefix/padding must be filled with 0 if @flags contains
  * #GST_MEMORY_FLAG_ZERO_PREFIXED and #GST_MEMORY_FLAG_ZERO_PADDED respectively.
  *
- * Returns: (transfer full): a new #GstMemory.
+ * Returns: (transfer full) (nullable): a new #GstMemory.
  */
 GstMemory *
 gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data,