tsdemux: store global tags to push later
authorThiago Santos <ts.santos@sisa.samsung.com>
Tue, 25 Feb 2014 01:43:56 +0000 (22:43 -0300)
committerThiago Santos <ts.santos@sisa.samsung.com>
Wed, 26 Feb 2014 13:26:57 +0000 (10:26 -0300)
Keep a list of current global tags around and push them
whenever a new stream is started. Also convert all stream
specific tags to global as they are stream specific for
the container, so they are global for the streams from
within that container.

https://bugzilla.gnome.org/show_bug.cgi?id=644395

gst/mpegtsdemux/tsdemux.c
gst/mpegtsdemux/tsdemux.h

index 390d080..0c1542f 100644 (file)
@@ -344,6 +344,11 @@ gst_ts_demux_reset (MpegTSBase * base)
     demux->update_segment = NULL;
   }
 
+  if (demux->global_tags) {
+    gst_tag_list_unref (demux->global_tags);
+    demux->global_tags = NULL;
+  }
+
   demux->have_group_id = FALSE;
   demux->group_id = G_MAXUINT;
 }
@@ -607,21 +612,54 @@ gst_ts_demux_srcpad_event (GstPad * pad, GstObject * parent, GstEvent * event)
   return res;
 }
 
+static void
+clean_global_taglist (GstTagList * taglist)
+{
+  gst_tag_list_remove_tag (taglist, GST_TAG_CONTAINER_FORMAT);
+  gst_tag_list_remove_tag (taglist, GST_TAG_CODEC);
+}
+
 static gboolean
 push_event (MpegTSBase * base, GstEvent * event)
 {
   GstTSDemux *demux = (GstTSDemux *) base;
   GList *tmp;
+  gboolean early_ret = FALSE;
 
   if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
     GST_DEBUG_OBJECT (base, "Ignoring segment event (recreated later)");
     gst_event_unref (event);
     return TRUE;
+
+  } else if (GST_EVENT_TYPE (event) == GST_EVENT_TAG) {
+    /* In case we receive tags before data, store them to send later
+     * If we already have the program, send it right away */
+    GstTagList *taglist;
+
+    gst_event_parse_tag (event, &taglist);
+
+    if (demux->global_tags == NULL) {
+      demux->global_tags = gst_tag_list_copy (taglist);
+
+      /* Tags that are stream specific for the container should be considered
+       * global for the container streams */
+      if (gst_tag_list_get_scope (taglist) == GST_TAG_SCOPE_STREAM) {
+        gst_tag_list_set_scope (demux->global_tags, GST_TAG_SCOPE_GLOBAL);
+      }
+    } else {
+      demux->global_tags = gst_tag_list_make_writable (demux->global_tags);
+      gst_tag_list_insert (demux->global_tags, taglist, GST_TAG_MERGE_REPLACE);
+    }
+    clean_global_taglist (demux->global_tags);
+
+    /* tags are stored to be used after if there are no streams yet,
+     * so we should never reject */
+    early_ret = TRUE;
   }
 
   if (G_UNLIKELY (demux->program == NULL)) {
     gst_event_unref (event);
-    return FALSE;
+    return early_ret;
   }
 
   for (tmp = demux->program->stream_list; tmp; tmp = tmp->next) {
@@ -1666,6 +1704,11 @@ push_new_segment:
     gst_pad_push_event (stream->pad, demux->segment_event);
   }
 
+  if (demux->global_tags) {
+    gst_pad_push_event (stream->pad,
+        gst_event_new_tag (gst_tag_list_ref (demux->global_tags)));
+  }
+
   /* Push pending tags */
   if (stream->taglist) {
     GST_DEBUG_OBJECT (stream->pad, "Sending tags %" GST_PTR_FORMAT,
@@ -1818,6 +1861,10 @@ gst_ts_demux_flush (MpegTSBase * base, gboolean hard)
     demux->segment_event = NULL;
   }
   demux->calculate_update_segment = FALSE;
+  if (demux->global_tags) {
+    gst_tag_list_unref (demux->global_tags);
+    demux->global_tags = NULL;
+  }
   if (hard) {
     /* For pull mode seeks the current segment needs to be preserved */
     demux->rate = 1.0;
index b997602..e85c2ba 100644 (file)
@@ -69,6 +69,9 @@ struct _GstTSDemux
   GstSegment segment;
   GstEvent *segment_event;
 
+  /* global taglist */
+  GstTagList *global_tags;
+
   /* Set when program change */
   gboolean calculate_update_segment;
   /* update segment is */