From cd6069f5af03b35fd0182ac9dfac3b4c0eccbe4d Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Fri, 20 Jun 2014 12:38:59 -0600 Subject: [PATCH] hlsdemux: Don't use approximate duration for fragment buffer pts 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 | 16 ++++++++++++++-- ext/hls/gsthlsdemux.h | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c index c7fefa7ad3..f86a5883c2 100644 --- a/ext/hls/gsthlsdemux.c +++ b/ext/hls/gsthlsdemux.c @@ -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) { diff --git a/ext/hls/gsthlsdemux.h b/ext/hls/gsthlsdemux.h index cc9a2637df..ad23ff1e8e 100644 --- a/ext/hls/gsthlsdemux.h +++ b/ext/hls/gsthlsdemux.h @@ -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