[Bug 759604] New: gst_element_lost_state() interfers with base-time resetting of later gst_element_set_state()

GStreamer (GNOME Bugzilla) bugzilla at gnome.org
Thu Dec 17 08:45:38 PST 2015


https://bugzilla.gnome.org/show_bug.cgi?id=759604

            Bug ID: 759604
           Summary: gst_element_lost_state() interfers with base-time
                    resetting of later gst_element_set_state()
    Classification: Platform
           Product: GStreamer
           Version: git master
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: Normal
         Component: gstreamer (core)
          Assignee: gstreamer-bugs at lists.freedesktop.org
          Reporter: slomo at coaxion.net
        QA Contact: gstreamer-bugs at lists.freedesktop.org
     GNOME version: ---

Created attachment 317583
  --> https://bugzilla.gnome.org/attachment.cgi?id=317583&action=edit
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.

-- 
You are receiving this mail because:
You are the QA Contact for the bug.
You are the assignee for the bug.


More information about the gstreamer-bugs mailing list