GNOME Bugzilla – Bug 759604
gst_element_lost_state() interfers with base-time resetting of later gst_element_set_state()
Last modified: 2018-11-03 12:31:23 UTC
Created attachment 317583 [details] testcase Consider the following situation in a pipeline with async=true sinks: 1) gst_element_lost_state() due to flushing for whatever reason 2) gst_element_set_state(PAUSED) on the pipeline due to BUFFERING<100% before 1) finished to put the pipeline to PLAYING again 3) gst_element_set_state(PLAYING) on the pipeline much later because BUFFERING=100% What will happen here is that 1) does a "state change" without going through the GstElement::change_state() machinery and as such no start_time will be set. It will update current/next/pending state to PAUSED and target state stays at PLAYING. 2) will then immediately return and only update the target state to PAUSED but nothing will go through GstElement::change_state() anywhere. Later 3) will change the state to PLAYING again but base_time is not updated as in 1) and 2) the start_time was not set. The effect of this is that the running time continued all the time the pipeline was buffering, and as such now everything that was buffered is most likely too late and will be dropped. Note that similar code to gst_element_lost_state() is also in GstBin's handle_async_start(), which will cause the same problems if a child element is posting async-start messages. So this situation could also happen in pipelines where sinks are dynamically added. gst_element_lost_state() (and the async-start handling in GstBin) intentionally does not update start_time as a) the clock might not work anymore at this point and b) the running time should continue if it can as losing state should just be something that happens very shortly and should not interrupt playback (e.g. of other pipeline branches inside the pipeline!). Attached is a test application that reproduces this behaviour. Take a look at where the LOST_STATE #define is used to get an idea of the different variants that can happen, and which work and which don't. I'm not sure how to fix this without breaking other things. IMHO for 2.0 we should clean up all this state change machinery a lot and make sure we have a sensible state machine again that does not come with weird non-states like the ones that currently happen when state is lost.
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gstreamer/issues/145.