hlsdemux: Implement proper handling of discontinuities
authorSebastian Dröge <sebastian@centricular.com>
Sat, 1 Mar 2014 16:13:58 +0000 (17:13 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Sat, 1 Mar 2014 16:15:54 +0000 (17:15 +0100)
It's not really correct yet for seeks but better than what
we had before.

See https://bugzilla.gnome.org/show_bug.cgi?id=695846

ext/hls/gsthlsdemux.c
ext/hls/gsthlsdemux.h
ext/hls/m3u8.c
ext/hls/m3u8.h

index 4b996ce..1ab1186 100644 (file)
@@ -360,6 +360,7 @@ gst_hls_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
       current_sequence = file->sequence;
       current_pos = 0;
       target_pos = (GstClockTime) start;
+      /* FIXME: Here we need proper discont handling */
       for (walk = demux->client->current->files; walk; walk = walk->next) {
         file = walk->data;
 
@@ -793,9 +794,11 @@ gst_hls_demux_stream_loop (GstHLSDemux * demux)
 
   buf = gst_fragment_get_buffer (fragment);
 
-  if (G_UNLIKELY (!srccaps || !gst_caps_is_equal_fixed (bufcaps, srccaps))) {
+  if (G_UNLIKELY (!srccaps || demux->discont || GST_BUFFER_IS_DISCONT (buf))) {
     switch_pads (demux, bufcaps);
     demux->need_segment = TRUE;
+    demux->discont = FALSE;
+    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
   }
   gst_caps_unref (bufcaps);
   if (G_LIKELY (srccaps))
@@ -905,6 +908,7 @@ gst_hls_demux_reset (GstHLSDemux * demux, gboolean dispose)
 
   demux->position_shift = 0;
   demux->need_segment = TRUE;
+  demux->discont = TRUE;
 
   demux->have_group_id = FALSE;
   demux->group_id = G_MAXUINT;
@@ -1162,6 +1166,7 @@ retry_failover_protection:
 
   GST_INFO_OBJECT (demux, "Client was on %dbps, max allowed is %dbps, switching"
       " to bitrate %dbps", old_bandwidth, max_bitrate, new_bandwidth);
+  demux->discont = TRUE;
 
   if (gst_hls_demux_update_playlist (demux, FALSE, NULL)) {
     GstStructure *s;
@@ -1436,6 +1441,8 @@ gst_hls_demux_get_next_fragment (GstHLSDemux * demux,
   if (discont) {
     GST_DEBUG_OBJECT (demux, "Marking fragment as discontinuous");
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
+  } else {
+    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
   }
 
   /* The buffer ref is still kept inside the fragment download */
index 3cc28b3..fa77c5d 100644 (file)
@@ -94,6 +94,7 @@ struct _GstHLSDemux
   /* Position in the stream */
   GstClockTime position_shift;
   gboolean need_segment;
+  gboolean discont;
 
   /* Cache for the last key */
   gchar *key_url;
index 52fab5b..de6dc61 100644 (file)
@@ -236,7 +236,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
   gint val;
   GstClockTime duration;
   gchar *title, *end;
-//  gboolean discontinuity;
+  gboolean discontinuity = FALSE;
   GstM3U8 *list;
   gboolean have_iv = FALSE;
   guint8 iv[16] = { 0, };
@@ -324,8 +324,11 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
           }
         }
 
+        file->discont = discontinuity;
+
         duration = 0;
         title = NULL;
+        discontinuity = FALSE;
         self->files = g_list_append (self->files, file);
       }
 
@@ -373,7 +376,7 @@ gst_m3u8_update (GstM3U8 * self, gchar * data, gboolean * updated)
       if (int_from_string (data + 22, &data, &val))
         self->mediasequence = val;
     } else if (g_str_has_prefix (data, "#EXT-X-DISCONTINUITY")) {
-      /* discontinuity = TRUE; */
+      discontinuity = TRUE;
     } else if (g_str_has_prefix (data, "#EXT-X-PROGRAM-DATE-TIME:")) {
       /* <YYYY-MM-DDThh:mm:ssZ> */
       GST_DEBUG ("FIXME parse date");
@@ -618,7 +621,7 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
     *timestamp = client->sequence_position;
 
   if (discontinuity)
-    *discontinuity = client->sequence != file->sequence;
+    *discontinuity = client->sequence != file->sequence || file->discont;
   if (uri)
     *uri = file->uri;
   if (duration)
index b249e98..7ec03fa 100644 (file)
@@ -66,6 +66,7 @@ struct _GstM3U8MediaFile
   GstClockTime duration;
   gchar *uri;
   guint sequence;               /* the sequence nb of this file */
+  gboolean discont;             /* this file marks a discontinuity */
   gchar *key;
   guint8 iv[16];
 };