From 0745d567a7959e01b4308c0971134d5c3d272c39 Mon Sep 17 00:00:00 2001 From: Alex Ashley Date: Tue, 10 Nov 2015 16:19:34 +0000 Subject: [PATCH] hlsdemux: correct the calculation of seek range of non-live streams 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 | 12 ++++++++---- tests/check/elements/hlsdemux_m3u8.c | 11 +++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c index c49f4337f9..a70bc747d3 100644 --- a/ext/hls/m3u8.c +++ b/ext/hls/m3u8.c @@ -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; diff --git a/tests/check/elements/hlsdemux_m3u8.c b/tests/check/elements/hlsdemux_m3u8.c index c64640cb76..6f638f9cce 100644 --- a/tests/check/elements/hlsdemux_m3u8.c +++ b/tests/check/elements/hlsdemux_m3u8.c @@ -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); }