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.
This commit is contained in:
Thomas Bluemel 2014-06-20 12:38:59 -06:00 committed by Thiago Santos
parent c1251ab861
commit cd6069f5af
2 changed files with 16 additions and 2 deletions

View file

@ -436,6 +436,7 @@ gst_hls_demux_seek (GstAdaptiveDemux * demux, GstEvent * seek)
GST_M3U8_CLIENT_LOCK (hlsdemux->client); GST_M3U8_CLIENT_LOCK (hlsdemux->client);
GST_DEBUG_OBJECT (demux, "seeking to sequence %u", (guint) current_sequence); GST_DEBUG_OBJECT (demux, "seeking to sequence %u", (guint) current_sequence);
hlsdemux->reset_pts = TRUE;
hlsdemux->client->sequence = current_sequence; hlsdemux->client->sequence = current_sequence;
hlsdemux->client->sequence_position = current_pos; hlsdemux->client->sequence_position = current_pos;
GST_M3U8_CLIENT_UNLOCK (hlsdemux->client); GST_M3U8_CLIENT_UNLOCK (hlsdemux->client);
@ -461,6 +462,8 @@ gst_hls_demux_setup_streams (GstAdaptiveDemux * demux)
/* only 1 output supported */ /* only 1 output supported */
gst_adaptive_demux_stream_new (demux, gst_hls_demux_create_pad (hlsdemux)); gst_adaptive_demux_stream_new (demux, gst_hls_demux_create_pad (hlsdemux));
hlsdemux->reset_pts = TRUE;
return TRUE; return TRUE;
} }
@ -725,6 +728,7 @@ gst_hls_demux_advance_fragment (GstAdaptiveDemuxStream * stream)
gst_m3u8_client_advance_fragment (hlsdemux->client, gst_m3u8_client_advance_fragment (hlsdemux->client,
stream->demux->segment.rate > 0); stream->demux->segment.rate > 0);
hlsdemux->reset_pts = FALSE;
return GST_FLOW_OK; return GST_FLOW_OK;
} }
@ -748,8 +752,12 @@ gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream * stream)
} }
/* set up our source for download */ /* set up our source for download */
stream->fragment.timestamp = timestamp; if (hlsdemux->reset_pts) {
stream->fragment.duration = duration; stream->fragment.timestamp = timestamp;
} else {
stream->fragment.timestamp = GST_CLOCK_TIME_NONE;
}
if (hlsdemux->current_key) if (hlsdemux->current_key)
g_free (hlsdemux->current_key); g_free (hlsdemux->current_key);
hlsdemux->current_key = key; hlsdemux->current_key = key;
@ -799,6 +807,7 @@ gst_hls_demux_reset (GstAdaptiveDemux * ademux)
GstHLSDemux *demux = GST_HLS_DEMUX_CAST (ademux); GstHLSDemux *demux = GST_HLS_DEMUX_CAST (ademux);
demux->do_typefind = TRUE; demux->do_typefind = TRUE;
demux->reset_pts = TRUE;
g_free (demux->key_url); g_free (demux->key_url);
demux->key_url = NULL; demux->key_url = NULL;
@ -1018,6 +1027,9 @@ retry:
} else { } else {
target_pos = 0; 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; current_pos = 0;
for (walk = demux->client->current->files; walk; walk = walk->next) { for (walk = demux->client->current->files; walk; walk = walk->next) {

View file

@ -102,6 +102,8 @@ struct _GstHLSDemux
* the last buffer can only be pushed when * the last buffer can only be pushed when
* resized, so need to store and wait for * resized, so need to store and wait for
* EOS to know it is the last */ * EOS to know it is the last */
gboolean reset_pts;
}; };
struct _GstHLSDemuxClass struct _GstHLSDemuxClass