hlsdemux: Don't use approximate duration for fragment buffer pts
authorThomas Bluemel <tbluemel@control4.com>
Fri, 20 Jun 2014 18:38:59 +0000 (12:38 -0600)
committerThiago Santos <thiagoss@osg.samsung.com>
Wed, 7 Jan 2015 12:30:40 +0000 (09:30 -0300)
The duration values in playlists are approximate only, and for
playlist versions 2 and older they are only rounded integer values.
They cannot be used to timestamp buffers.  This resulted in playback
gaps and skips because the actual duration of fragments is slightly
different.  The solution is to only set the pts of the very first
buffer processed, not for each fragment.

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

index c7fefa7..f86a588 100644 (file)
@@ -436,6 +436,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
 
   GST_M3U8_CLIENT_LOCK (hlsdemux->client);
   GST_DEBUG_OBJECT (demux, "seeking to sequence %u", (guint) current_sequence);
+  hlsdemux->reset_pts = TRUE;
   hlsdemux->client->sequence = current_sequence;
   hlsdemux->client->sequence_position = current_pos;
   GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
@@ -461,6 +462,8 @@ gst_hls_demux_setup_streams (GstAdaptiveDemux * demux)
   /* only 1 output supported */
   gst_adaptive_demux_stream_new (demux, gst_hls_demux_create_pad (hlsdemux));
 
+  hlsdemux->reset_pts = TRUE;
+
   return TRUE;
 }
 
@@ -725,6 +728,7 @@ gst_hls_demux_advance_fragment (GstAdaptiveDemuxStream * stream)
 
   gst_m3u8_client_advance_fragment (hlsdemux->client,
       stream->demux->segment.rate > 0);
+  hlsdemux->reset_pts = FALSE;
   return GST_FLOW_OK;
 }
 
@@ -748,8 +752,12 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream)
   }
 
   /* set up our source for download */
-  stream->fragment.timestamp = timestamp;
-  stream->fragment.duration = duration;
+  if (hlsdemux->reset_pts) {
+    stream->fragment.timestamp = timestamp;
+  } else {
+    stream->fragment.timestamp = GST_CLOCK_TIME_NONE;
+  }
+
   if (hlsdemux->current_key)
     g_free (hlsdemux->current_key);
   hlsdemux->current_key = key;
@@ -799,6 +807,7 @@ gst_hls_demux_reset (GstAdaptiveDemux * ademux)
   GstHLSDemux *demux = GST_HLS_DEMUX_CAST (ademux);
 
   demux->do_typefind = TRUE;
+  demux->reset_pts = TRUE;
 
   g_free (demux->key_url);
   demux->key_url = NULL;
@@ -1018,6 +1027,9 @@ retry:
     } else {
       target_pos = 0;
     }
+    if (GST_CLOCK_TIME_IS_VALID (demux->client->sequence_position)) {
+      target_pos = MAX (target_pos, demux->client->sequence_position);
+    }
 
     current_pos = 0;
     for (walk = demux->client->current->files; walk; walk = walk->next) {
index cc9a263..ad23ff1 100644 (file)
@@ -102,6 +102,8 @@ struct _GstHLSDemux
                               * the last buffer can only be pushed when
                               * resized, so need to store and wait for
                               * EOS to know it is the last */
+
+  gboolean reset_pts;
 };
 
 struct _GstHLSDemuxClass