--- gstreamer-0.10.20.orig/gst/gstbin.c	2009-01-21 20:37:18.000000000 +0000
+++ gstreamer-0.10.20/gst/gstbin.c	2009-01-21 22:40:32.000000000 +0000
@@ -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,10 +2176,26 @@
         GstElement *child;
 
         child = GST_ELEMENT_CAST (data);
+        GstState child_current, child_pending;
+
+        child_current = GST_STATE(child);
+        child_pending = GST_STATE_PENDING(child);
 
-        /* set state and base_time now */
-        ret = gst_bin_element_set_state (bin, child, base_time, current, next);
+        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);
+        }
+        else {
+          GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+              "child %s, is skipping transition from %s to  %s, since bin pending is %s : last change state return follows", GST_ELEMENT_NAME(child), gst_element_state_get_name (child_current),
+              gst_element_state_get_name (next), gst_element_state_get_name (pending));
 
+          // Get the last set_state result to preserve NO_PREROLL and ASYNC
+          ret = GST_STATE_RETURN (element);
+        }
         switch (ret) {
           case GST_STATE_CHANGE_SUCCESS:
             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
