diff options
author | Antoine Tremblay <hexa00@gmail.com> | 2009-08-18 11:36:36 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian.droege@collabora.co.uk> | 2009-08-18 11:36:36 +0200 |
commit | c87d55170512153d3025f32275f198e9b86f1172 (patch) | |
tree | bdf140576fc0ae8a8a0bd04624dcd41da53db447 | |
parent | a0ed1a44a54604a4efae7f926d70e00021db09b6 (diff) |
gstbin: Don't try to change children's state if they're already in the state we want
Fixes bug #368536.
-rw-r--r-- | gst/gstbin.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/gst/gstbin.c b/gst/gstbin.c index 5c80d25d9c..533dca8ef7 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -1979,6 +1979,7 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element, GstState next) { GstStateChangeReturn ret; + GstState pending, child_current, child_pending; gboolean locked; GList *found; @@ -1990,8 +1991,10 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element, element->base_time = base_time; /* peel off the locked flag */ locked = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE); - /* get previous state return */ + /* Get the previous set_state result to preserve NO_PREROLL and ASYNC */ ret = GST_STATE_RETURN (element); + child_current = GST_STATE (element); + child_pending = GST_STATE_PENDING (element); GST_OBJECT_UNLOCK (element); /* skip locked elements */ @@ -2007,6 +2010,16 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element, } GST_OBJECT_LOCK (bin); + pending = GST_STATE_PENDING (bin); + + /* Try not to change the state of elements that are already in the state we're + * going to */ + if (!(child_pending != GST_STATE_VOID_PENDING || + (child_pending == GST_STATE_VOID_PENDING && + ((pending > child_current && next > child_current) || + (pending < child_current && next < child_current))))) + goto unneeded; + /* the element was busy with an upwards async state change, we must wait for * an ASYNC_DONE message before we attemp to change the state. */ if ((found = @@ -2064,6 +2077,18 @@ was_busy: GST_STATE_UNLOCK (element); return GST_STATE_CHANGE_ASYNC; } +unneeded: + { + GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, + "skipping transition from %s to %s, since bin pending" + " is %s : last change state return follows", + gst_element_state_get_name (child_current), + gst_element_state_get_name (next), + gst_element_state_get_name (pending)); + GST_OBJECT_UNLOCK (bin); + GST_STATE_UNLOCK (element); + return ret; + } } /* gst_iterator_fold functions for pads_activate @@ -2330,8 +2355,7 @@ restart: child = GST_ELEMENT_CAST (data); /* set state and base_time now */ - ret = - gst_bin_element_set_state (bin, child, base_time, start_time, + ret = gst_bin_element_set_state (bin, child, base_time, start_time, current, next); switch (ret) { |