basesink: call state change in all cases

When we asynchronously go from READY to PLAYING, also call the
state change function so that subclasses can update their state for PLAYING.
Because the PREROLL lock is not recursive, we can't make this without
races and we must assume for now that the subclass can handle concurrent calls
to PAUSED->PLAYING and PLAYING->PAUSED. We can make this assumption because not
many elements actually do something in those state changes and the ones that
did would be broken even more without this change.

https://bugzilla.gnome.org/show_bug.cgi?id=702282
This commit is contained in:
Wim Taymans 2013-06-17 10:25:20 +02:00
parent 6ca26e9a00
commit 124b8e38af

View file

@ -1491,7 +1491,29 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
GST_CLOCK_TIME_NONE));
}
if (post_playing) {
if (post_paused) {
GstElementClass *klass;
klass = GST_ELEMENT_GET_CLASS (basesink);
basesink->have_preroll = TRUE;
/* after releasing this lock, the state change function
* can execute concurrently with this thread. There is nothing we do to
* prevent this for now. subclasses should be prepared to handle it. */
GST_BASE_SINK_PREROLL_UNLOCK (basesink);
if (klass->change_state)
klass->change_state (GST_ELEMENT_CAST (basesink),
GST_STATE_CHANGE_PAUSED_TO_PLAYING);
GST_BASE_SINK_PREROLL_LOCK (basesink);
/* state change function could have been executed and we could be
* flushing now */
if (G_UNLIKELY (basesink->flushing))
goto stopping;
}
GST_DEBUG_OBJECT (basesink, "posting PLAYING state change message");
/* FIXME, we released the PREROLL lock above, it's possible that this
* message is not correct anymore when the element went back to PAUSED */
gst_element_post_message (GST_ELEMENT_CAST (basesink),
gst_message_new_state_changed (GST_OBJECT_CAST (basesink),
next, pending, GST_STATE_VOID_PENDING));