uri: fix wrong G_GNUC_MALLOC
[platform/upstream/gstreamer.git] / gst / gstindex.c
index 0a70c3b..d168eee 100644 (file)
  *
  * GstIndex is used to generate a stream index of one or more elements
  * in a pipeline.
+ *
+ * Elements will overload the set_index and get_index virtual methods in
+ * #GstElement. When streaming data, the element will add index entries if it
+ * has an index set.
+ *
+ * Each element that adds to the index will do that using a writer_id. The
+ * writer_id is obtained from gst_index_get_writer_id().
+ *
+ * The application that wants to index the stream will create a new index object
+ * using gst_index_new() or gst_index_factory_make(). The index is assigned to a
+ * specific element, a bin or the whole pipeline. This will cause indexable
+ * elements to add entires to the index while playing.
+ */
+
+/* FIXME: complete gobject annotations */
+/* FIXME-0.11: cleanup API
+ * - no one seems to use GstIndexGroup, GstIndexCertainty
+ *
+ * - the API for application to use the index is mostly missing
+ *   - apps need to get a list of writers
+ *   - apps need to be able to iterate over each writers index entry collection
+ * - gst_index_get_assoc_entry() should pass ownership
+ *   - the GstIndexEntry structure is large and contains repetitive information
+ *   - we want to allow Indexers to implement a saner storage and create
+ *     GstIndexEntries on demand (the app has to free them), might even make
+ *     sense to ask the app to provide a ptr and fill it.
  */
 
 #include "gst_private.h"
@@ -58,8 +84,6 @@ enum
 GST_DEBUG_CATEGORY_STATIC (index_debug);
 #define GST_CAT_DEFAULT index_debug
 
-static void gst_index_class_init (GstIndexClass * klass);
-static void gst_index_init (GstIndex * index);
 static void gst_index_finalize (GObject * object);
 
 static void gst_index_set_property (GObject * object, guint prop_id,
@@ -68,6 +92,7 @@ static void gst_index_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
 static GstIndexGroup *gst_index_group_new (guint groupnum);
+static void gst_index_group_free (GstIndexGroup * group);
 
 static gboolean gst_index_path_resolver (GstIndex * index, GstObject * writer,
     gchar ** writer_string, gpointer data);
@@ -198,7 +223,7 @@ gst_index_finalize (GObject * object)
   GstIndex *index = GST_INDEX (object);
 
   if (index->groups) {
-    g_list_foreach (index->groups, (GFunc) g_free, NULL);
+    g_list_foreach (index->groups, (GFunc) gst_index_group_free, NULL);
     g_list_free (index->groups);
     index->groups = NULL;
   }
@@ -228,7 +253,7 @@ gst_index_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case ARG_RESOLVER:
-      index->method = g_value_get_enum (value);
+      index->method = (GstIndexResolverMethod) g_value_get_enum (value);
       index->resolver = resolvers[index->method].resolver;
       index->resolver_user_data = resolvers[index->method].user_data;
       break;
@@ -259,7 +284,7 @@ gst_index_get_property (GObject * object, guint prop_id,
 static GstIndexGroup *
 gst_index_group_new (guint groupnum)
 {
-  GstIndexGroup *indexgroup = g_new (GstIndexGroup, 1);
+  GstIndexGroup *indexgroup = g_slice_new (GstIndexGroup);
 
   indexgroup->groupnum = groupnum;
   indexgroup->entries = NULL;
@@ -271,12 +296,20 @@ gst_index_group_new (guint groupnum)
   return indexgroup;
 }
 
+static void
+gst_index_group_free (GstIndexGroup * group)
+{
+  g_slice_free (GstIndexGroup, group);
+}
+
 /**
  * gst_index_new:
  *
- * Create a new tileindex object
+ * Create a new dummy index object. Use gst_element_set_index() to assign that
+ * to an element or pipeline. This index is not storing anything, but will
+ * still emit e.g. the #GstIndex::entry-added signal.
  *
- * Returns: a new index object
+ * Returns: (transfer full): a new index object
  */
 GstIndex *
 gst_index_new (void)
@@ -496,17 +529,22 @@ gst_index_set_resolver_full (GstIndex * index, GstIndexResolver resolver,
  *
  * Copies an entry and returns the result.
  *
- * Returns: a newly allocated #GstIndexEntry.
+ * Free-function: gst_index_entry_free
+ *
+ * Returns: (transfer full): a newly allocated #GstIndexEntry.
  */
 GstIndexEntry *
 gst_index_entry_copy (GstIndexEntry * entry)
 {
-  return g_memdup (entry, sizeof (*entry));
+  GstIndexEntry *new_entry = g_slice_new (GstIndexEntry);
+
+  memcpy (new_entry, entry, sizeof (GstIndexEntry));
+  return new_entry;
 }
 
 /**
  * gst_index_entry_free:
- * @entry: the entry to free
+ * @entry: (transfer full): the entry to free
  *
  * Free the memory used by the given entry.
  */
@@ -532,7 +570,7 @@ gst_index_entry_free (GstIndexEntry * entry)
       break;
   }
 
-  g_free (entry);
+  g_slice_free (GstIndexEntry, entry);
 }
 
 /**
@@ -545,7 +583,9 @@ gst_index_entry_free (GstIndexEntry * entry)
  * used to map dynamic GstFormat ids to their original
  * format key.
  *
- * Returns: a pointer to the newly added entry in the index.
+ * Free-function: gst_index_entry_free
+ *
+ * Returns: (transfer full): a pointer to the newly added entry in the index.
  */
 GstIndexEntry *
 gst_index_add_format (GstIndex * index, gint id, GstFormat format)
@@ -559,7 +599,7 @@ gst_index_add_format (GstIndex * index, gint id, GstFormat format)
   if (!GST_INDEX_IS_WRITABLE (index) || id == -1)
     return NULL;
 
-  entry = g_new0 (GstIndexEntry, 1);
+  entry = g_slice_new (GstIndexEntry);
   entry->type = GST_INDEX_ENTRY_FORMAT;
   entry->id = id;
   entry->data.format.format = format;
@@ -593,7 +633,7 @@ gst_index_add_id (GstIndex * index, gint id, gchar * description)
   if (!GST_INDEX_IS_WRITABLE (index) || id == -1)
     return NULL;
 
-  entry = g_new0 (GstIndexEntry, 1);
+  entry = g_slice_new (GstIndexEntry);
   entry->type = GST_INDEX_ENTRY_ID;
   entry->id = id;
   entry->data.id.description = description;
@@ -619,20 +659,23 @@ gst_index_gtype_resolver (GstIndex * index, GstObject * writer,
   g_return_val_if_fail (writer != NULL, FALSE);
 
   if (GST_IS_PAD (writer)) {
-    GstElement *element =
-        (GstElement *) gst_object_get_parent (GST_OBJECT (writer));
+    GstObject *element = gst_object_get_parent (GST_OBJECT (writer));
     gchar *name;
 
     name = gst_object_get_name (writer);
-    *writer_string = g_strdup_printf ("%s.%s",
-        g_type_name (G_OBJECT_TYPE (element)), name);
+    if (element) {
+      *writer_string = g_strdup_printf ("%s.%s",
+          G_OBJECT_TYPE_NAME (element), name);
+      gst_object_unref (element);
+    } else {
+      *writer_string = name;
+      name = NULL;
+    }
 
-    gst_object_unref (element);
     g_free (name);
 
   } else {
-    *writer_string =
-        g_strdup_printf ("%s", g_type_name (G_OBJECT_TYPE (writer)));
+    *writer_string = g_strdup (G_OBJECT_TYPE_NAME (writer));
   }
 
   return TRUE;
@@ -652,6 +695,12 @@ gst_index_gtype_resolver (GstIndex * index, GstObject * writer,
  * to a string. That string will be used to register or look up an id
  * in the index.
  *
+ * <note>
+ * The caller must not hold @writer's #GST_OBJECT_LOCK, as the default
+ * resolver may call functions that take the object lock as well, and
+ * the lock is not recursive.
+ * </note>
+ *
  * Returns: TRUE if the writer would be mapped to an id.
  */
 gboolean
@@ -701,7 +750,7 @@ gst_index_get_writer_id (GstIndex * index, GstObject * writer, gint * id)
     if (!entry) {
       /* index is probably not writable, make an entry anyway
        * to keep it in our cache */
-      entry = g_new0 (GstIndexEntry, 1);
+      entry = g_slice_new (GstIndexEntry);
       entry->type = GST_INDEX_ENTRY_ID;
       entry->id = *id;
       entry->data.id.description = writer_string;
@@ -753,7 +802,7 @@ gst_index_add_associationv (GstIndex * index, gint id, GstAssocFlags flags,
   if (!GST_INDEX_IS_WRITABLE (index) || id == -1)
     return NULL;
 
-  entry = g_malloc (sizeof (GstIndexEntry));
+  entry = g_slice_new (GstIndexEntry);
 
   entry->type = GST_INDEX_ENTRY_ASSOCIATION;
   entry->id = id;