From cd57697a2cb81cd04fd1b32e9b91032b6c7d8012 Mon Sep 17 00:00:00 2001 From: Glen Diener Date: Wed, 29 Jul 2015 18:54:35 -0600 Subject: [PATCH] matroskademux: Preserve forward referenced track tags https://bugzilla.gnome.org/show_bug.cgi?id=752850 --- gst/matroska/matroska-demux.c | 8 ++++++++ gst/matroska/matroska-read-common.c | 22 ++++++++++++++++++++-- gst/matroska/matroska-read-common.h | 4 ++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 6173240d64..1d84abca6f 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -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:{ diff --git a/gst/matroska/matroska-read-common.c b/gst/matroska/matroska-read-common.c index 6076e40c72..2639251eac 100644 --- a/gst/matroska/matroska-read-common.c +++ b/gst/matroska/matroska-read-common.c @@ -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 diff --git a/gst/matroska/matroska-read-common.h b/gst/matroska/matroska-read-common.h index 3be9542089..ed01e1fad3 100644 --- a/gst/matroska/matroska-read-common.h +++ b/gst/matroska/matroska-read-common.h @@ -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);