From 5b68f28c944e7be23b88ba04f7c44c58899dc53d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 2 Jul 2008 08:47:00 +0000 Subject: [PATCH] gst/matroska/matroska-demux.c: If no Tracks element is found until the first Cluster is found search it and error out... Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_loop_stream_parse_id): If no Tracks element is found until the first Cluster is found search it and error out if none is found in the complete file. --- ChangeLog | 7 ++++ gst/matroska/matroska-demux.c | 71 +++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e95b5beda..b38cfce7e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2008-07-02 Sebastian Dröge + + * gst/matroska/matroska-demux.c: + (gst_matroska_demux_loop_stream_parse_id): + If no Tracks element is found until the first Cluster is found + search it and error out if none is found in the complete file. + 2008-07-02 Sebastian Dröge * gst/matroska/matroska-demux.c: (gst_matroska_demux_sync_streams): diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 62fb087b30..037ff30e27 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -4373,7 +4373,7 @@ gst_matroska_demux_loop_stream_parse_id (GstMatroskaDemux * demux, { GstEbmlRead *ebml = GST_EBML_READ (demux); - GstFlowReturn ret; + GstFlowReturn ret = GST_FLOW_OK; switch (id) { /* stream info @@ -4443,8 +4443,73 @@ gst_matroska_demux_loop_stream_parse_id (GstMatroskaDemux * demux, case GST_MATROSKA_ID_CLUSTER: { if (demux->state != GST_MATROSKA_DEMUX_STATE_DATA) { - /* FIXME: Skip first and try to read TRACKS and other things - * first, then go back here. */ + /* We need a Tracks element first before we can output anything. + * Search it! + */ + if (!demux->tracks_parsed) { + GstEbmlLevel *level; + GstFlowReturn iret = GST_FLOW_OK; + guint32 iid; + guint level_up; + guint64 before_pos; + + GST_WARNING_OBJECT (demux, + "Found Cluster element before Tracks, searching Tracks"); + + /* remember */ + level_up = demux->level_up; + before_pos = ebml->offset; + + /* we don't want to lose our seekhead level, so we add + * a dummy. This is a crude hack. */ + + level = g_slice_new (GstEbmlLevel); + level->start = 0; + level->length = G_MAXUINT64; + ebml->level = g_list_prepend (ebml->level, level); + + /* Search Tracks element */ + while (iret == GST_FLOW_OK) { + if ((iret = gst_ebml_read_skip (ebml)) != GST_FLOW_OK) + break; + + if ((iret = + gst_ebml_peek_id (ebml, &demux->level_up, + &iid)) != GST_FLOW_OK) + break; + + if (iid != GST_MATROSKA_ID_TRACKS) + continue; + + iret = gst_matroska_demux_parse_tracks (demux); + break; + } + + if (!demux->tracks_parsed) { + GST_ERROR_OBJECT (demux, "No Tracks element found"); + ret = GST_FLOW_ERROR; + } + + /* remove dummy level */ + while (ebml->level) { + guint64 length; + + level = ebml->level->data; + ebml->level = g_list_delete_link (ebml->level, ebml->level); + length = level->length; + g_slice_free (GstEbmlLevel, level); + if (length == G_MAXUINT64) + break; + } + + /* seek back */ + gst_ebml_read_seek (ebml, before_pos); + demux->level_up = level_up; + } + + if (ret != GST_FLOW_OK) + break; + demux->state = GST_MATROSKA_DEMUX_STATE_DATA; /* FIXME: different streams might have different lengths! */ /* send initial discont */