adaptivedemux: Implement GST_SEEK_TYPE_END usage for live
authorEdward Hervey <edward@centricular.com>
Fri, 5 May 2017 16:25:43 +0000 (18:25 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Tue, 9 May 2017 07:02:07 +0000 (09:02 +0200)
When dealing with live streams, we can't rely on GstSegment calculation
since it uses the segment duration to calculate the absolute values.

But since we are dealing with live *and* we know the ranges, we can
compute the absolute seeking values using the range stop (i.e. "now")
as the END position.

Allows seeking back to "live" by using start_type:GST_SEEK_TYPE_END
and start:0

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

gst-libs/gst/adaptivedemux/gstadaptivedemux.c

index a5e517b..c3f4cd6 100644 (file)
@@ -1502,6 +1502,7 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
 
   if (gst_adaptive_demux_is_live (demux)) {
     gint64 range_start, range_stop;
+    gboolean changed = FALSE;
     if (!gst_adaptive_demux_get_live_seek_range (demux, &range_start,
             &range_stop)) {
       GST_MANIFEST_UNLOCK (demux);
@@ -1510,6 +1511,18 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
       return FALSE;
     }
 
+    /* Handle relative positioning for live streams (relative to the range_stop) */
+    if (start_type == GST_SEEK_TYPE_END) {
+      start = range_stop + start;
+      start_type = GST_SEEK_TYPE_SET;
+      changed = TRUE;
+    }
+    if (stop_type == GST_SEEK_TYPE_END) {
+      stop = range_stop + stop;
+      stop_type = GST_SEEK_TYPE_SET;
+      changed = TRUE;
+    }
+
     if (!(flags & GST_SEEK_FLAG_ACCURATE)) {
       /* If the accurate flag is not set, we allow seeking before the start
        * to map to the start for live cases, since those can return a "moving
@@ -1523,6 +1536,7 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
         start = range_start;
         if (stop != GST_CLOCK_TIME_NONE)
           stop += dt;
+        changed = TRUE;
       }
     }
 
@@ -1533,6 +1547,14 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
       gst_event_unref (event);
       return FALSE;
     }
+
+    if (changed) {
+      gst_event_unref (event);
+      event =
+          gst_event_new_seek (rate, format, flags,
+          start_type, start, stop_type, stop);
+
+    }
   }
 
   seqnum = gst_event_get_seqnum (event);