hlsdemux: Handle GST_SEEK_TYPE_NONE seek
authorEdward Hervey <edward@centricular.com>
Sat, 26 Nov 2016 08:26:36 +0000 (09:26 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Sat, 26 Nov 2016 09:45:52 +0000 (10:45 +0100)
When one is only updating the "stop" position (i.e. non-flushing seek,
with GST_SEEK_TYPE_NONE on the "start" (or stop in reverse) position),
we only need to store those values instead of moving the current position.

https://bugzilla.gnome.org/show_bug.cgi?id=775127

ext/hls/gsthlsdemux.c

index bb91f30..9247d45 100644 (file)
@@ -296,7 +296,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
   GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (demux);
   GstFormat format;
   GstSeekFlags flags;
-  GstSeekType start_type, stop_type;
+  GstSeekType start_type, stop_type, target_type;
   gint64 start, stop;
   gdouble rate, old_rate;
   GList *walk, *stream_walk;
@@ -348,6 +348,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
     /* TODO why not continue using the same? that was being used up to now? */
     gst_hls_demux_change_playlist (hlsdemux, bitrate, NULL);
   }
+
   for (stream_walk = demux->streams; stream_walk != NULL;
       stream_walk = stream_walk->next) {
     GstHLSDemuxStream *hls_stream =
@@ -358,66 +359,73 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
     current_pos = 0;
     reverse = rate < 0;
     target_pos = reverse ? stop : start;
+    target_type = reverse ? stop_type : start_type;
 
-    /* Snap to segment boundary. Improves seek performance on slow machines. */
-    keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
-    snap_nearest =
-        (flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
-    snap_before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
-    snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
-
-    GST_M3U8_CLIENT_LOCK (hlsdemux->client);
-    /* FIXME: Here we need proper discont handling */
-    for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
-      file = walk->data;
-
-      current_sequence = file->sequence;
-      if ((!reverse && snap_after) || snap_nearest) {
-        if (current_pos >= target_pos)
-          break;
-        if (snap_nearest && target_pos - current_pos < file->duration / 2)
-          break;
-      } else if (reverse && snap_after) {
-        /* check if the next fragment is our target, in this case we want to
-         * start from the previous fragment */
-        GstClockTime next_pos = current_pos + file->duration;
-
-        if (next_pos <= target_pos && target_pos < next_pos + file->duration) {
+    if (target_type == GST_SEEK_TYPE_NONE && !(flags & GST_SEEK_FLAG_FLUSH)) {
+      /* No need to move */
+      gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
+          start, stop_type, stop, NULL);
+    } else {
+      /* Snap to segment boundary. Improves seek performance on slow machines. */
+      keyunit = ! !(flags & GST_SEEK_FLAG_KEY_UNIT);
+      snap_nearest =
+          (flags & GST_SEEK_FLAG_SNAP_NEAREST) == GST_SEEK_FLAG_SNAP_NEAREST;
+      snap_before = ! !(flags & GST_SEEK_FLAG_SNAP_BEFORE);
+      snap_after = ! !(flags & GST_SEEK_FLAG_SNAP_AFTER);
+
+      GST_M3U8_CLIENT_LOCK (hlsdemux->client);
+      /* FIXME: Here we need proper discont handling */
+      for (walk = hls_stream->playlist->files; walk; walk = walk->next) {
+        file = walk->data;
+
+        current_sequence = file->sequence;
+        if ((!reverse && snap_after) || snap_nearest) {
+          if (current_pos >= target_pos)
+            break;
+          if (snap_nearest && target_pos - current_pos < file->duration / 2)
+            break;
+        } else if (reverse && snap_after) {
+          /* check if the next fragment is our target, in this case we want to
+           * start from the previous fragment */
+          GstClockTime next_pos = current_pos + file->duration;
+
+          if (next_pos <= target_pos && target_pos < next_pos + file->duration) {
+            break;
+          }
+        } else if (current_pos <= target_pos
+            && target_pos < current_pos + file->duration) {
           break;
         }
-      } else if (current_pos <= target_pos
-          && target_pos < current_pos + file->duration) {
-        break;
+        current_pos += file->duration;
       }
-      current_pos += file->duration;
-    }
-
-    if (walk == NULL) {
-      GST_DEBUG_OBJECT (demux, "seeking further than track duration");
-      current_sequence++;
-    }
 
-    GST_DEBUG_OBJECT (demux, "seeking to sequence %u",
-        (guint) current_sequence);
-    hls_stream->reset_pts = TRUE;
-    hls_stream->playlist->sequence = current_sequence;
-    hls_stream->playlist->current_file = walk;
-    hls_stream->playlist->sequence_position = current_pos;
-    GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
+      if (walk == NULL) {
+        GST_DEBUG_OBJECT (demux, "seeking further than track duration");
+        current_sequence++;
+      }
 
-    /* Play from the end of the current selected segment */
-    if (file) {
-      if (reverse && (snap_before || snap_after || snap_nearest))
-        current_pos += file->duration;
-    }
+      GST_DEBUG_OBJECT (demux, "seeking to sequence %u",
+          (guint) current_sequence);
+      hls_stream->reset_pts = TRUE;
+      hls_stream->playlist->sequence = current_sequence;
+      hls_stream->playlist->current_file = walk;
+      hls_stream->playlist->sequence_position = current_pos;
+      GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
+
+      /* Play from the end of the current selected segment */
+      if (file) {
+        if (reverse && (snap_before || snap_after || snap_nearest))
+          current_pos += file->duration;
+      }
 
-    if (keyunit || snap_before || snap_after || snap_nearest) {
-      if (!reverse)
-        gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
-            current_pos, stop_type, stop, NULL);
-      else
-        gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
-            start, stop_type, current_pos, NULL);
+      if (keyunit || snap_before || snap_after || snap_nearest) {
+        if (!reverse)
+          gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
+              current_pos, stop_type, stop, NULL);
+        else
+          gst_segment_do_seek (&demux->segment, rate, format, flags, start_type,
+              start, stop_type, current_pos, NULL);
+      }
     }
   }