mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 18:05:37 +00:00
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
This commit is contained in:
parent
8677c0bdf3
commit
c05541c195
1 changed files with 49 additions and 3 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue