fixes 123774 - setting state on a bin should set state on children as well
authorThomas Vander Stichele <thomas@apestaart.org>
Fri, 9 Jul 2004 13:26:12 +0000 (13:26 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Fri, 9 Jul 2004 13:26:12 +0000 (13:26 +0000)
Original commit message from CVS:
fixes 123774 - setting state on a bin should set state on children as well

ChangeLog
docs/gst/tmpl/gstelement.sgml
docs/gst/tmpl/gsttypes.sgml
gst/gstbin.c
gst/gstelement.c
tests/old/testsuite/states/parent.c
testsuite/states/parent.c

index 1f40744..c8fb119 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
 2004-07-09  Thomas Vander Stichele  <thomas (at) apestaart (dot) org>
 
+       * 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  <thomas (at) apestaart (dot) org>
+
        * gst/gstqueue.c: (gst_queue_class_init), (gst_queue_finalize),
        (gst_queue_chain), (gst_queue_get), (gst_queue_handle_src_event),
        (gst_queue_release_locks), (gst_queue_change_state),
index 6263b4e..2a07afc 100644 (file)
@@ -76,8 +76,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@:
-
 @gstelement: the object which received the signal.
 
 <!-- ##### SIGNAL GstElement::error ##### -->
@@ -85,11 +83,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@: 
-@: 
-@:
-
 @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
 
 </para>
 
-@: 
-@: 
-@:
-
 @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
 
 </para>
 
-@: 
-@:
-
 @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
 
 </para>
 
-@:
-
 @gstelement: the object which received the signal.
 
 <!-- ##### SIGNAL GstElement::pad-removed ##### -->
@@ -133,9 +117,6 @@ and gst_element_set_clock().  You can wait for the clock to reach a given
 
 </para>
 
-@: 
-@:
-
 @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
 
 </para>
 
-@: 
-@: 
-@:
-
 @gstelement: the object which received the signal.
 @arg1: 
 @arg2: 
index dcf6af2..b786243 100644 (file)
@@ -127,58 +127,58 @@ template.
 
 </para>
 
-@gstelement: the object which received the signal.
+@
 
 <!-- ##### SIGNAL GstElement::error ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
-@arg2
-@arg3
+@
+@: 
+@: 
+@: 
 
 <!-- ##### SIGNAL GstElement::found-tag ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
-@arg2
+@
+@: 
+@: 
 
 <!-- ##### SIGNAL GstElement::new-pad ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
+@
+@: 
 
 <!-- ##### SIGNAL GstElement::no-more-pads ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
+@
 
 <!-- ##### SIGNAL GstElement::pad-removed ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
+@
+@: 
 
 <!-- ##### SIGNAL GstElement::state-change ##### -->
 <para>
 
 </para>
 
-@gstelement: the object which received the signal.
-@arg1
-@arg2
+@
+@: 
+@: 
 
 <!-- ##### STRUCT GstElementClass ##### -->
 <para>
index 911fe73..3ae14d4 100644 (file)
@@ -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;
 
index d202484..6dd45cb 100644 (file)
@@ -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;
index 6e54217..7994339 100644 (file)
@@ -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;
 }
index 6e54217..7994339 100644 (file)
@@ -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;
 }