matroskademux: Preserve forward referenced track tags
authorGlen Diener <grd@loganmill.net>
Thu, 30 Jul 2015 00:54:35 +0000 (18:54 -0600)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 5 Aug 2015 20:46:33 +0000 (16:46 -0400)
https://bugzilla.gnome.org/show_bug.cgi?id=752850

gst/matroska/matroska-demux.c
gst/matroska/matroska-read-common.c
gst/matroska/matroska-read-common.h

index 6173240..1d84abc 100644 (file)
@@ -397,6 +397,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
   GstPadTemplate *templ = NULL;
   GstStreamFlags stream_flags;
   GstCaps *caps = NULL;
+  GstTagList *cached_taglist;
   gchar *padname = NULL;
   GstFlowReturn ret;
   guint32 id, riff_fourcc = 0;
@@ -1128,6 +1129,13 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml)
     return ret;
   }
 
+  /* check for a cached track taglist  */
+  cached_taglist =
+      (GstTagList *) g_hash_table_lookup (demux->common.cached_track_taglists,
+      GUINT_TO_POINTER (context->uid));
+  if (cached_taglist)
+    gst_tag_list_insert (context->tags, cached_taglist, GST_TAG_MERGE_APPEND);
+
   /* now create the GStreamer connectivity */
   switch (context->type) {
     case GST_MATROSKA_TRACK_TYPE_VIDEO:{
index 6076e40..2639251 100644 (file)
@@ -2392,9 +2392,21 @@ gst_matroska_read_common_parse_metadata_id_tag (GstMatroskaReadCommon * common,
         }
       }
       if (!found) {
-        GST_FIXME_OBJECT (common->sinkpad,
+        /* Cache the track taglist: possibly belongs to a track that will be parsed
+           later in gst_matroska_demux.c:gst_matroska_demux_add_stream (...) */
+        gpointer track_uid = GUINT_TO_POINTER (tgt);
+        GstTagList *cached_taglist =
+            g_hash_table_lookup (common->cached_track_taglists, track_uid);
+        if (cached_taglist)
+          gst_tag_list_insert (cached_taglist, taglist, GST_TAG_MERGE_REPLACE);
+        else {
+          gst_tag_list_ref (taglist);
+          g_hash_table_insert (common->cached_track_taglists, track_uid,
+              taglist);
+        }
+        GST_DEBUG_OBJECT (common->sinkpad,
             "Found track-specific tag(s), but track %" G_GUINT64_FORMAT
-            " is not known (yet?)", tgt);
+            " is not known yet, caching", tgt);
       }
     }
   } else
@@ -2844,6 +2856,9 @@ gst_matroska_read_common_init (GstMatroskaReadCommon * ctx)
   ctx->index = NULL;
   ctx->global_tags = NULL;
   ctx->adapter = gst_adapter_new ();
+  ctx->cached_track_taglists =
+      g_hash_table_new_full (NULL, NULL, NULL,
+      (GDestroyNotify) gst_tag_list_unref);
 }
 
 void
@@ -2860,6 +2875,9 @@ gst_matroska_read_common_finalize (GstMatroskaReadCommon * ctx)
   }
 
   g_object_unref (ctx->adapter);
+  g_hash_table_remove_all (ctx->cached_track_taglists);
+  g_hash_table_unref (ctx->cached_track_taglists);
+
 }
 
 void
index 3be9542..ed01e1f 100644 (file)
@@ -102,6 +102,10 @@ typedef struct _GstMatroskaReadCommon {
 
   /* push based mode usual suspects */
   GstAdapter              *adapter;
+
+  /* cache for track tags that forward-reference their tracks */
+  GHashTable *cached_track_taglists ;
 } GstMatroskaReadCommon;
 
 GstFlowReturn gst_matroska_decode_content_encodings (GArray * encodings);