From 5baf5f4b1e45ef5bced93bd1d5f9fe5363047541 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 17 Nov 2022 02:59:37 +1100 Subject: [PATCH] hlsdemux2: Add a timestamp to the playlist Store the timestamp for this playlist. If valid it represents the monotonic time at which the data was retrieved, minus any proxy cache Age field. Part-of: --- .../ext/adaptivedemux2/hls/gsthlsdemux.c | 16 +++++++++++----- .../ext/adaptivedemux2/hls/m3u8.c | 7 +++++-- .../ext/adaptivedemux2/hls/m3u8.h | 3 +++ .../tests/check/elements/hlsdemux_m3u8.c | 4 ++-- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c index 2486a3db1b..c0f5ef6c8a 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/gsthlsdemux.c @@ -941,7 +941,7 @@ gst_hls_demux_process_manifest (GstAdaptiveDemux * demux, GstBuffer * buf) if (hlsdemux->master->is_simple) { simple_media_playlist = - gst_hls_media_playlist_parse (playlist, + gst_hls_media_playlist_parse (playlist, GST_CLOCK_TIME_NONE, gst_adaptive_demux_get_manifest_ref_uri (demux), NULL); } @@ -2066,6 +2066,12 @@ download_media_playlist (GstHLSDemux * demux, gchar * uri, GError ** err, "Couldn't download the playlist"); goto out; } + + /* Calculate the newest time we know this playlist was valid to store on the HLS Media Playlist */ + GstClockTime playlist_ts = + MAX (0, GST_CLOCK_DIFF (download_request_get_age (download), + download->download_start_time)); + buf = download_request_take_buffer (download); download_request_unref (download); @@ -2090,7 +2096,9 @@ download_media_playlist (GstHLSDemux * demux, gchar * uri, GError ** err, playlist->reloaded = TRUE; g_free (playlist_data); } else { - playlist = gst_hls_media_playlist_parse (playlist_data, uri, base_uri); + playlist = + gst_hls_media_playlist_parse (playlist_data, playlist_ts, uri, + base_uri); if (!playlist) { GST_WARNING_OBJECT (demux, "Couldn't parse playlist"); if (err) @@ -2424,8 +2432,6 @@ gst_hls_demux_stream_update_media_playlist (GstHLSDemux * demux, GST_WARNING_OBJECT (stream, "Could not get playlist '%s'", *uri); return GST_FLOW_ERROR; } - stream->playlist_last_update_time = - gst_adaptive_demux2_get_monotonic_time (GST_ADAPTIVE_DEMUX (demux)); /* Check if a redirect happened */ if (g_strcmp0 (*uri, new_playlist->uri)) { @@ -2660,7 +2666,7 @@ gst_hls_demux_stream_update_fragment_info (GstAdaptiveDemux2Stream * stream) stream->current_position : GST_CLOCK_TIME_NONE; GstClockTime playlist_age = gst_adaptive_demux2_get_monotonic_time (GST_ADAPTIVE_DEMUX (demux)) - - hlsdemux_stream->playlist_last_update_time; + hlsdemux_stream->playlist->playlist_ts; GST_DEBUG_OBJECT (stream, "Updating fragment information, current_position:%" GST_TIME_FORMAT " which is %" GST_STIME_FORMAT " from live edge. Playlist age %" diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c index f330b6ac01..bbd796c77c 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c @@ -404,6 +404,7 @@ gst_hls_media_playlist_new (const gchar * uri, const gchar * base_uri) m3u8 = g_new0 (GstHLSMediaPlaylist, 1); + m3u8->playlist_ts = GST_CLOCK_TIME_NONE; m3u8->uri = g_strdup (uri); m3u8->base_uri = g_strdup (base_uri); @@ -763,8 +764,8 @@ malformed_line: /* Parse and create a new GstHLSMediaPlaylist */ GstHLSMediaPlaylist * -gst_hls_media_playlist_parse (gchar * data, const gchar * uri, - const gchar * base_uri) +gst_hls_media_playlist_parse (gchar * data, + GstClockTime playlist_ts, const gchar * uri, const gchar * base_uri) { gchar *input_data = data; GstHLSMediaPlaylist *self; @@ -784,6 +785,7 @@ gst_hls_media_playlist_parse (gchar * data, const gchar * uri, GPtrArray *partial_segments = NULL; gboolean is_gap = FALSE; + GST_LOG ("playlist ts: %" GST_TIMEP_FORMAT, &playlist_ts); GST_LOG ("uri: %s", uri); GST_LOG ("base_uri: %s", base_uri); GST_TRACE ("data:\n%s", data); @@ -801,6 +803,7 @@ gst_hls_media_playlist_parse (gchar * data, const gchar * uri, } self = gst_hls_media_playlist_new (uri, base_uri); + self->playlist_ts = playlist_ts; /* Store a copy of the data */ self->last_data = g_strdup (data); diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h index e2a0302f91..ac578a1217 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.h @@ -97,6 +97,8 @@ struct _GstHLSMediaPlaylist gchar *uri; /* actually downloaded URI */ 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 */ + /* Base Tag */ gint version; /* EXT-X-VERSION (default 1) */ @@ -272,6 +274,7 @@ gst_hls_media_playlist_has_same_data (GstHLSMediaPlaylist * m3u8, GstHLSMediaPlaylist * gst_hls_media_playlist_parse (gchar * data, + GstClockTime playlist_ts, const gchar * uri, const gchar * base_uri); diff --git a/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c b/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c index c59ef876ea..45c4f802db 100644 --- a/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c +++ b/subprojects/gst-plugins-good/tests/check/elements/hlsdemux_m3u8.c @@ -265,7 +265,7 @@ load_m3u8 (const gchar * data) GstHLSMediaPlaylist *playlist; playlist = gst_hls_media_playlist_parse (g_strdup (data), - "http://localhost/test.m3u8", NULL); + GST_CLOCK_TIME_NONE, "http://localhost/test.m3u8", NULL); fail_unless (playlist != NULL); return playlist; @@ -556,7 +556,7 @@ GST_START_TEST (test_parse_invalid_playlist) GstHLSMediaPlaylist *pl; pl = gst_hls_media_playlist_parse (g_strdup ("#INVALID"), - "http://localhost/test.m3u8", NULL); + GST_CLOCK_TIME_NONE, "http://localhost/test.m3u8", NULL); fail_if (pl != NULL); }