mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 10:11:08 +00:00
decodebin2: Protect subtitle elements and subtitle encoding by a new mutex
Using the object lock here can and will lead to deadlocks because of deep-notifies of property changes: the deep-notify handler will get the parent of objects, which will take the object lock again. Fixes bug #600479.
This commit is contained in:
parent
f365385458
commit
5798b543df
1 changed files with 36 additions and 9 deletions
|
@ -150,8 +150,9 @@ struct _GstDecodeBin
|
|||
|
||||
GValueArray *factories; /* factories we can use for selecting elements */
|
||||
|
||||
GMutex *subtitle_lock; /* Protects changes to subtitles and encoding */
|
||||
GList *subtitles; /* List of elements with subtitle-encoding,
|
||||
* protected by object lock! */
|
||||
* protected by above mutex! */
|
||||
|
||||
gboolean have_type; /* if we received the have_type signal */
|
||||
guint have_type_id; /* signal id for have-type from typefind */
|
||||
|
@ -316,6 +317,23 @@ static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
|
|||
g_mutex_unlock (GST_DECODE_BIN_CAST(dbin)->dyn_lock); \
|
||||
} G_STMT_END
|
||||
|
||||
#define SUBTITLE_LOCK(dbin) G_STMT_START { \
|
||||
GST_LOG_OBJECT (dbin, \
|
||||
"subtitle locking from thread %p", \
|
||||
g_thread_self ()); \
|
||||
g_mutex_lock (GST_DECODE_BIN_CAST(dbin)->subtitle_lock); \
|
||||
GST_LOG_OBJECT (dbin, \
|
||||
"subtitle lock from thread %p", \
|
||||
g_thread_self ()); \
|
||||
} G_STMT_END
|
||||
|
||||
#define SUBTITLE_UNLOCK(dbin) G_STMT_START { \
|
||||
GST_LOG_OBJECT (dbin, \
|
||||
"subtitle unlocking from thread %p", \
|
||||
g_thread_self ()); \
|
||||
g_mutex_unlock (GST_DECODE_BIN_CAST(dbin)->subtitle_lock); \
|
||||
} G_STMT_END
|
||||
|
||||
/* GstDecodeGroup
|
||||
*
|
||||
* Streams belonging to the same group/chain of a media file
|
||||
|
@ -849,6 +867,8 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
|
|||
decode_bin->shutdown = FALSE;
|
||||
decode_bin->blocked_pads = NULL;
|
||||
|
||||
decode_bin->subtitle_lock = g_mutex_new ();
|
||||
|
||||
decode_bin->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);
|
||||
decode_bin->caps = gst_static_caps_get (&default_raw_caps);
|
||||
decode_bin->use_buffering = DEFAULT_USE_BUFFERING;
|
||||
|
@ -905,6 +925,11 @@ gst_decode_bin_finalize (GObject * object)
|
|||
decode_bin->dyn_lock = NULL;
|
||||
}
|
||||
|
||||
if (decode_bin->subtitle_lock) {
|
||||
g_mutex_free (decode_bin->subtitle_lock);
|
||||
decode_bin->subtitle_lock = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
|
@ -975,7 +1000,7 @@ gst_decode_bin_set_subs_encoding (GstDecodeBin * dbin, const gchar * encoding)
|
|||
|
||||
GST_DEBUG_OBJECT (dbin, "Setting new encoding: %s", GST_STR_NULL (encoding));
|
||||
|
||||
GST_OBJECT_LOCK (dbin);
|
||||
SUBTITLE_LOCK (dbin);
|
||||
g_free (dbin->encoding);
|
||||
dbin->encoding = g_strdup (encoding);
|
||||
|
||||
|
@ -984,7 +1009,7 @@ gst_decode_bin_set_subs_encoding (GstDecodeBin * dbin, const gchar * encoding)
|
|||
g_object_set (G_OBJECT (walk->data), "subtitle-encoding", dbin->encoding,
|
||||
NULL);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (dbin);
|
||||
SUBTITLE_UNLOCK (dbin);
|
||||
}
|
||||
|
||||
static gchar *
|
||||
|
@ -994,9 +1019,9 @@ gst_decode_bin_get_subs_encoding (GstDecodeBin * dbin)
|
|||
|
||||
GST_DEBUG_OBJECT (dbin, "Getting currently set encoding");
|
||||
|
||||
GST_OBJECT_LOCK (dbin);
|
||||
SUBTITLE_LOCK (dbin);
|
||||
encoding = g_strdup (dbin->encoding);
|
||||
GST_OBJECT_UNLOCK (dbin);
|
||||
SUBTITLE_UNLOCK (dbin);
|
||||
|
||||
return encoding;
|
||||
}
|
||||
|
@ -1488,10 +1513,12 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
|||
/* try to configure the subtitle encoding property when we can */
|
||||
if (g_object_class_find_property (G_OBJECT_GET_CLASS (element),
|
||||
"subtitle-encoding")) {
|
||||
SUBTITLE_LOCK (dbin);
|
||||
GST_DEBUG_OBJECT (dbin,
|
||||
"setting subtitle-encoding=%s to element", dbin->encoding);
|
||||
g_object_set (G_OBJECT (element), "subtitle-encoding", dbin->encoding,
|
||||
NULL);
|
||||
SUBTITLE_UNLOCK (dbin);
|
||||
subtitle = TRUE;
|
||||
} else
|
||||
subtitle = FALSE;
|
||||
|
@ -1518,11 +1545,11 @@ connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
|
|||
continue;
|
||||
}
|
||||
if (subtitle) {
|
||||
GST_OBJECT_LOCK (dbin);
|
||||
SUBTITLE_LOCK (dbin);
|
||||
/* we added the element now, add it to the list of subtitle-encoding
|
||||
* elements when we can set the property */
|
||||
dbin->subtitles = g_list_prepend (dbin->subtitles, element);
|
||||
GST_OBJECT_UNLOCK (dbin);
|
||||
SUBTITLE_UNLOCK (dbin);
|
||||
}
|
||||
|
||||
res = TRUE;
|
||||
|
@ -2022,10 +2049,10 @@ gst_decode_chain_free_internal (GstDecodeChain * chain, gboolean hide)
|
|||
gst_element_set_state (element, GST_STATE_NULL);
|
||||
}
|
||||
|
||||
GST_OBJECT_LOCK (chain->dbin);
|
||||
SUBTITLE_LOCK (chain->dbin);
|
||||
/* remove possible subtitle element */
|
||||
chain->dbin->subtitles = g_list_remove (chain->dbin->subtitles, element);
|
||||
GST_OBJECT_UNLOCK (chain->dbin);
|
||||
SUBTITLE_UNLOCK (chain->dbin);
|
||||
|
||||
if (!hide) {
|
||||
gst_object_unref (element);
|
||||
|
|
Loading…
Reference in a new issue