GNOME Bugzilla – Bug 656751
deadlock in decodebin2
Last modified: 2011-08-19 08:43:15 UTC
I'm working on HLS streaming and when I do a seek in an HLS stream, I can trigger a deadlock in decodebin2. It's not easy to reproduce with GST_DEBUG enabled, but I can reproduce it with enough tries (race condition). Basically what happens is that tsdemux will switch streams by adding pads and sending an EOS on the previous pads, this results in the deadlock where the eos handlers (for audio and video) will get triggered.. one of them takes the chain/group/expose lock and tries to remove the group/chain but blocks because it tries to get the stream pad lock which has already been taken by the gst_pad_send_event that is sending the EOS on the other thread, which itself is blocked waiting for the chain lock taken by the first thread... Have a look at the backtrace for the two threads involved :
+ Trace 228117
Thread 8 (Thread 0x9e7feb70 (LWP 31178))
Thread 7 (Thread 0x9dffdb70 (LWP 31179))
Found the issue. The deadlock situation was caused by decodebin2 draining the decode group before it was completely drained. This is why it locked trying to remove the pad which itself was sending an EOS. This is caused by this commit : http://cgit.freedesktop.org/~bilboed/gst-plugins-base/commit/?id=f65fede141f85924071dacccac92e0ee8a628a1e which, apparently, is not in the master git repository yet, so I'm marking this bug as invalid. I'll contact bilboed with the fix to this bug, which is actually quite simple : diff --git a/gst/playback/gstdecodebin2.c b/gst/playback/gstdecodebin2.c index 180c170..6d0c7e6 100644 --- a/gst/playback/gstdecodebin2.c +++ b/gst/playback/gstdecodebin2.c @@ -2944,7 +2944,7 @@ drain_and_switch_group (GstDecodeGroup * group, GstDecodePad * drainpad, * new information */ for (tmp = group->children; tmp; tmp = tmp->next) { GstDecodeChain *chain = (GstDecodeChain *) tmp->data; - gboolean subdrained; + gboolean subdrained = FALSE; handled |= drain_and_switch_chains (chain, drainpad, last_group, &subdrained,
drain_and_switch_chains() should always set the three out-parameters I guess. Currently there are some paths that don't set some