summaryrefslogtreecommitdiff
path: root/ext/hls
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@osg.samsung.com>2015-01-08 08:46:48 -0300
committerThiago Santos <thiagoss@osg.samsung.com>2015-01-08 09:59:01 -0300
commitdd7cb8f6327dea4c2278117e06cd0210bc8f22c9 (patch)
treee271f7b7f579c232b58601fae0cf9f7476213f20 /ext/hls
parent7e7cabb4228a4d8beeda15a497c09e0bbf188390 (diff)
downloadgstreamer-plugins-bad-dd7cb8f6327dea4c2278117e06cd0210bc8f22c9.tar.gz
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
Diffstat (limited to 'ext/hls')
-rw-r--r--ext/hls/gsthlsdemux.c13
-rwxr-xr-xext/hls/m3u8.c38
-rwxr-xr-xext/hls/m3u8.h1
3 files changed, 52 insertions, 0 deletions
diff --git a/ext/hls/gsthlsdemux.c b/ext/hls/gsthlsdemux.c
index f86a5883c..f465f499f 100644
--- a/ext/hls/gsthlsdemux.c
+++ b/ext/hls/gsthlsdemux.c
@@ -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)
{
diff --git a/ext/hls/m3u8.c b/ext/hls/m3u8.c
index a27bca187..01a370a73 100755
--- a/ext/hls/m3u8.c
+++ b/ext/hls/m3u8.c
@@ -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)
{
diff --git a/ext/hls/m3u8.h b/ext/hls/m3u8.h
index cef3bc63d..2f78e8cf6 100755
--- a/ext/hls/m3u8.h
+++ b/ext/hls/m3u8.h
@@ -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);