tag: Add a scope to taglists
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 27 Jul 2012 21:52:12 +0000 (23:52 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Fri, 27 Jul 2012 22:34:41 +0000 (00:34 +0200)
This specifies if a given taglist applies to the complete
medium or only this specific stream. By default a taglist
has a stream scope.

Fixes bug #677619.

gst/gstevent.c
gst/gstevent.h
gst/gsttaglist.c
gst/gsttaglist.h
libs/gst/base/gstbaseparse.c
tests/check/gst/gstevent.c
tests/check/gst/gstutils.c

index 2096176..3bb4d7f 100644 (file)
@@ -984,26 +984,29 @@ gst_event_copy_segment (GstEvent * event, GstSegment * segment)
 
 /**
  * gst_event_new_tag:
- * @name: (transfer none): the name of the event
  * @taglist: (transfer full): metadata list. The event will take ownership
  *     of the taglist.
  *
  * Generates a metadata tag event from the given @taglist.
  *
- * Since the TAG event has the %GST_EVENT_TYPE_STICKY_MULTI flag set, the
- * @name will be used to keep track of multiple tag events.
+ * The scope of the taglist specifies if the taglist applies to the
+ * complete medium or only to this specific stream. As the tag event
+ * is a sticky event, elements should merge tags received from
+ * upstream with a given scope with their own tags with the same
+ * scope and create a new tag event from it.
  *
  * Returns: (transfer full): a new #GstEvent
  */
 GstEvent *
-gst_event_new_tag (const gchar * name, GstTagList * taglist)
+gst_event_new_tag (GstTagList * taglist)
 {
   GstStructure *s;
   GValue val = G_VALUE_INIT;
+  const gchar *names[] = { "GstTagList-stream", "GstTagList-global" };
 
   g_return_val_if_fail (taglist != NULL, NULL);
 
-  s = gst_structure_new_empty (name);
+  s = gst_structure_new_empty (names[gst_tag_list_get_scope (taglist)]);
   g_value_init (&val, GST_TYPE_TAG_LIST);
   g_value_take_boxed (&val, taglist);
   gst_structure_id_take_value (s, GST_QUARK (TAGLIST), &val);
index 16004cc..00d8d18 100644 (file)
@@ -518,7 +518,7 @@ void            gst_event_parse_segment         (GstEvent *event, const GstSegme
 void            gst_event_copy_segment          (GstEvent *event, GstSegment *segment);
 
 /* tag event */
-GstEvent*       gst_event_new_tag               (const gchar *name, GstTagList *taglist) G_GNUC_MALLOC;
+GstEvent*       gst_event_new_tag               (GstTagList *taglist) G_GNUC_MALLOC;
 void            gst_event_parse_tag             (GstEvent *event, GstTagList **taglist);
 
 /* TOC event */
index 1da2ca8..7de389f 100644 (file)
@@ -57,9 +57,11 @@ typedef struct _GstTagListImpl
   GstTagList taglist;
 
   GstStructure *structure;
+  GstTagScope scope;
 } GstTagListImpl;
 
 #define GST_TAG_LIST_STRUCTURE(taglist)  ((GstTagListImpl*)(taglist))->structure
+#define GST_TAG_LIST_SCOPE(taglist)  ((GstTagListImpl*)(taglist))->scope
 
 typedef struct
 {
@@ -670,6 +672,7 @@ gst_tag_list_new_internal (GstStructure * s)
       (GstMiniObjectFreeFunction) __gst_tag_list_free);
 
   GST_TAG_LIST_STRUCTURE (tag_list) = s;
+  GST_TAG_LIST_SCOPE (tag_list) = GST_TAG_SCOPE_STREAM;
 
 #ifdef DEBUG_REFCOUNT
   GST_CAT_TRACE (GST_CAT_TAGS, "created taglist %p", tag_list);
@@ -784,6 +787,40 @@ gst_tag_list_new_valist (va_list var_args)
 }
 
 /**
+ * gst_tag_list_set_scope:
+ * @list: a #GstTagList
+ * @scope: new scope for @list
+ *
+ * Sets the scope of @list to @scope. By default the scope
+ * of a taglist is #GST_TAG_SCOPE_STREAM.
+ *
+ */
+void
+gst_tag_list_set_scope (GstTagList * list, GstTagScope scope)
+{
+  g_return_if_fail (GST_IS_TAG_LIST (list));
+  g_return_if_fail (gst_tag_list_is_writable (list));
+
+  GST_TAG_LIST_SCOPE (list) = scope;
+}
+
+/**
+ * gst_tag_list_get_scope:
+ * @list: a #GstTagList
+ *
+ * Gets the scope of @list.
+ *
+ * Returns: The scope of @list
+ */
+GstTagScope
+gst_tag_list_get_scope (const GstTagList * list)
+{
+  g_return_val_if_fail (GST_IS_TAG_LIST (list), GST_TAG_SCOPE_STREAM);
+
+  return GST_TAG_LIST_SCOPE (list);
+}
+
+/**
  * gst_tag_list_to_string:
  * @list: a #GstTagList
  *
index dcbe37a..e6f1648 100644 (file)
@@ -211,10 +211,27 @@ GstTagFlag             gst_tag_get_flag        (const gchar * tag);
 gboolean               gst_tag_is_fixed        (const gchar * tag);
 
 /* tag lists */
+
+/**
+ * GstTagEventScope:
+ * @GST_TAG_SCOPE_STREAM: tags specific to this single stream
+ * @GST_TAG_SCOPE_GLOBAL: global tags for the complete medium
+ *
+ * GstTagScope specifies if a taglist applies to the complete
+ * medium or only to one single stream.
+ */
+typedef enum {
+  GST_TAG_SCOPE_STREAM,
+  GST_TAG_SCOPE_GLOBAL
+} GstTagScope;
+
 GstTagList * gst_tag_list_new_empty         (void) G_GNUC_MALLOC;
 GstTagList * gst_tag_list_new               (const gchar * tag, ...) G_GNUC_MALLOC;
 GstTagList * gst_tag_list_new_valist        (va_list var_args) G_GNUC_MALLOC;
 
+void         gst_tag_list_set_scope         (GstTagList * list, GstTagScope scope);
+GstTagScope  gst_tag_list_get_scope         (const GstTagList * list);
+
 gchar      * gst_tag_list_to_string         (const GstTagList * list) G_GNUC_MALLOC;
 GstTagList * gst_tag_list_new_from_string   (const gchar      * str) G_GNUC_MALLOC;
 
index edaedcc..349a202 100644 (file)
@@ -1404,8 +1404,7 @@ gst_base_parse_post_bitrates (GstBaseParse * parse, gboolean post_min,
       parse->priv->max_bitrate);
 
   if (taglist != NULL) {
-    gst_pad_push_event (parse->srcpad, gst_event_new_tag ("GstParser",
-            taglist));
+    gst_pad_push_event (parse->srcpad, gst_event_new_tag (taglist));
   }
 }
 
@@ -3983,6 +3982,10 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
 
   gst_event_parse_tag (event, &taglist);
 
+  /* We only care about stream tags here */
+  if (gst_tag_list_get_scope (taglist) != GST_TAG_SCOPE_STREAM)
+    return;
+
   if (gst_tag_list_get_uint (taglist, GST_TAG_MINIMUM_BITRATE, &tmp)) {
     GST_DEBUG_OBJECT (parse, "upstream min bitrate %d", tmp);
     parse->priv->post_min_bitrate = FALSE;
index 5e805cc..fc215f2 100644 (file)
@@ -185,7 +185,7 @@ GST_START_TEST (create_events)
     GstTagList *taglist = gst_tag_list_new_empty ();
     GstTagList *tl2 = NULL;
 
-    event = gst_event_new_tag ("test", taglist);
+    event = gst_event_new_tag (taglist);
     fail_if (taglist == NULL);
     fail_if (event == NULL);
     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
index 046187b..e0d0ff3 100644 (file)
@@ -504,7 +504,7 @@ GST_START_TEST (test_element_found_tags)
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
 
   srcpad = gst_element_get_static_pad (fakesrc, "src");
-  gst_pad_push_event (srcpad, gst_event_new_tag ("test", list));
+  gst_pad_push_event (srcpad, gst_event_new_tag (list));
   gst_object_unref (srcpad);
 
   bus = gst_element_get_bus (pipeline);