From 2d799149482b74709a3116527ad6859b8e289695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Thu, 19 Jun 2008 08:22:16 +0000 Subject: [PATCH] gst/matroska/matroska-demux.c: If a gap of more than 1/2 second is found in one stream send a Original commit message from CVS: * gst/matroska/matroska-demux.c: (gst_matroska_demux_parse_blockgroup_or_simpleblock): If a gap of more than 1/2 second is found in one stream send a NEWSEGMENT event to not stall the pipeline if the gap is too large. This also fixes Matroska files where the first buffer doesn't start at timestamp 0. Fixes bug #429322. The duration of a block is the default duration multiplied with the number of laces. Every lace is one frame and the default duration is the duration of one frame. This fixes playback of files that use lacing for some tracks. --- ChangeLog | 14 ++++++++++++++ gst/matroska/matroska-demux.c | 30 +++++++++++++++++++++--------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7fb139874d..51d9fddce2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-06-19 Sebastian Dröge + + * gst/matroska/matroska-demux.c: + (gst_matroska_demux_parse_blockgroup_or_simpleblock): + If a gap of more than 1/2 second is found in one stream send a + NEWSEGMENT event to not stall the pipeline if the gap is too large. + This also fixes Matroska files where the first buffer doesn't start + at timestamp 0. Fixes bug #429322. + + The duration of a block is the default duration multiplied with the + number of laces. Every lace is one frame and the default duration + is the duration of one frame. This fixes playback of files that use + lacing for some tracks. + 2008-06-18 Sebastian Dröge * gst/matroska/matroska-demux.c: diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index 907e3409cb..f73715f15b 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -25,9 +25,8 @@ * TODO: check CRC32 if present * TODO: there can be a segment after the first segment. Handle like * chained oggs. Fixes #334082 - * TODO: handle gaps better, especially gaps at the start of a track. - * Needs sending of filler segments, closing of segments and - * other magic... Fixes #429322 + * TODO: Better handling of segments: close old segments, start first segment + * at the first buffer timestamp and not at 0 * TODO: Test samples: http://www.matroska.org/samples/matrix/index.html * http://samples.mplayerhq.hu/Matroska/ * TODO: check if demuxing is done correct for all codecs according to spec @@ -3766,12 +3765,14 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, gst_util_gdouble_to_guint64 (gst_util_guint64_to_gdouble (block_duration * demux->time_scale) * stream->timecodescale); } else if (stream->default_duration) { - duration = stream->default_duration; + duration = stream->default_duration * laces; } /* else duration is diff between timecode of this and next block */ for (n = 0; n < laces; n++) { GstBuffer *sub; + GstClockTimeDiff diff; + if (lace_size[n] == 0) continue; @@ -3782,10 +3783,23 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, sub = gst_matroska_decode_buffer (stream, sub); GST_BUFFER_TIMESTAMP (sub) = lace_time; - if (lace_time != GST_CLOCK_TIME_NONE) + + if (lace_time != GST_CLOCK_TIME_NONE) { demux->segment.last_stop = lace_time; + diff = GST_CLOCK_DIFF (stream->pos, lace_time); + if (diff < -GST_SECOND / 2 || diff > GST_SECOND / 2) { + GST_DEBUG_OBJECT (demux, "Gap of %" G_GINT64_FORMAT " ns detected in" + "stream %d. Sending updated NEWSEGMENT event", diff, + stream->index); + gst_pad_push_event (stream->pad, gst_event_new_new_segment (TRUE, + demux->segment.rate, GST_FORMAT_TIME, lace_time, -1, + lace_time)); + } + } + stream->pos = demux->segment.last_stop; + gst_matroska_demux_sync_streams (demux); if (gst_matroska_demux_stream_is_wavpack (stream)) { @@ -3794,11 +3808,10 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, &sub); } - /* FIXME: do all laces have the same length? the lenght of a lace should - * in theory be default_duration as one lace should contain on frame */ if (duration) { GST_BUFFER_DURATION (sub) = duration / laces; stream->pos += GST_BUFFER_DURATION (sub); + demux->segment.last_stop += GST_BUFFER_DURATION (sub); } if (is_simpleblock) { @@ -3821,7 +3834,6 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, goto done; } - if (stream->set_discont) { GST_BUFFER_FLAG_SET (sub, GST_BUFFER_FLAG_DISCONT); stream->set_discont = FALSE; @@ -3847,7 +3859,7 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, size -= lace_size[n]; if (lace_time != GST_CLOCK_TIME_NONE) - lace_time += duration; + lace_time += duration / laces; } }