From b645d7ab8c1ee3d582126b36a877eec0ac75706d Mon Sep 17 00:00:00 2001 From: Thomas Vander Stichele Date: Fri, 9 Jul 2004 13:26:12 +0000 Subject: [PATCH] fixes 123774 - setting state on a bin should set state on children as well Original commit message from CVS: fixes 123774 - setting state on a bin should set state on children as well --- ChangeLog | 16 +++++++++++ docs/gst/tmpl/gstelement.sgml | 23 ---------------- docs/gst/tmpl/gsttypes.sgml | 32 +++++++++++----------- gst/gstbin.c | 16 ++++++----- gst/gstelement.c | 42 +++++++++++++++++++---------- tests/old/testsuite/states/parent.c | 3 ++- testsuite/states/parent.c | 3 ++- 7 files changed, 74 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f40744b08..c8fb119397 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2004-07-09 Thomas Vander Stichele + + * docs/gst/tmpl/gstelement.sgml: + * docs/gst/tmpl/gsttypes.sgml: + * gst/gstbin.c: (gst_bin_change_state): + * gst/gstelement.c: (gst_element_set_state), + (gst_element_change_state): + rework so that for bins we try to set the state on all children + as well even if the bin is in the correct state already. + change while to do so at least one iteration is done. + For regular elements, we fall back to the previous behaviour for + now since we first need a new plugins release. + * testsuite/states/parent.c: (main): + test for this case + Fixes #123774 + 2004-07-09 Thomas Vander Stichele * gst/gstqueue.c: (gst_queue_class_init), (gst_queue_finalize), diff --git a/docs/gst/tmpl/gstelement.sgml b/docs/gst/tmpl/gstelement.sgml index 6263b4e824..2a07afc6df 100644 --- a/docs/gst/tmpl/gstelement.sgml +++ b/docs/gst/tmpl/gstelement.sgml @@ -76,8 +76,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: - @gstelement: the object which received the signal. @@ -85,11 +83,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: -@: -@: -@: - @gstelement: the object which received the signal. @arg1: @arg2: @@ -100,10 +93,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: -@: -@: - @gstelement: the object which received the signal. @arg1: @arg2: @@ -113,9 +102,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: -@: - @gstelement: the object which received the signal. @arg1: @@ -124,8 +110,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: - @gstelement: the object which received the signal. @@ -133,9 +117,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: -@: - @gstelement: the object which received the signal. @arg1: @@ -144,10 +125,6 @@ and gst_element_set_clock(). You can wait for the clock to reach a given -@: -@: -@: - @gstelement: the object which received the signal. @arg1: @arg2: diff --git a/docs/gst/tmpl/gsttypes.sgml b/docs/gst/tmpl/gsttypes.sgml index dcf6af2d83..b78624314b 100644 --- a/docs/gst/tmpl/gsttypes.sgml +++ b/docs/gst/tmpl/gsttypes.sgml @@ -127,58 +127,58 @@ template. -@gstelement: the object which received the signal. +@: -@gstelement: the object which received the signal. -@arg1: -@arg2: -@arg3: +@: +@: +@: +@: -@gstelement: the object which received the signal. -@arg1: -@arg2: +@: +@: +@: -@gstelement: the object which received the signal. -@arg1: +@: +@: -@gstelement: the object which received the signal. +@: -@gstelement: the object which received the signal. -@arg1: +@: +@: -@gstelement: the object which received the signal. -@arg1: -@arg2: +@: +@: +@: diff --git a/gst/gstbin.c b/gst/gstbin.c index 911fe73071..3ae14d48c8 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -726,12 +726,16 @@ gst_bin_change_state (GstElement * element) if (pending == GST_STATE_VOID_PENDING) return GST_STATE_SUCCESS; - if (old_state == pending) { - GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, - "old and pending state are both %s, returning", - gst_element_state_get_name (pending)); - return GST_STATE_SUCCESS; - } + /* we want to recurse into children anyway, regardless of our old + * state */ + /* + if (old_state == pending) { + GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, + "old and pending state are both %s, returning", + gst_element_state_get_name (pending)); + return GST_STATE_SUCCESS; + } + */ children = bin->children; diff --git a/gst/gstelement.c b/gst/gstelement.c index d2024848ac..6dd45cb4fc 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -2725,13 +2725,22 @@ gst_element_set_state (GstElement * element, GstElementState state) GstElementStateReturn return_val = GST_STATE_SUCCESS; g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); + oclass = GST_ELEMENT_GET_CLASS (element); + + /* for bins, we allow calls to change_state where old == new + * for elements, too many of them break with g_assert_not_reached(), + * so weed those out first. This is done in gst-plugins CVS and can + * be fixed here after a new plugins reelase. + * FIXME: of course this file should not have ties to gstbin.h *at all*, + * but someone else added a function at the bottom using it. + * Fix this properly for 0.9 */ /* start with the current state */ curpending = GST_STATE (element); - if (state == curpending) { + if (!GST_IS_BIN (element) && state == curpending) { GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, - "element is already in requested state %s", + "non-bin element is already in requested state %s, returning", gst_element_state_get_name (state)); return (GST_STATE_SUCCESS); } @@ -2740,17 +2749,11 @@ gst_element_set_state (GstElement * element, GstElementState state) gst_element_state_get_name (curpending), gst_element_state_get_name (state)); - /* loop until the final requested state is set */ - while (GST_STATE (element) != state - && GST_STATE (element) != GST_STATE_VOID_PENDING) { - /* move the curpending state in the correct direction */ - if (curpending < state) - curpending <<= 1; - else - curpending >>= 1; + /* loop until the final requested state is set; + * loop at least once, starting with the current state */ + do { /* set the pending state variable */ - /* FIXME: should probably check to see that we don't already have one */ GST_STATE_PENDING (element) = curpending; if (curpending != state) { @@ -2758,10 +2761,13 @@ gst_element_set_state (GstElement * element, GstElementState state) "intermediate: setting state from %s to %s", gst_element_state_get_name (GST_STATE (element)), gst_element_state_get_name (curpending)); + } else { + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, + "start: setting current state %s again", + gst_element_state_get_name (GST_STATE (element))); } /* call the state change function so it can set the state */ - oclass = GST_ELEMENT_GET_CLASS (element); if (oclass->change_state) return_val = (oclass->change_state) (element); @@ -2780,7 +2786,8 @@ gst_element_set_state (GstElement * element, GstElementState state) /* if it did not, this is an error - fix the element that does this */ if (GST_STATE (element) != curpending) { g_warning ("element %s claimed state-change success," - "but state didn't change to %s. State is %s (%s pending), fix the element", + "but state didn't change to %s. State is %s (%s pending), " + "fix the element", GST_ELEMENT_NAME (element), gst_element_state_get_name (curpending), gst_element_state_get_name (GST_STATE (element)), @@ -2793,7 +2800,14 @@ gst_element_set_state (GstElement * element, GstElementState state) /* somebody added a GST_STATE_ and forgot to do stuff here ! */ g_assert_not_reached (); } - } + /* move the curpending state in the correct direction */ + if (curpending < state) + curpending <<= 1; + else + curpending >>= 1; + } while (GST_STATE (element) != state + && GST_STATE (element) != GST_STATE_VOID_PENDING); + exit: return return_val; diff --git a/tests/old/testsuite/states/parent.c b/tests/old/testsuite/states/parent.c index 6e54217673..7994339671 100644 --- a/tests/old/testsuite/states/parent.c +++ b/tests/old/testsuite/states/parent.c @@ -100,8 +100,9 @@ main (gint argc, gchar * argv[]) g_assert (GST_STATE (bin2) == GST_STATE_PAUSED); g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED); //FIXME: fix core so that this assert works - //g_assert (GST_STATE (identity) == GST_STATE_PAUSED); + g_assert (GST_STATE (identity) == GST_STATE_PAUSED); g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED); + g_print ("passed.\n"); return 0; } diff --git a/testsuite/states/parent.c b/testsuite/states/parent.c index 6e54217673..7994339671 100644 --- a/testsuite/states/parent.c +++ b/testsuite/states/parent.c @@ -100,8 +100,9 @@ main (gint argc, gchar * argv[]) g_assert (GST_STATE (bin2) == GST_STATE_PAUSED); g_assert (GST_STATE (fakesrc) == GST_STATE_PAUSED); //FIXME: fix core so that this assert works - //g_assert (GST_STATE (identity) == GST_STATE_PAUSED); + g_assert (GST_STATE (identity) == GST_STATE_PAUSED); g_assert (GST_STATE (fakesink) == GST_STATE_PAUSED); + g_print ("passed.\n"); return 0; }