hlsdemux2: No longer re-add segments from before the playlist
authorEdward Hervey <edward@centricular.com>
Thu, 2 Jun 2022 07:46:22 +0000 (09:46 +0200)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Tue, 28 Jun 2022 17:59:23 +0000 (17:59 +0000)
When updating playlists, there is a possibility that the playlists don't
perfectly align, but the last entry of the previous playlist is *just* before
the first entry of the new playlist.

In those cases, we still can transfer the timing information from one playlist
to another, but we do not want to return that segment as being the matching one.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2679>

subprojects/gst-plugins-good/ext/adaptivedemux2/hls/m3u8.c

index 0668139..8ffdccc 100644 (file)
@@ -946,14 +946,20 @@ gst_hls_media_playlist_find_by_uri (GstHLSMediaPlaylist * playlist,
 /* Find the equivalent segment in the given playlist.
  *
  * The returned segment does *NOT* have increased reference !
+ *
+ * If the provided segment is just before the first entry of the playlist, it
+ * will be added to the playlist (with a reference) and is_before will be set to
+ * TRUE.
  */
 static GstM3U8MediaSegment *
 find_segment_in_playlist (GstHLSMediaPlaylist * playlist,
-    GstM3U8MediaSegment * segment)
+    GstM3U8MediaSegment * segment, gboolean * is_before)
 {
   GstM3U8MediaSegment *res = NULL;
   guint idx;
 
+  *is_before = FALSE;
+
   /* The easy one. Happens when stream times need to be re-synced in an existing
    * playlist */
   if (g_ptr_array_find (playlist->segments, segment, NULL)) {
@@ -994,6 +1000,7 @@ find_segment_in_playlist (GstHLSMediaPlaylist * playlist,
               GST_STIME_ARGS (ddiff));
           g_ptr_array_insert (playlist->segments, 0,
               gst_m3u8_media_segment_ref (segment));
+          *is_before = TRUE;
           return segment;
         }
         if (ddiff > 0) {
@@ -1044,6 +1051,7 @@ find_segment_in_playlist (GstHLSMediaPlaylist * playlist,
       GST_DEBUG ("reference segment is just before 1st segment, inserting");
       g_ptr_array_insert (playlist->segments, 0,
           gst_m3u8_media_segment_ref (segment));
+      *is_before = TRUE;
       return segment;
     }
 
@@ -1065,16 +1073,13 @@ find_segment_in_playlist (GstHLSMediaPlaylist * playlist,
  *
  * If an equivalent/identical one is found it is returned with
  * the reference count incremented
- *
- * If the reference segment is *just* before the 1st segment in the playlist, it
- * will be inserted and returned. This allows coping with non-overlapping (but
- * contiguous) playlist updates.
  */
 GstM3U8MediaSegment *
 gst_hls_media_playlist_sync_to_segment (GstHLSMediaPlaylist * playlist,
     GstM3U8MediaSegment * segment)
 {
   GstM3U8MediaSegment *res = NULL;
+  gboolean is_before;
 #ifndef GST_DISABLE_GST_DEBUG
   gchar *pdtstring;
 #endif
@@ -1088,13 +1093,14 @@ gst_hls_media_playlist_sync_to_segment (GstHLSMediaPlaylist * playlist,
       GST_TIME_ARGS (segment->duration), segment->sequence,
       segment->discont_sequence, segment->uri, playlist->uri);
 
-  res = find_segment_in_playlist (playlist, segment);
+  res = find_segment_in_playlist (playlist, segment, &is_before);
 
   /* For live playlists we re-calculate all stream times based on the existing
    * stream time. Non-live playlists have their stream time calculated at
    * parsing time. */
   if (res) {
-    gst_m3u8_media_segment_ref (res);
+    if (!is_before)
+      gst_m3u8_media_segment_ref (res);
     if (res->stream_time == GST_CLOCK_STIME_NONE)
       res->stream_time = segment->stream_time;
     if (GST_HLS_MEDIA_PLAYLIST_IS_LIVE (playlist))
@@ -1106,6 +1112,11 @@ gst_hls_media_playlist_sync_to_segment (GstHLSMediaPlaylist * playlist,
       res->discont_sequence = segment->discont_sequence;
       gst_hls_media_playlist_recalculate_dsn (playlist, res);
     }
+    if (is_before) {
+      GST_DEBUG ("Dropping segment from before the playlist");
+      g_ptr_array_remove_index (playlist->segments, 0);
+      res = NULL;
+    }
 #ifndef GST_DISABLE_GST_DEBUG
     pdtstring =
         res->datetime ? g_date_time_format_iso8601 (res->datetime) : NULL;
@@ -1163,6 +1174,7 @@ gst_hls_media_playlist_sync_to_playlist (GstHLSMediaPlaylist * playlist,
   GstM3U8MediaSegment *res = NULL;
   GstM3U8MediaSegment *cand = NULL;
   guint idx;
+  gboolean is_before;
 
   g_return_val_if_fail (playlist && reference, FALSE);
 
@@ -1171,7 +1183,7 @@ gst_hls_media_playlist_sync_to_playlist (GstHLSMediaPlaylist * playlist,
    * go backwards */
   for (idx = reference->segments->len - 1; idx; idx--) {
     cand = g_ptr_array_index (reference->segments, idx);
-    res = find_segment_in_playlist (playlist, cand);
+    res = find_segment_in_playlist (playlist, cand, &is_before);
     if (res)
       break;
   }
@@ -1193,6 +1205,9 @@ gst_hls_media_playlist_sync_to_playlist (GstHLSMediaPlaylist * playlist,
     res->discont_sequence = cand->discont_sequence;
     gst_hls_media_playlist_recalculate_dsn (playlist, res);
   }
+  if (is_before) {
+    g_ptr_array_remove_index (playlist->segments, 0);
+  }
 
   return TRUE;
 }