bin: Child elements can miss state changes happening during async state transitions
Submitted by Sebastian Dröge
gst_element_set_state_func() currently only updates the target state of the element itself, if there is a pending state and it's either smaller/equal than the new state, or the next state is the same as the new state.
These basically mean that currently an async state transition is happening while the new state is set, and we go to the same or a higher state.
Now consider the following scenario:
- bin is in PLAYING and all child elements know that
- app sends flushing seek, state is lost
- bin records that, goes current=next=pending=PAUSED, target still PLAYING and no child elements get notified
- app sets state to PAUSED
- gst_element_set_state() only updates the target state of the bin but not the childs (last state change they saw is PAUSED->PLAYING from before)
- at some point the async state change is finished
- bin is happy because target=current=pending and all good
If you carefully followed this, the child elements saw as very last state change PAUSED->PLAYING. That is, they think they are actually PLAYING it this point.
For most elements this doesn't matter as PLAYING and PAUSED are the same for them. For rtspsrc it has a very big impact though: the pipeline (and sinks!) are PAUSED after all this, but rtspsrc told the server that we're PLAYING after the seek (because that's all it knows) and the server sends us data until all queues are full and memory is exhausted or other bads things happen.