From 0eb30d478d079c381d73ed0b3c063526c7a3427b Mon Sep 17 00:00:00 2001
|
From: Jeffy Chen <jeffy.chen@rock-chips.com>
|
Date: Fri, 26 Nov 2021 17:41:47 +0800
|
Subject: [PATCH 8/9] playbin2: Fix deadlock when hooking about-to-finish
|
signal
|
|
The playbin2 will deactivate old group in drain_cb() for that, which
|
would cause deadlock when other thread tries to notify pad-change at
|
the same time.
|
|
Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
|
---
|
gst/playback/gstplaybin2.c | 20 ++++++++++++++++++++
|
1 file changed, 20 insertions(+)
|
|
diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
|
index f1ddef0..f07fd75 100644
|
--- a/gst/playback/gstplaybin2.c
|
+++ b/gst/playback/gstplaybin2.c
|
@@ -385,6 +385,11 @@ G_STMT_START { \
|
#define GST_PLAY_BIN_SHUTDOWN_UNLOCK(bin) \
|
GST_PLAY_BIN_DYN_UNLOCK (bin); \
|
|
+/* lock to protect drain callbacks */
|
+#define GST_PLAY_BIN_DRAIN_LOCK(bin) g_mutex_lock (&(bin)->drain_lock)
|
+#define GST_PLAY_BIN_DRAIN_TRYLOCK(bin) g_mutex_trylock (&(bin)->drain_lock)
|
+#define GST_PLAY_BIN_DRAIN_UNLOCK(bin) g_mutex_unlock (&(bin)->drain_lock)
|
+
|
/**
|
* GstPlayBin:
|
*
|
@@ -427,6 +432,9 @@ struct _GstPlayBin
|
gint shutdown;
|
gboolean async_pending; /* async-start has been emitted */
|
|
+ /* lock protecting draining */
|
+ GMutex drain_lock;
|
+
|
GMutex elements_lock;
|
guint32 elements_cookie;
|
GList *elements; /* factories we can use for selecting elements */
|
@@ -1552,6 +1560,7 @@ gst_play_bin_init (GstPlayBin * playbin)
|
{
|
g_rec_mutex_init (&playbin->lock);
|
g_mutex_init (&playbin->dyn_lock);
|
+ g_mutex_init (&playbin->drain_lock);
|
|
/* assume we can create an input-selector */
|
playbin->have_selector = TRUE;
|
@@ -1651,6 +1660,7 @@ gst_play_bin_finalize (GObject * object)
|
g_list_free_full (playbin->contexts, (GDestroyNotify) gst_context_unref);
|
|
g_rec_mutex_clear (&playbin->lock);
|
+ g_mutex_clear (&playbin->drain_lock);
|
g_mutex_clear (&playbin->dyn_lock);
|
g_mutex_clear (&playbin->elements_lock);
|
|
@@ -3150,7 +3160,14 @@ combiner_active_pad_changed (GObject * combiner, GParamSpec * pspec,
|
GstSourceCombine *combine = NULL;
|
int i;
|
|
+ /* We got a pad-change after draining; no need to notify */
|
+ if (!GST_PLAY_BIN_DRAIN_TRYLOCK (playbin))
|
+ return;
|
+
|
GST_PLAY_BIN_LOCK (playbin);
|
+
|
+ GST_PLAY_BIN_DRAIN_UNLOCK (playbin);
|
+
|
group = get_group (playbin);
|
|
for (i = 0; i < PLAYBIN_STREAM_LAST; i++) {
|
@@ -3960,7 +3977,10 @@ drained_cb (GstElement * decodebin, GstSourceGroup * group)
|
|
/* now activate the next group. If the app did not set a uri, this will
|
* fail and we can do EOS */
|
+
|
+ GST_PLAY_BIN_DRAIN_LOCK (playbin);
|
setup_next_source (playbin, GST_STATE_PAUSED);
|
+ GST_PLAY_BIN_DRAIN_UNLOCK (playbin);
|
}
|
|
/* Like gst_element_factory_can_sink_any_caps() but doesn't
|
--
|
2.20.1
|