GNOME Bugzilla – Bug 485753
Decodebin2 deadlocks when nulling pipeline during typefind
Last modified: 2007-10-16 16:48:34 UTC
Steps to reproduce the problem: 1. Set playbin with some uri to PLAYING 2. when typefind element is performing typefind, set playbin to NULL This is what I think happens next: * Decodebin2 takes its state_lock and starts setting its children from PAUSED to READY * Typefind element won't switch to READY until it finishes its typefinding and has emitted have_type signal * type_found callback in decodebin2 tries to take state_lock too and pipeline deadlocks. I can reproduce the problem with attached test player: $ GST_DEBUG=GST_STATES:5,typefind:5,decodebin2:5 ./dbin2-deadlock http://replaygain.hydrogenaudio.org/ref_pink.wav 2> gst.log Starting pipeline Got state-changed message from play Got clock-provide message from play Got state-changed message from test Got state-changed message from async-fakesink Got state-changed message from typefind typefind changed state to 2 Got state-changed message from decodebin20 Got state-changed message from typefind typefind changed state to 3 Got state-changed message from source Got state-changed message from source Got buffer 1 with size 1171 Got buffer 2 with size 1448 Nulling pipeline One way to fix this would be to connect/disconnect type_found callback in READY_TO_PAUSED/PAUSED_TO_READY state changes in decodebin2.
Created attachment 97064 [details] dbin2-deadlock.c test player
Created attachment 97065 [details] decodebin2:5,GST_STATES:5,typefind:5 gst.log
decodebin used to check for shutdown right after taking locks, this was removed.
actually, it also fails with decodebin.
* gst/playback/gstdecodebin.c: (new_pad), (type_found): Make the window for a race in typefind and shutting down smaller until we figure out the right locking here. Avoids #485753 usually. * gst/playback/gstdecodebin2.c: (type_found), (pad_added_group_cb): Remove unneeded lock causing a race in typefind and shutting down. Fixes #485753. * gst/playback/gstplaybin.c: (gst_play_bin_change_state): Also remove sinks when going to NULL because we might not complete the state change to PAUSED, causing the PAUSED->READY state change not to happen.