From 124b8e38afa5a7e18b01d8f5969b7b20b9854030 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 17 Jun 2013 10:25:20 +0200 Subject: [PATCH] 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 --- libs/gst/base/gstbasesink.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index d517fed2cd..9e97550e54 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -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));