From bbded080e0525b7d3646977ebbb46215ea36e434 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 8 Jul 2010 18:57:21 +0200 Subject: [PATCH] qtdemux: do not align reverse playback reference stream twice Timestamp rounding issues could lead to going backwards 2 keyframe periods (rather than only 1). While this is not necessarily a problem, it might potentially place additional (buffering) load on downstream and could be avoided (because We Can). Fixes #623629. --- gst/qtdemux/qtdemux.c | 47 ++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index fea3385885..9f6d08b2da 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -1919,6 +1919,7 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux) { guint8 n = 0; guint32 seg_idx = 0, k_index = 0; + guint32 ref_seg_idx, ref_k_index; guint64 k_pos = 0, last_stop = 0; QtDemuxSegment *seg = NULL; QtDemuxStream *ref_str = NULL; @@ -2016,33 +2017,47 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux) goto eos; } + ref_seg_idx = ref_str->segment_index; + ref_k_index = k_index; + /* Align them all on this */ for (n = 0; n < qtdemux->n_streams; n++) { guint32 index = 0; guint64 media_start = 0, seg_time = 0; QtDemuxStream *str = qtdemux->streams[n]; - seg_idx = gst_qtdemux_find_segment (qtdemux, str, k_pos); - GST_DEBUG_OBJECT (qtdemux, "align segment %d", seg_idx); + /* aligning reference stream again might lead to backing up to yet another + * keyframe (due to timestamp rounding issues), + * potentially putting more load on downstream; so let's try to avoid */ + if (str == ref_str) { + seg_idx = ref_seg_idx; + seg = &str->segments[seg_idx]; + k_index = ref_k_index; + GST_DEBUG_OBJECT (qtdemux, "reference stream segment %d, " + "sample at index %d", ref_str->segment_index, k_index); + } else { + seg_idx = gst_qtdemux_find_segment (qtdemux, str, k_pos); + GST_DEBUG_OBJECT (qtdemux, "align segment %d", seg_idx); - /* segment not found, continue with normal flow */ - if (seg_idx == -1) - continue; + /* segment not found, continue with normal flow */ + if (seg_idx == -1) + continue; - /* get segment and time in the segment */ - seg = &str->segments[seg_idx]; - seg_time = k_pos - seg->time; + /* get segment and time in the segment */ + seg = &str->segments[seg_idx]; + seg_time = k_pos - seg->time; - /* get the media time in the segment */ - media_start = seg->media_start + seg_time; + /* get the media time in the segment */ + media_start = seg->media_start + seg_time; - /* get the index of the sample with media time */ - index = gst_qtdemux_find_index (qtdemux, str, media_start); - GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u", - GST_TIME_ARGS (media_start), index); + /* get the index of the sample with media time */ + index = gst_qtdemux_find_index (qtdemux, str, media_start); + GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u", + GST_TIME_ARGS (media_start), index); - /* find previous keyframe */ - k_index = gst_qtdemux_find_keyframe (qtdemux, str, index); + /* find previous keyframe */ + k_index = gst_qtdemux_find_keyframe (qtdemux, str, index); + } /* Remember until where we want to go */ str->to_sample = str->from_sample - 1;