diff --git a/ChangeLog b/ChangeLog index 3c3777ff67..3c541eb372 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2008-06-15 Sebastian Dröge + + * gst/matroska/ebml-read.c: + * gst/matroska/ebml-read.h: + * gst/matroska/matroska-demux.c: (gst_matroska_demux_reset), + (gst_matroska_demux_parse_metadata): + * gst/matroska/matroska-demux.h: + Make sure that every Tags element is only parsed once and it's + containing tags are only posted once. + 2008-06-15 Sebastian Dröge * gst/matroska/ebml-read.c: (gst_ebml_peek_id), diff --git a/gst/matroska/ebml-read.c b/gst/matroska/ebml-read.c index fce3ff61ab..87d6234561 100644 --- a/gst/matroska/ebml-read.c +++ b/gst/matroska/ebml-read.c @@ -75,7 +75,7 @@ gst_ebml_read_get_type (void) return gst_ebml_read_type; } -static void +void gst_ebml_level_free (GstEbmlLevel * level) { g_slice_free (GstEbmlLevel, level); diff --git a/gst/matroska/ebml-read.h b/gst/matroska/ebml-read.h index 54782b2597..2d5a5a1387 100644 --- a/gst/matroska/ebml-read.h +++ b/gst/matroska/ebml-read.h @@ -61,6 +61,8 @@ typedef struct _GstEbmlReadClass { GType gst_ebml_read_get_type (void); +void gst_ebml_level_free (GstEbmlLevel *level); + GstFlowReturn gst_ebml_peek_id (GstEbmlRead *ebml, guint *level_up, guint32 *id); diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 4cbef2859b..409c6c59d7 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -312,6 +312,10 @@ gst_matroska_demux_reset (GstElement * element) demux->tracks_parsed = FALSE; demux->segmentinfo_parsed = FALSE; + g_list_foreach (demux->tags_parsed, (GFunc) gst_ebml_level_free, NULL); + g_list_free (demux->tags_parsed); + demux->tags_parsed = NULL; + gst_segment_init (&demux->segment, GST_FORMAT_TIME); } @@ -2318,6 +2322,39 @@ gst_matroska_demux_parse_metadata (GstMatroskaDemux * demux, guint32 id; + GList *l; + + GstEbmlLevel *curlevel; + + /* Can't be NULL at this point */ + g_assert (ebml->level != NULL); + curlevel = ebml->level->data; + + /* Make sure we don't parse a tags element twice and + * post it's tags twice */ + for (l = demux->tags_parsed; l; l = l->next) { + GstEbmlLevel *level = l->data; + + if (ebml->level) + curlevel = ebml->level->data; + else + break; + + if (level->start == curlevel->start && level->length == curlevel->length) { + GST_DEBUG_OBJECT (demux, "Skipping already parsed Tags at offset %" + G_GUINT64_FORMAT, ebml->offset); + ret = gst_ebml_read_skip (ebml); + return ret; + } + } + + GST_DEBUG_OBJECT (demux, "Parsing Tags at offset %" G_GUINT64_FORMAT, + ebml->offset); + /* TODO: g_slice_dup() if we depend on GLib 2.14 */ + curlevel = g_slice_new (GstEbmlLevel); + memcpy (curlevel, ebml->level->data, sizeof (GstEbmlLevel)); + demux->tags_parsed = g_list_prepend (demux->tags_parsed, curlevel); + /* TODO: review length/eos logic */ if (prevent_eos) { length = gst_ebml_read_get_length (ebml); diff --git a/gst/matroska/matroska-demux.h b/gst/matroska/matroska-demux.h index 413cdc8a3f..8ea9c3acef 100644 --- a/gst/matroska/matroska-demux.h +++ b/gst/matroska/matroska-demux.h @@ -81,6 +81,7 @@ typedef struct _GstMatroskaDemux { gboolean index_parsed; gboolean tracks_parsed; gboolean segmentinfo_parsed; + GList *tags_parsed; /* start-of-segment */ guint64 ebml_segment_start;