hlsdemux2: Improve live playlist update intervals

The live playlists should be updated at a defined interval. The problem is that
this interval was used *after* the playlist was finally received and processed,
which resulted in a gradual shift happening in playlist updates.

Instead store and use the time at which playlists were requested to determine
when the next one should be downloaded.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3883>
This commit is contained in:
Edward Hervey 2023-01-04 11:49:14 +01:00 committed by GStreamer Marge Bot
parent 6684aee14c
commit 714628f1ec
3 changed files with 29 additions and 1 deletions

View file

@ -179,7 +179,31 @@ static void
schedule_next_playlist_load (GstHLSDemuxPlaylistLoader * pl,
GstHLSDemuxPlaylistLoaderPrivate * priv, GstClockTime next_load_interval)
{
GST_LOG_OBJECT (pl, "Scheduling next playlist reload");
/* If we have a valid request time, compute a more accurate download time for
* the playlist.
*
* This better takes into account the time it took to actually get and process
* the current playlist.
*/
if (priv->current_playlist
&& GST_CLOCK_TIME_IS_VALID (priv->current_playlist->request_time)) {
GstClockTime now = gst_adaptive_demux2_get_monotonic_time (priv->demux);
GstClockTimeDiff load_diff = GST_CLOCK_DIFF (now,
priv->current_playlist->request_time + next_load_interval);
GST_LOG_OBJECT (pl,
"now %" GST_TIME_FORMAT " request_time %" GST_TIME_FORMAT
" next_load_interval %" GST_TIME_FORMAT, GST_TIME_ARGS (now),
GST_TIME_ARGS (priv->current_playlist->request_time),
GST_TIME_ARGS (next_load_interval));
if (load_diff < 0) {
GST_LOG_OBJECT (pl, "Playlist update already late by %" GST_STIME_FORMAT,
GST_STIME_ARGS (load_diff));
};
next_load_interval = MAX (0, load_diff);
}
GST_LOG_OBJECT (pl, "Scheduling next playlist reload in %" GST_TIME_FORMAT,
GST_TIME_ARGS (next_load_interval));
g_assert (priv->pending_cb_id == 0);
priv->state = PLAYLIST_LOADER_STATE_WAITING;
priv->pending_cb_id =
@ -557,6 +581,7 @@ on_download_complete (DownloadRequest * download, DownloadRequestState state,
GST_DEBUG_OBJECT (pl, "playlist data was unchanged");
playlist = gst_hls_media_playlist_ref (current_playlist);
playlist->reloaded = TRUE;
playlist->request_time = GST_CLOCK_TIME_NONE;
g_free (playlist_data);
} else {
playlist =
@ -566,6 +591,7 @@ on_download_complete (DownloadRequest * download, DownloadRequestState state,
GST_WARNING_OBJECT (pl, "Couldn't parse playlist");
goto error_retry_out;
}
playlist->request_time = download->download_request_time;
}
/* Transfer over any skipped segments from the current playlist if

View file

@ -410,6 +410,7 @@ gst_hls_media_playlist_new (const gchar * uri, const gchar * base_uri)
m3u8->playlist_ts = GST_CLOCK_TIME_NONE;
m3u8->uri = g_strdup (uri);
m3u8->base_uri = g_strdup (base_uri);
m3u8->request_time = GST_CLOCK_TIME_NONE;
m3u8->version = 1;
m3u8->type = GST_HLS_PLAYLIST_TYPE_UNDEFINED;

View file

@ -98,6 +98,7 @@ struct _GstHLSMediaPlaylist
gchar *base_uri; /* URI to use as base for resolving relative URIs.
* This will be different to uri in case of redirects */
GstClockTime playlist_ts; /* Monotonic clock time estimate for this playlist's validity from download time and cached Age */
GstClockTime request_time; /* Time at which this playlist was requested in monotonic clock time. */
/* Base Tag */
gint version; /* EXT-X-VERSION (default 1) */