hlsdemux: correct the calculation of seek range of non-live streams
authorAlex Ashley <bugzilla@ashley-family.net>
Tue, 10 Nov 2015 16:19:34 +0000 (16:19 +0000)
committerSebastian Dröge <sebastian@centricular.com>
Wed, 2 Dec 2015 08:16:25 +0000 (10:16 +0200)
The seek range calculation for on-demand streams was incorrectly
excluding the last three segments of the stream. This three segment
rule should only be applied to live streams [1].

[1] https://tools.ietf.org/html/draft-pantos-http-live-streaming-17#section-6.3.3

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

ext/hls/m3u8.c
tests/check/elements/hlsdemux_m3u8.c

index c49f433..a70bc74 100644 (file)
@@ -1345,6 +1345,7 @@ gst_m3u8_client_get_seek_range (GstM3U8Client * client, gint64 * start,
   GList *walk;
   GstM3U8MediaFile *file;
   guint count;
+  guint min_distance = 0;
 
   g_return_val_if_fail (client != NULL, FALSE);
 
@@ -1355,13 +1356,16 @@ gst_m3u8_client_get_seek_range (GstM3U8Client * client, gint64 * start,
     return FALSE;
   }
 
+  if (GST_M3U8_CLIENT_IS_LIVE (client)) {
+    /* min_distance is used to make sure the seek range is never closer than
+       GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments from the end of a live
+       playlist - see 6.3.3. "Playing the Playlist file" of the HLS draft */
+    min_distance = GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE;
+  }
   count = g_list_length (client->current->files);
 
-  /* count is used to make sure the seek range is never closer than
-     GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments from the end of the
-     playlist - see 6.3.3. "Playing the Playlist file" of the HLS draft */
   for (walk = client->current->files;
-      walk && count >= GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE; walk = walk->next) {
+      walk && count >= min_distance; walk = walk->next) {
     file = walk->data;
     --count;
     duration += file->duration;
index c64640c..6f638f9 100644 (file)
@@ -511,6 +511,8 @@ GST_START_TEST (test_live_playlist)
   GstM3U8Client *client;
   GstM3U8 *pl;
   GstM3U8MediaFile *file;
+  gint64 start = -1;
+  gint64 stop = -1;
 
   client = load_playlist (LIVE_PLAYLIST);
 
@@ -530,6 +532,9 @@ GST_START_TEST (test_live_playlist)
   assert_equals_string (file->uri,
       "https://priv.example.com/fileSequence2683.ts");
   assert_equals_int (file->sequence, 2683);
+  fail_unless (gst_m3u8_client_get_seek_range (client, &start, &stop));
+  assert_equals_int64 (start, 0);
+  assert_equals_float (stop / (double) GST_SECOND, 16.0);
 
   gst_m3u8_client_free (client);
 }
@@ -573,6 +578,8 @@ GST_START_TEST (test_playlist_with_doubles_duration)
   GstM3U8Client *client;
   GstM3U8 *pl;
   GstM3U8MediaFile *file;
+  gint64 start = -1;
+  gint64 stop = -1;
 
   client = load_playlist (DOUBLES_PLAYLIST);
 
@@ -586,6 +593,10 @@ GST_START_TEST (test_playlist_with_doubles_duration)
   assert_equals_float (file->duration / (double) GST_SECOND, 10.2344);
   file = GST_M3U8_MEDIA_FILE (g_list_nth_data (pl->files, 3));
   assert_equals_float (file->duration / (double) GST_SECOND, 9.92);
+  fail_unless (gst_m3u8_client_get_seek_range (client, &start, &stop));
+  assert_equals_int64 (start, 0);
+  assert_equals_float (stop / (double) GST_SECOND,
+      10.321 + 9.6789 + 10.2344 + 9.92);
   gst_m3u8_client_free (client);
 }