mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-22 23:28:16 +00:00
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.
This commit is contained in:
parent
2a22e9d487
commit
bbded080e0
1 changed files with 31 additions and 16 deletions
|
@ -1919,6 +1919,7 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux)
|
||||||
{
|
{
|
||||||
guint8 n = 0;
|
guint8 n = 0;
|
||||||
guint32 seg_idx = 0, k_index = 0;
|
guint32 seg_idx = 0, k_index = 0;
|
||||||
|
guint32 ref_seg_idx, ref_k_index;
|
||||||
guint64 k_pos = 0, last_stop = 0;
|
guint64 k_pos = 0, last_stop = 0;
|
||||||
QtDemuxSegment *seg = NULL;
|
QtDemuxSegment *seg = NULL;
|
||||||
QtDemuxStream *ref_str = NULL;
|
QtDemuxStream *ref_str = NULL;
|
||||||
|
@ -2016,33 +2017,47 @@ gst_qtdemux_seek_to_previous_keyframe (GstQTDemux * qtdemux)
|
||||||
goto eos;
|
goto eos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ref_seg_idx = ref_str->segment_index;
|
||||||
|
ref_k_index = k_index;
|
||||||
|
|
||||||
/* Align them all on this */
|
/* Align them all on this */
|
||||||
for (n = 0; n < qtdemux->n_streams; n++) {
|
for (n = 0; n < qtdemux->n_streams; n++) {
|
||||||
guint32 index = 0;
|
guint32 index = 0;
|
||||||
guint64 media_start = 0, seg_time = 0;
|
guint64 media_start = 0, seg_time = 0;
|
||||||
QtDemuxStream *str = qtdemux->streams[n];
|
QtDemuxStream *str = qtdemux->streams[n];
|
||||||
|
|
||||||
seg_idx = gst_qtdemux_find_segment (qtdemux, str, k_pos);
|
/* aligning reference stream again might lead to backing up to yet another
|
||||||
GST_DEBUG_OBJECT (qtdemux, "align segment %d", seg_idx);
|
* 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 */
|
/* segment not found, continue with normal flow */
|
||||||
if (seg_idx == -1)
|
if (seg_idx == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* get segment and time in the segment */
|
/* get segment and time in the segment */
|
||||||
seg = &str->segments[seg_idx];
|
seg = &str->segments[seg_idx];
|
||||||
seg_time = k_pos - seg->time;
|
seg_time = k_pos - seg->time;
|
||||||
|
|
||||||
/* get the media time in the segment */
|
/* get the media time in the segment */
|
||||||
media_start = seg->media_start + seg_time;
|
media_start = seg->media_start + seg_time;
|
||||||
|
|
||||||
/* get the index of the sample with media time */
|
/* get the index of the sample with media time */
|
||||||
index = gst_qtdemux_find_index (qtdemux, str, media_start);
|
index = gst_qtdemux_find_index (qtdemux, str, media_start);
|
||||||
GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u",
|
GST_DEBUG_OBJECT (qtdemux, "sample for %" GST_TIME_FORMAT " at %u",
|
||||||
GST_TIME_ARGS (media_start), index);
|
GST_TIME_ARGS (media_start), index);
|
||||||
|
|
||||||
/* find previous keyframe */
|
/* find previous keyframe */
|
||||||
k_index = gst_qtdemux_find_keyframe (qtdemux, str, index);
|
k_index = gst_qtdemux_find_keyframe (qtdemux, str, index);
|
||||||
|
}
|
||||||
|
|
||||||
/* Remember until where we want to go */
|
/* Remember until where we want to go */
|
||||||
str->to_sample = str->from_sample - 1;
|
str->to_sample = str->from_sample - 1;
|
||||||
|
|
Loading…
Reference in a new issue