Commit 08861601 authored by Matthew Waters's avatar Matthew Waters 🐨
Browse files

adaptivedemux: separate manifest update task from download tasks

Rationale is to allow the manifest update task to continue running while
seeks are occurring.  Otherwise, if the user reliably performs a seek
before the manifest is updated, then as the manifest task is reset on
seeks (and thus the time to wait between manifest updates), the manifest
would never be updated.

This fix makes the manifest update task free-running and continously
update even during seeks.
parent 5199aa60
......@@ -276,6 +276,11 @@ static GstFlowReturn
gst_adaptive_demux_stream_push_event (GstAdaptiveDemuxStream * stream,
GstEvent * event);
static void gst_adaptive_demux_stop_manifest_update_task (GstAdaptiveDemux *
demux);
static void gst_adaptive_demux_start_manifest_update_task (GstAdaptiveDemux *
demux);
static void gst_adaptive_demux_start_tasks (GstAdaptiveDemux * demux,
gboolean start_preroll_streams);
static void gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux);
......@@ -556,11 +561,19 @@ gst_adaptive_demux_change_state (GstElement * element,
GST_MANIFEST_LOCK (demux);
demux->running = FALSE;
gst_adaptive_demux_reset (demux);
gst_adaptive_demux_stop_manifest_update_task (demux);
GST_MANIFEST_UNLOCK (demux);
/* demux->priv->updates_task value never changes, so it is safe to read it
* outside critical section
*/
gst_task_join (demux->priv->updates_task);
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
GST_MANIFEST_LOCK (demux);
gst_adaptive_demux_reset (demux);
if (demux->priv->have_manifest)
gst_adaptive_demux_start_manifest_update_task (demux);
demux->running = TRUE;
GST_MANIFEST_UNLOCK (demux);
break;
......@@ -701,15 +714,7 @@ gst_adaptive_demux_sink_event (GstPad * pad, GstObject * parent,
gst_adaptive_demux_prepare_streams (demux,
gst_adaptive_demux_is_live (demux));
gst_adaptive_demux_start_tasks (demux, TRUE);
if (gst_adaptive_demux_is_live (demux)) {
g_mutex_lock (&demux->priv->updates_timed_lock);
demux->priv->stop_updates_task = FALSE;
g_mutex_unlock (&demux->priv->updates_timed_lock);
/* Task to periodically update the manifest */
if (demux_class->requires_periodical_playlist_update (demux)) {
gst_task_start (demux->priv->updates_task);
}
}
gst_adaptive_demux_start_manifest_update_task (demux);
} else {
/* no streams */
GST_WARNING_OBJECT (demux, "No streams created from manifest");
......@@ -770,7 +775,6 @@ gst_adaptive_demux_reset (GstAdaptiveDemux * demux)
demux->priv->old_streams = NULL;
gst_adaptive_demux_stop_tasks (demux);
gst_uri_downloader_reset (demux->downloader);
if (klass->reset)
klass->reset (demux);
......@@ -1686,13 +1690,6 @@ gst_adaptive_demux_handle_seek_event (GstAdaptiveDemux * demux, GstPad * pad,
gst_adaptive_demux_start_tasks (demux, FALSE);
}
if (gst_adaptive_demux_is_live (demux)) {
g_mutex_lock (&demux->priv->updates_timed_lock);
demux->priv->stop_updates_task = FALSE;
g_mutex_unlock (&demux->priv->updates_timed_lock);
/* Task to periodically update the manifest */
gst_task_start (demux->priv->updates_task);
}
GST_MANIFEST_UNLOCK (demux);
GST_API_UNLOCK (demux);
gst_event_unref (event);
......@@ -1900,6 +1897,38 @@ gst_adaptive_demux_start_tasks (GstAdaptiveDemux * demux,
}
}
/* must be called with manifest_lock taken */
static void
gst_adaptive_demux_stop_manifest_update_task (GstAdaptiveDemux * demux)
{
gst_uri_downloader_cancel (demux->downloader);
gst_task_stop (demux->priv->updates_task);
g_mutex_lock (&demux->priv->updates_timed_lock);
demux->priv->stop_updates_task = TRUE;
g_cond_signal (&demux->priv->updates_timed_cond);
g_mutex_unlock (&demux->priv->updates_timed_lock);
}
/* must be called with manifest_lock taken */
static void
gst_adaptive_demux_start_manifest_update_task (GstAdaptiveDemux * demux)
{
GstAdaptiveDemuxClass *demux_class = GST_ADAPTIVE_DEMUX_GET_CLASS (demux);
if (gst_adaptive_demux_is_live (demux)) {
gst_uri_downloader_reset (demux->downloader);
g_mutex_lock (&demux->priv->updates_timed_lock);
demux->priv->stop_updates_task = FALSE;
g_mutex_unlock (&demux->priv->updates_timed_lock);
/* Task to periodically update the manifest */
if (demux_class->requires_periodical_playlist_update (demux)) {
gst_task_start (demux->priv->updates_task);
}
}
}
/* must be called with manifest_lock taken
* This function will temporarily release manifest_lock in order to join the
* download threads.
......@@ -1911,13 +1940,6 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux)
{
GList *iter;
gst_task_stop (demux->priv->updates_task);
g_mutex_lock (&demux->priv->updates_timed_lock);
demux->priv->stop_updates_task = TRUE;
g_cond_signal (&demux->priv->updates_timed_cond);
g_mutex_unlock (&demux->priv->updates_timed_lock);
GST_LOG_OBJECT (demux, "Stopping tasks");
for (iter = demux->streams; iter; iter = g_list_next (iter)) {
......@@ -1934,8 +1956,6 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux)
g_cond_broadcast (&demux->priv->preroll_cond);
g_mutex_unlock (&demux->priv->preroll_lock);
gst_uri_downloader_cancel (demux->downloader);
g_mutex_lock (&demux->priv->manifest_update_lock);
g_cond_broadcast (&demux->priv->manifest_cond);
g_mutex_unlock (&demux->priv->manifest_update_lock);
......@@ -1966,11 +1986,6 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux)
GST_MANIFEST_UNLOCK (demux);
/* demux->priv->updates_task value never changes, so it is safe to read it
* outside critical section
*/
gst_task_join (demux->priv->updates_task);
GST_MANIFEST_LOCK (demux);
for (iter = demux->streams; iter; iter = g_list_next (iter)) {
......@@ -3771,16 +3786,15 @@ gst_adaptive_demux_updates_loop (GstAdaptiveDemux * demux)
&demux->priv->updates_timed_lock, next_update);
g_mutex_unlock (&demux->priv->updates_timed_lock);
GST_MANIFEST_LOCK (demux);
g_mutex_lock (&demux->priv->updates_timed_lock);
if (demux->priv->stop_updates_task) {
g_mutex_unlock (&demux->priv->updates_timed_lock);
GST_MANIFEST_UNLOCK (demux);
goto quit;
}
g_mutex_unlock (&demux->priv->updates_timed_lock);
GST_MANIFEST_LOCK (demux);
GST_DEBUG_OBJECT (demux, "Updating playlist");
ret = gst_adaptive_demux_update_manifest (demux);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment