summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Waters <matthew@centricular.com>2017-04-07 16:33:21 +1000
committerMatthew Waters <matthew@centricular.com>2017-04-25 14:16:15 +1000
commit0886160123115f8b9f90ad5811d6bd9a171b92e8 (patch)
treeac528ac6c38c722de16dc3498e23c547e3af7cf6
parent5199aa60d5fd11c70553801b24f37e56db2655cd (diff)
downloadgstreamer-plugins-bad-0886160123115f8b9f90ad5811d6bd9a171b92e8.tar.gz
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.
-rw-r--r--gst-libs/gst/adaptivedemux/gstadaptivedemux.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
index 756f0c0db..da755744d 100644
--- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
+++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
@@ -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);