--- gstreamer-0.10.20.orig/gst/gstbin.c	2008-09-23 14:36:49.000000000 -0400
+++ gstreamer-0.10.20/gst/gstbin.c	2008-09-24 17:50:10.000000000 -0400
@@ -2085,7 +2085,7 @@
 {
   GstBin *bin;
   GstStateChangeReturn ret;
-  GstState current, next;
+  GstState current, next, pending;
   gboolean have_async;
   gboolean have_no_preroll;
   GstClockTime base_time;
@@ -2093,6 +2093,7 @@
   gboolean done;
 
   /* we don't need to take the STATE_LOCK, it is already taken */
+  pending = (GstState) GST_STATE_PENDING (element);
   current = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
   next = (GstState) GST_STATE_TRANSITION_NEXT (transition);
 
@@ -2175,42 +2176,58 @@
         GstElement *child;
 
         child = GST_ELEMENT_CAST (data);
+        GstState child_current, child_pending;
 
-        /* set state and base_time now */
-        ret = gst_bin_element_set_state (bin, child, base_time, current, next);
+        child_current = GST_STATE(child);
+        child_pending = GST_STATE_PENDING(child);
 
-        switch (ret) {
-          case GST_STATE_CHANGE_SUCCESS:
-            GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
-                "child '%s' changed state to %d(%s) successfully",
-                GST_ELEMENT_NAME (child), next,
-                gst_element_state_get_name (next));
-            break;
-          case GST_STATE_CHANGE_ASYNC:
-          {
-            GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
-                "child '%s' is changing state asynchronously to %s",
-                GST_ELEMENT_NAME (child), gst_element_state_get_name (next));
-            have_async = TRUE;
-            break;
+        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 ))))
+        {
+          /* set state and base_time now */
+          ret = gst_bin_element_set_state (bin, child, base_time, current, next);
+
+          switch (ret) {
+            case GST_STATE_CHANGE_SUCCESS:
+              GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+                  "child '%s' changed state to %d(%s) successfully",
+                  GST_ELEMENT_NAME (child), next,
+                  gst_element_state_get_name (next));
+              break;
+            case GST_STATE_CHANGE_ASYNC:
+            {
+              GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+                  "child '%s' is changing state asynchronously to %s",
+                  GST_ELEMENT_NAME (child), gst_element_state_get_name (next));
+              have_async = TRUE;
+              break;
+            }
+            case GST_STATE_CHANGE_FAILURE:
+              GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+                  "child '%s' failed to go to state %d(%s)",
+                  GST_ELEMENT_NAME (child),
+                  next, gst_element_state_get_name (next));
+              gst_object_unref (child);
+              goto done;
+            case GST_STATE_CHANGE_NO_PREROLL:
+              GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+                  "child '%s' changed state to %d(%s) successfully without preroll",
+                  GST_ELEMENT_NAME (child), next,
+                  gst_element_state_get_name (next));
+              have_no_preroll = TRUE;
+              break;
+            default:
+              g_assert_not_reached ();
+              break;
           }
-          case GST_STATE_CHANGE_FAILURE:
-            GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
-                "child '%s' failed to go to state %d(%s)",
-                GST_ELEMENT_NAME (child),
-                next, gst_element_state_get_name (next));
-            gst_object_unref (child);
-            goto done;
-          case GST_STATE_CHANGE_NO_PREROLL:
-            GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
-                "child '%s' changed state to %d(%s) successfully without preroll",
-                GST_ELEMENT_NAME (child), next,
-                gst_element_state_get_name (next));
-            have_no_preroll = TRUE;
-            break;
-          default:
-            g_assert_not_reached ();
-            break;
+        }
+        else
+        {
+          GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+            "child %s, is skipping transition from %s to  %s, since bin pending is %s", GST_ELEMENT_NAME(child), gst_element_state_get_name (child_current),
+             gst_element_state_get_name (next), gst_element_state_get_name (pending));
         }
         gst_object_unref (child);
         break;
