hlsdemux: implement _has_next_fragment to avoid busy looping

It will allow the demuxer to wait for a fragment to be available instead
of busy looping polling the playlist for a new fragment
This commit is contained in:
Thiago Santos 2015-01-08 08:46:48 -03:00
parent 7e7cabb422
commit dd7cb8f632
3 changed files with 52 additions and 0 deletions

View file

@ -115,6 +115,8 @@ static void gst_hls_demux_finish_fragment (GstAdaptiveDemux * demux,
GstAdaptiveDemuxStream * stream, GstBuffer ** buffer);
static GstFlowReturn gst_hls_demux_chunk_received (GstAdaptiveDemux * demux,
GstAdaptiveDemuxStream * stream, GstBuffer ** chunk);
static gboolean gst_hls_demux_stream_has_next_fragment (GstAdaptiveDemuxStream *
stream);
static GstFlowReturn gst_hls_demux_advance_fragment (GstAdaptiveDemuxStream *
stream);
static GstFlowReturn gst_hls_demux_update_fragment_info (GstAdaptiveDemuxStream
@ -205,6 +207,8 @@ gst_hls_demux_class_init (GstHLSDemuxClass * klass)
adaptivedemux_class->update_manifest = gst_hls_demux_update_manifest;
adaptivedemux_class->reset = gst_hls_demux_reset;
adaptivedemux_class->seek = gst_hls_demux_seek;
adaptivedemux_class->stream_has_next_fragment =
gst_hls_demux_stream_has_next_fragment;
adaptivedemux_class->stream_advance_fragment = gst_hls_demux_advance_fragment;
adaptivedemux_class->stream_update_fragment_info =
gst_hls_demux_update_fragment_info;
@ -721,6 +725,15 @@ gst_hls_demux_chunk_received (GstAdaptiveDemux * demux,
return GST_FLOW_OK;
}
static gboolean
gst_hls_demux_stream_has_next_fragment (GstAdaptiveDemuxStream * stream)
{
GstHLSDemux *hlsdemux = GST_HLS_DEMUX_CAST (stream->demux);
return gst_m3u8_client_has_next_fragment (hlsdemux->client,
stream->demux->segment.rate > 0);
}
static GstFlowReturn
gst_hls_demux_advance_fragment (GstAdaptiveDemuxStream * stream)
{

View file

@ -947,6 +947,28 @@ _find_current (GstM3U8MediaFile * file, GstM3U8Client * client)
return file->sequence != client->sequence;
}
static gboolean
has_next_fragment (GstM3U8Client * client, GList * l, gboolean forward)
{
GstM3U8MediaFile *file;
if (!forward)
l = g_list_last (l);
while (l) {
file = l->data;
if (forward && file->sequence > client->sequence)
break;
else if (!forward && file->sequence < client->sequence)
break;
l = (forward ? l->next : l->prev);
}
return l != NULL;
}
static GList *
find_next_fragment (GstM3U8Client * client, GList * l, gboolean forward)
{
@ -1023,6 +1045,22 @@ gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
return TRUE;
}
gboolean
gst_m3u8_client_has_next_fragment (GstM3U8Client * client, gboolean forward)
{
gboolean ret;
g_return_if_fail (client != NULL);
g_return_if_fail (client->current != NULL);
GST_M3U8_CLIENT_LOCK (client);
GST_DEBUG ("Checking if has next fragment %" G_GINT64_FORMAT,
client->sequence + 1);
ret = has_next_fragment (client, client->current->files, forward);
GST_M3U8_CLIENT_UNLOCK (client);
return ret;
}
void
gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward)
{

View file

@ -107,6 +107,7 @@ gboolean gst_m3u8_client_get_next_fragment (GstM3U8Client * client,
gboolean * discontinuity, gchar ** uri, GstClockTime * duration,
GstClockTime * timestamp, gint64 * range_start, gint64 * range_end,
gchar ** key, guint8 ** iv, gboolean forward);
gboolean gst_m3u8_client_has_next_fragment (GstM3U8Client * client, gboolean forward);
void gst_m3u8_client_advance_fragment (GstM3U8Client * client, gboolean forward);
GstClockTime gst_m3u8_client_get_duration (GstM3U8Client * client);
GstClockTime gst_m3u8_client_get_target_duration (GstM3U8Client * client);