qtdemux: do not align reverse playback reference stream twice
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Thu, 8 Jul 2010 16:57:21 +0000 (18:57 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Fri, 16 Jul 2010 11:58:34 +0000 (13:58 +0200)
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

index fea3385885f72998b61daf3185eeb35e94030f86..9f6d08b2da7b7d3696e5ad3e2c9ed457ba150024 100644 (file)
@@ -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;