hlsdemux: When updating a non-live playlist make sure to find the current sequence...
authorSebastian Dröge <sebastian@centricular.com>
Thu, 10 Apr 2014 12:46:01 +0000 (14:46 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Thu, 10 Apr 2014 13:06:53 +0000 (15:06 +0200)
Sequence numbers in different playlists are not guaranteed to be the same for the
same position, e.g. fragments could have different durations in different playlists.

In theory we should do exactly the same for live playlists, but unfortunately we can't
because doing this kind of seeking requires the complete playlist since we started
playback. For live playlists the server is however dropping fragments in the beginning
over time and we have no absolute time references.

ext/hls/gsthlsdemux.c

index 83ffc34..e7656db 100644 (file)
@@ -1222,7 +1222,7 @@ gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
 
   /*  If it's a live source, do not let the sequence number go beyond
    * three fragments before the end of the list */
-  if (updated && update == FALSE && demux->client->current &&
+  if (update == FALSE && demux->client->current &&
       gst_m3u8_client_is_live (demux->client)) {
     gint64 last_sequence;
 
@@ -1238,6 +1238,33 @@ gst_hls_demux_update_playlist (GstHLSDemux * demux, gboolean update,
       demux->client->sequence = last_sequence - 3;
     }
     GST_M3U8_CLIENT_UNLOCK (demux->client);
+  } else if (demux->client->current && !gst_m3u8_client_is_live (demux->client)) {
+    GstClockTime current_pos, target_pos;
+    guint sequence = 0;
+    GList *walk;
+
+    /* Sequence numbers are not guaranteed to be the same in different
+     * playlists, so get the correct fragment here based on the current
+     * position
+     */
+    GST_M3U8_CLIENT_LOCK (demux->client);
+    current_pos = 0;
+    target_pos = demux->segment.position;
+    for (walk = demux->client->current->files; walk; walk = walk->next) {
+      GstM3U8MediaFile *file = walk->data;
+
+      sequence = file->sequence;
+      if (current_pos <= target_pos
+          && target_pos < current_pos + file->duration) {
+        break;
+      }
+      current_pos += file->duration;
+    }
+    /* End of playlist */
+    if (!walk)
+      sequence++;
+    demux->client->sequence = sequence;
+    GST_M3U8_CLIENT_UNLOCK (demux->client);
   }
 
   return updated;