There was a deadlock between a thread changing decodebin/demuxer
state from PAUSED to READY, and another thread pushing data
when starting.
From the stack trace at
https://bug741355.bugzilla-attachments.gnome.org/attachment.cgi?id=292471,
I deduce the following is happening, though I did not reproduce the
problem so I'm not sure this patch fixes it.
The streaming thread (thread 2 in that stack trace) takes the demuxer's
sink pad's stream lock in gst_ogg_demux_perform_seek_pull and will
activate a new chain. This ends up causing the expose lock being taken
in _pad_added_cb in decodebin.
Meanwhile, a state changed is triggered on thread 1, which takes the
expose lock in decodebin in gst_decode_bin_change_state, then frees
the previous chain, which ends up calling gst_pad_stop_task on the
demuxer's task, which in turn takes the demuxer's sink pad's stream
lock, deadlocking as both threads are now waiting for each other.
https://bugzilla.gnome.org/show_bug.cgi?id=741355
{
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
GstDecodeBin *dbin = GST_DECODE_BIN (element);
+ GstDecodeChain *chain_to_free = NULL;
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
do_async_done (dbin);
EXPOSE_LOCK (dbin);
if (dbin->decode_chain) {
- gst_decode_chain_free (dbin->decode_chain);
+ chain_to_free = dbin->decode_chain;
+ gst_decode_chain_free_internal (dbin->decode_chain, TRUE);
dbin->decode_chain = NULL;
}
EXPOSE_UNLOCK (dbin);
+ if (chain_to_free)
+ gst_decode_chain_free (chain_to_free);
g_list_free_full (dbin->buffering_status,
(GDestroyNotify) gst_message_unref);
dbin->buffering_status = NULL;