GNOME Bugzilla – Bug 462558
Regression in async state change handling
Last modified: 2007-08-02 11:15:33 UTC
Attempting to play a musepack file in playbin no longer succeeds in pre-rolling with the current 0.10.13.4 pre-release.
The problem seems to be caused by the state-change changes since 0.10.13, specifically the handling of async-start/async-done messages.
Attaching some munged gst debug logs that show the sequence. The problem seems to be that the fakesink which decodebin uses to trigger an async state change sends an async-start message, and is then removed before decodebin actually finishes changing state. When it is removed, it sends an async-done, which is not forwarded by decodebin because it has not yet finished changing state, despite the fact that decodebin did originally send an async-start to the parent when it received the original async-start from its child fakesink.
The end result is that playbin thinks decodebin is still changing state asynchronously when it has in fact already completed.
Created attachment 92876 [details]
debug log 1
gzipped & munged debug log (I stripped some columns) that shows the sequence occurring when playing a musepack file embedded in an APE tag.
Created attachment 92877 [details]
debug log 2
gzipped & munged debug log (I stripped some columns) that shows the sequence occurring when playing an MP3 file embedded in an ID3 tag.
The big difference between the 2 scenarios seems to be that musepackdec is pull-based and sends tags to the src pad much sooner than the mp3 decoder, causing the decodebin-fakesink to be removed much sooner.
It's because decodebin resyncs when iterating over its children (because fakesink was removed in the middle). It then forgets that there was an async element previously that is now gone and therefore does not post an ASYNC_DONE message.
Created attachment 92909 [details] [review]
Don't forget about the fact that some element went ASYNC even after a resync. This makes us post the ASYNC_DONE message correctly.
Rock! Please commit :)
* gst/gstbin.c: (gst_bin_change_state_func),
Don't forget about the fact that some element went ASYNC even after a
resync. This makes us post the ASYNC_DONE message correctly.