[gst-cvs] gstreamer: gstbin: Don't try to change children's state if they' re already in the state we want
Sebastian Dröge
slomo at kemper.freedesktop.org
Tue Aug 18 02:39:10 PDT 2009
Module: gstreamer
Branch: master
Commit: c87d55170512153d3025f32275f198e9b86f1172
URL: http://cgit.freedesktop.org/gstreamer/gstreamer/commit/?id=c87d55170512153d3025f32275f198e9b86f1172
Author: Antoine Tremblay <hexa00 at gmail.com>
Date: Tue Aug 18 11:36:36 2009 +0200
gstbin: Don't try to change children's state if they're already in the state we want
Fixes bug #368536.
---
gst/gstbin.c | 30 +++++++++++++++++++++++++++---
1 files changed, 27 insertions(+), 3 deletions(-)
diff --git a/gst/gstbin.c b/gst/gstbin.c
index 5c80d25..533dca8 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) {
More information about the Gstreamer-commits
mailing list