summaryrefslogtreecommitdiff
path: root/gst-libs
diff options
context:
space:
mode:
authordavecraig@unbalancedaudio.com <davecraig@unbalancedaudio.com>2017-08-08 09:20:00 +0000
committerSebastian Dröge <sebastian@centricular.com>2017-08-11 11:03:30 +0300
commit240ce8d9986b4e1effc3b76d07cb3ea94452c53f (patch)
tree69e4b450728611b0a4ab01c34b2184db036f79d8 /gst-libs
parent2196a0dcd18e0106d3ffa7ff5e1d6c74dd1cd8c5 (diff)
downloadgstreamer-plugins-bad-240ce8d9986b4e1effc3b76d07cb3ea94452c53f.tar.gz
adaptivedemux: Stop prepared streams as well as running streams
There can be twice as many stream tasks running as there are output pads for playback of variant HLS playlists. Half of them are the current pads, and the other half are the pads that are about to be switched to due to a bitrate change. The old code only stopped the current streams which could result in a deadlock on stopping the pipeline. The changes force stopping and joining of any prepared streams too. https://bugzilla.gnome.org/show_bug.cgi?id=785987
Diffstat (limited to 'gst-libs')
-rw-r--r--gst-libs/gst/adaptivedemux/gstadaptivedemux.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
index f2e7f8c73..a0f400712 100644
--- a/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
+++ b/gst-libs/gst/adaptivedemux/gstadaptivedemux.c
@@ -1972,20 +1972,27 @@ gst_adaptive_demux_start_manifest_update_task (GstAdaptiveDemux * demux)
static void
gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux, gboolean stop_updates)
{
+ int i;
GList *iter;
+ GList *list_to_process;
GST_LOG_OBJECT (demux, "Stopping tasks");
if (stop_updates)
gst_adaptive_demux_stop_manifest_update_task (demux);
- for (iter = demux->streams; iter; iter = g_list_next (iter)) {
- GstAdaptiveDemuxStream *stream = iter->data;
- g_mutex_lock (&stream->fragment_download_lock);
- stream->cancelled = TRUE;
- gst_task_stop (stream->download_task);
- g_cond_signal (&stream->fragment_download_cond);
- g_mutex_unlock (&stream->fragment_download_lock);
+ list_to_process = demux->streams;
+ for (i = 0; i < 2; ++i) {
+ for (iter = list_to_process; iter; iter = g_list_next (iter)) {
+ GstAdaptiveDemuxStream *stream = iter->data;
+
+ g_mutex_lock (&stream->fragment_download_lock);
+ stream->cancelled = TRUE;
+ gst_task_stop (stream->download_task);
+ g_cond_signal (&stream->fragment_download_cond);
+ g_mutex_unlock (&stream->fragment_download_lock);
+ }
+ list_to_process = demux->prepared_streams;
}
GST_MANIFEST_UNLOCK (demux);
@@ -2003,23 +2010,27 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux, gboolean stop_updates)
* object. Even if we temporarily release manifest_lock, the demux->streams
* cannot change and iter cannot be invalidated.
*/
- for (iter = demux->streams; iter; iter = g_list_next (iter)) {
- GstAdaptiveDemuxStream *stream = iter->data;
- GstElement *src = stream->src;
+ list_to_process = demux->streams;
+ for (i = 0; i < 2; ++i) {
+ for (iter = list_to_process; iter; iter = g_list_next (iter)) {
+ GstAdaptiveDemuxStream *stream = iter->data;
+ GstElement *src = stream->src;
- GST_MANIFEST_UNLOCK (demux);
+ GST_MANIFEST_UNLOCK (demux);
- if (src) {
- gst_element_set_locked_state (src, TRUE);
- gst_element_set_state (src, GST_STATE_READY);
- }
+ if (src) {
+ gst_element_set_locked_state (src, TRUE);
+ gst_element_set_state (src, GST_STATE_READY);
+ }
- /* stream->download_task value never changes, so it is safe to read it
- * outside critical section
- */
- gst_task_join (stream->download_task);
+ /* stream->download_task value never changes, so it is safe to read it
+ * outside critical section
+ */
+ gst_task_join (stream->download_task);
- GST_MANIFEST_LOCK (demux);
+ GST_MANIFEST_LOCK (demux);
+ }
+ list_to_process = demux->prepared_streams;
}
GST_MANIFEST_UNLOCK (demux);
@@ -2028,11 +2039,15 @@ gst_adaptive_demux_stop_tasks (GstAdaptiveDemux * demux, gboolean stop_updates)
GST_MANIFEST_LOCK (demux);
- for (iter = demux->streams; iter; iter = g_list_next (iter)) {
- GstAdaptiveDemuxStream *stream = iter->data;
+ list_to_process = demux->streams;
+ for (i = 0; i < 2; ++i) {
+ for (iter = list_to_process; iter; iter = g_list_next (iter)) {
+ GstAdaptiveDemuxStream *stream = iter->data;
- stream->download_error_count = 0;
- stream->need_header = TRUE;
+ stream->download_error_count = 0;
+ stream->need_header = TRUE;
+ }
+ list_to_process = demux->prepared_streams;
}
}