From c05541c19505cf52f4e76fcc27f2b85328e5660b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 7 May 2009 14:28:30 +0200 Subject: [PATCH] playbin2: make playsink go ASYNC to PAUSED Make playsink go async to the PAUSED state instead of relying on uridecodebin for async behaviour in playbin. This solves some problems (mainly with DVD) where the pipeline would go to PLAYING before preroll completed, failing to select the audiosink clock. Fixes #581727 --- gst/playback/gstplaysink.c | 52 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index b7f8c85..51faf78 100644 --- a/gst/playback/gstplaysink.c +++ b/gst/playback/gstplaysink.c @@ -122,6 +122,8 @@ struct _GstPlaySink GMutex *lock; + gboolean async_pending; + GstPlayFlags flags; /* chains */ @@ -794,6 +796,32 @@ gst_play_sink_find_property_sinks (GstPlaySink * playsink, GstElement * obj, return result; } +static void +do_async_start (GstPlaySink * playsink) +{ + GstMessage *message; + + playsink->async_pending = TRUE; + + message = gst_message_new_async_start (GST_OBJECT_CAST (playsink), FALSE); + GST_BIN_CLASS (gst_play_sink_parent_class)->handle_message (GST_BIN_CAST + (playsink), message); +} + +static void +do_async_done (GstPlaySink * playsink) +{ + GstMessage *message; + + if (playsink->async_pending) { + message = gst_message_new_async_done (GST_OBJECT_CAST (playsink)); + GST_BIN_CLASS (gst_play_sink_parent_class)->handle_message (GST_BIN_CAST + (playsink), message); + + playsink->async_pending = FALSE; + } +} + /* try to change the state of an element. This function returns the element when * the state change could be performed. When this function returns NULL an error * occured and the element is unreffed if @unref is TRUE. */ @@ -1974,6 +2002,7 @@ gst_play_sink_reconfigure (GstPlaySink * playsink) activate_chain (GST_PLAY_CHAIN (playsink->vischain), FALSE); } } + do_async_done (playsink); GST_PLAY_SINK_UNLOCK (playsink); return TRUE; @@ -2318,22 +2347,30 @@ static GstStateChangeReturn gst_play_sink_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn ret; + GstStateChangeReturn bret; + GstPlaySink *playsink; playsink = GST_PLAY_SINK (element); switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: + do_async_start (playsink); + ret = GST_STATE_CHANGE_ASYNC; break; default: break; } - ret = + bret = GST_ELEMENT_CLASS (gst_play_sink_parent_class)->change_state (element, transition); - if (ret == GST_STATE_CHANGE_FAILURE) - return ret; + if (G_UNLIKELY (bret == GST_STATE_CHANGE_FAILURE)) + goto activate_failed; + else if (G_UNLIKELY (bret == GST_STATE_CHANGE_NO_PREROLL)) { + do_async_done (playsink); + ret = bret; + } switch (transition) { case GST_STATE_CHANGE_READY_TO_PAUSED: @@ -2359,10 +2396,19 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition) activate_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE); add_chain (GST_PLAY_CHAIN (playsink->textchain), FALSE); } + do_async_done (playsink); break; default: break; } return ret; + + /* ERRORS */ +activate_failed: + { + GST_DEBUG_OBJECT (element, + "element failed to change states -- activation problem?"); + return GST_STATE_CHANGE_FAILURE; + } } -- 2.7.4