From 5bc9883d684aec3bf7904ad0b8a2eaaa0fdd839a Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 15 Apr 2024 08:47:12 +0200 Subject: [PATCH] hlsdemux2: Be more tolerant when matching segments with PDT Some servers might not provide 100% matching PDT when doing updates, or accross variants. This would cause the code matching segments using PDT to fail if the segment PDT was 1 microsecond (or whatever small value) before the candidate segment. And would pick the (wrong) following segment as the matching one. In order to be more tolerant when matching, we instead check whether the candidate segment is within the first segment of the segment we are trying to match. Part-of: --- .../ext/adaptivedemux2/hls/m3u8.c | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c index eda7ff41c7..ceee066cb1 100644 --- a/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c +++ b/subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c @@ -1876,15 +1876,24 @@ find_segment_in_playlist (GstHLSMediaPlaylist * playlist, } } - if (cand->datetime - && g_date_time_difference (cand->datetime, segment->datetime) >= 0) { + /* The reported PDT might not be 100% identical for matching segments + * across playlists, we therefore need to take into account a certain + * tolerance otherwise we would fail to match candidates with a PDT which + * is slightly before. We therefore check whether the segment starts + * within the first third of the candidate segment. + */ + if (cand->datetime) { + GstClockTimeDiff pdtdiff = g_date_time_difference (cand->datetime, + segment->datetime) * GST_USECOND + cand->duration / 3; + if (pdtdiff >= 0) { #ifndef GST_DISABLE_GST_DEBUG - gchar *pdtstring = g_date_time_format_iso8601 (cand->datetime); - GST_DEBUG ("Picking segment with datetime %s", pdtstring); - g_free (pdtstring); + gchar *pdtstring = g_date_time_format_iso8601 (cand->datetime); + GST_DEBUG ("Picking segment with datetime %s", pdtstring); + g_free (pdtstring); #endif - *matched_pdt = TRUE; - return cand; + *matched_pdt = TRUE; + return cand; + } } } }