matroskademux: fix bridging (time) gaps in streams

As a side effect, avoid sending newsegment updates with start times
that go back and forth, which leads to bogus downstream running_time.

Also fixes seeking in bug #606744.
This commit is contained in:
Mark Nauwelaerts 2010-01-28 18:53:18 +01:00
parent 9bec2b1127
commit b527360f21

View file

@ -4382,17 +4382,42 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
goto done; goto done;
} }
if (GST_CLOCK_TIME_IS_VALID (stream->pos)) { /* handle gaps, e.g. non-zero start-time, or an cue index entry
GstClockTimeDiff diff = GST_CLOCK_DIFF (stream->pos, lace_time); * that landed us with timestamps not quite intended */
if (GST_CLOCK_TIME_IS_VALID (demux->segment.last_stop)) {
GstClockTimeDiff diff;
if (diff < -GST_SECOND / 2 || diff > GST_SECOND / 2) { /* only send newsegments with increasing start times,
* otherwise if these go back and forth downstream (sinks) increase
* accumulated time and running_time */
diff = GST_CLOCK_DIFF (demux->segment.last_stop, lace_time);
if (diff > 2 * GST_SECOND && lace_time > demux->segment.start &&
(!GST_CLOCK_TIME_IS_VALID (demux->segment.stop) ||
lace_time < demux->segment.stop)) {
GST_DEBUG_OBJECT (demux, GST_DEBUG_OBJECT (demux,
"Gap of %" G_GINT64_FORMAT " ns detected in" "Gap of %" G_GINT64_FORMAT " ns detected in"
"stream %d. Sending updated NEWSEGMENT event", diff, "stream %d (" GST_TIME_FORMAT " -> " GST_TIME_FORMAT "). "
stream->index); "Sending updated NEWSEGMENT events", diff,
gst_pad_push_event (stream->pad, gst_event_new_new_segment (TRUE, stream->index, GST_TIME_ARGS (stream->pos),
demux->segment.rate, demux->segment.format, lace_time, GST_TIME_ARGS (lace_time));
demux->segment.stop, lace_time)); /* send newsegment events such that the gap is not accounted in
* accum time, hence running_time */
/* close ahead of gap */
gst_matroska_demux_send_event (demux,
gst_event_new_new_segment (TRUE, demux->segment.rate,
demux->segment.format, demux->segment.last_stop,
demux->segment.last_stop, demux->segment.last_stop));
/* skip gap */
gst_matroska_demux_send_event (demux,
gst_event_new_new_segment (FALSE, demux->segment.rate,
demux->segment.format, lace_time, demux->segment.stop,
lace_time));
/* align segment view with downstream,
* prevents double-counting accum when closing segment */
gst_segment_set_newsegment (&demux->segment, FALSE,
demux->segment.rate, demux->segment.format, lace_time,
demux->segment.stop, lace_time);
demux->segment.last_stop = lace_time;
} }
} }