/* GStreamer
 *
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2004 Wim Taymans <wim.taymans@gmail.com>
 *
 * gstbin.c: GstBin container object and support code
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * MT safe.
 */

/**
 * SECTION:gstbin
 * @short_description: Base class and element that can contain other elements
 *
 * #GstBin is an element that can contain other #GstElement, allowing them to be
 * managed as a group.
 * Pads from the child elements can be ghosted to the bin, see #GstGhostPad.
 * This makes the bin look like any other elements and enables creation of
 * higher-level abstraction elements.
 *
 * A new #GstBin is created with gst_bin_new(). Use a #GstPipeline instead if you
 * want to create a toplevel bin because a normal bin doesn't have a bus or
 * handle clock distribution of its own.
 *
 * After the bin has been created you will typically add elements to it with
 * gst_bin_add(). You can remove elements with gst_bin_remove().
 *
 * An element can be retrieved from a bin with gst_bin_get_by_name(), using the
 * elements name. gst_bin_get_by_name_recurse_up() is mainly used for internal
 * purposes and will query the parent bins when the element is not found in the
 * current bin.
 *
 * An iterator of elements in a bin can be retrieved with
 * gst_bin_iterate_elements(). Various other iterators exist to retrieve the
 * elements in a bin.
 *
 * gst_object_unref() is used to drop your reference to the bin.
 *
 * The #GstBin::element-added signal is fired whenever a new element is added to
 * the bin. Likewise the #GstBin::element-removed signal is fired whenever an
 * element is removed from the bin.
 *
 * <refsect2><title>Notes</title>
 * <para>
 * A #GstBin internally intercepts every #GstMessage posted by its children and
 * implements the following default behaviour for each of them:
 * <variablelist>
 *   <varlistentry>
 *     <term>GST_MESSAGE_EOS</term>
 *     <listitem><para>This message is only posted by sinks in the PLAYING
 *     state. If all sinks posted the EOS message, this bin will post and EOS
 *     message upwards.</para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>GST_MESSAGE_SEGMENT_START</term>
 *     <listitem><para>just collected and never forwarded upwards.
 *     The messages are used to decide when all elements have completed playback
 *     of their segment.</para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>GST_MESSAGE_SEGMENT_DONE</term>
 *     <listitem><para> Is posted by #GstBin when all elements that posted
 *     a SEGMENT_START have posted a SEGMENT_DONE.</para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>GST_MESSAGE_DURATION</term>
 *     <listitem><para> Is posted by an element that detected a change
 *     in the stream duration. The default bin behaviour is to clear any
 *     cached duration values so that the next duration query will perform
 *     a full duration recalculation. The duration change is posted to the
 *     application so that it can refetch the new duration with a duration
 *     query. Note that these messages can be posted before the bin is
 *     prerolled, in which case the duration query might fail.
 *     </para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>GST_MESSAGE_CLOCK_LOST</term>
 *     <listitem><para> This message is posted by an element when it
 *     can no longer provide a clock. The default bin behaviour is to
 *     check if the lost clock was the one provided by the bin. If so and
 *     the bin is currently in the PLAYING state, the message is forwarded to
 *     the bin parent.
 *     This message is also generated when a clock provider is removed from
 *     the bin. If this message is received by the application, it should
 *     PAUSE the pipeline and set it back to PLAYING to force a new clock
 *     distribution.
 *     </para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>GST_MESSAGE_CLOCK_PROVIDE</term>
 *     <listitem><para> This message is generated when an element
 *     can provide a clock. This mostly happens when a new clock
 *     provider is added to the bin. The default behaviour of the bin is to
 *     mark the currently selected clock as dirty, which will perform a clock
 *     recalculation the next time the bin is asked to provide a clock.
 *     This message is never sent tot the application but is forwarded to
 *     the parent of the bin.
 *     </para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>OTHERS</term>
 *     <listitem><para> posted upwards.</para></listitem>
 *   </varlistentry>
 * </variablelist>
 *
 *
 * A #GstBin implements the following default behaviour for answering to a
 * #GstQuery:
 * <variablelist>
 *   <varlistentry>
 *     <term>GST_QUERY_DURATION</term>
 *     <listitem><para>If the query has been asked before with the same format
 *     and the bin is a toplevel bin (ie. has no parent),
 *     use the cached previous value. If no previous value was cached, the
 *     query is sent to all sink elements in the bin and the MAXIMUM of all
 *     values is returned. If the bin is a toplevel bin the value is cached.
 *     If no sinks are available in the bin, the query fails.
 *     </para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>GST_QUERY_POSITION</term>
 *     <listitem><para>The query is sent to all sink elements in the bin and the
 *     MAXIMUM of all values is returned. If no sinks are available in the bin,
 *     the query fails.
 *     </para></listitem>
 *   </varlistentry>
 *   <varlistentry>
 *     <term>OTHERS</term>
 *     <listitem><para>the query is forwarded to all sink elements, the result
 *     of the first sink that answers the query successfully is returned. If no
 *     sink is in the bin, the query fails.</para></listitem>
 *   </varlistentry>
 * </variablelist>
 *
 * A #GstBin will by default forward any event sent to it to all sink elements.
 * If all the sinks return TRUE, the bin will also return TRUE, else FALSE is
 * returned. If no sinks are in the bin, the event handler will return TRUE.
 *
 * </para>
 * </refsect2>
 *
 * Last reviewed on 2012-03-28 (0.11.3)
 */

#include "gst_private.h"

#include "gstevent.h"
#include "gstbin.h"
#include "gstinfo.h"
#include "gsterror.h"

#include "gstutils.h"
#include "gstchildproxy.h"

GST_DEBUG_CATEGORY_STATIC (bin_debug);
#define GST_CAT_DEFAULT bin_debug

/* a bin is toplevel if it has no parent or when it is configured to behave like
 * a toplevel bin */
#define BIN_IS_TOPLEVEL(bin) ((GST_OBJECT_PARENT (bin) == NULL) || bin->priv->asynchandling)

#define GST_BIN_GET_PRIVATE(obj)  \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BIN, GstBinPrivate))

struct _GstBinPrivate
{
  gboolean asynchandling;
  /* if we get an ASYNC_DONE message from ourselves, this means that the
   * subclass will simulate ASYNC behaviour without having ASYNC children. When
   * such an ASYNC_DONE message is posted while we are doing a state change, we
   * have to process the message after finishing the state change even when no
   * child returned GST_STATE_CHANGE_ASYNC. */
  gboolean pending_async_done;

  guint32 structure_cookie;

#if 0
  /* cached index */
  GstIndex *index;
#endif

  /* forward messages from our children */
  gboolean message_forward;

  gboolean posted_eos;
};

typedef struct
{
  GstBin *bin;
  guint32 cookie;
  GstState pending;
} BinContinueData;

static void gst_bin_dispose (GObject * object);

static void gst_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstStateChangeReturn gst_bin_change_state_func (GstElement * element,
    GstStateChange transition);
static void gst_bin_state_changed (GstElement * element, GstState oldstate,
    GstState newstate, GstState pending);
static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
    GstState * state, GstState * pending, GstClockTime timeout);
static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
    gboolean flag_pending, GstClockTime running_time);
static void bin_handle_async_start (GstBin * bin);
static void bin_push_state_continue (BinContinueData * data);
static void bin_do_eos (GstBin * bin);

static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);

#if 0
static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
static GstIndex *gst_bin_get_index_func (GstElement * element);
#endif

static GstClock *gst_bin_provide_clock_func (GstElement * element);
static gboolean gst_bin_set_clock_func (GstElement * element, GstClock * clock);

static void gst_bin_handle_message_func (GstBin * bin, GstMessage * message);
static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
static GstBusSyncReply bin_bus_handler (GstBus * bus,
    GstMessage * message, GstBin * bin);
static gboolean gst_bin_query (GstElement * element, GstQuery * query);

static gboolean gst_bin_do_latency_func (GstBin * bin);

static void bin_remove_messages (GstBin * bin, GstObject * src,
    GstMessageType types);
static void gst_bin_continue_func (BinContinueData * data);
static gint bin_element_is_sink (GstElement * child, GstBin * bin);
static gint bin_element_is_src (GstElement * child, GstBin * bin);

static GstIterator *gst_bin_sort_iterator_new (GstBin * bin);

/* Bin signals and properties */
enum
{
  ELEMENT_ADDED,
  ELEMENT_REMOVED,
  DO_LATENCY,
  LAST_SIGNAL
};

#define DEFAULT_ASYNC_HANDLING	FALSE
#define DEFAULT_MESSAGE_FORWARD	FALSE

enum
{
  PROP_0,
  PROP_ASYNC_HANDLING,
  PROP_MESSAGE_FORWARD,
  PROP_LAST
};

static void gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data);

static guint gst_bin_signals[LAST_SIGNAL] = { 0 };

#define _do_init \
{ \
  static const GInterfaceInfo iface_info = { \
    gst_bin_child_proxy_init, \
    NULL, \
    NULL}; \
  \
  g_type_add_interface_static (g_define_type_id, GST_TYPE_CHILD_PROXY, &iface_info); \
  \
  GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD, \
      "debugging info for the 'bin' container element"); \
  \
}

#define gst_bin_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstBin, gst_bin, GST_TYPE_ELEMENT, _do_init);

static GObject *
gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
    guint index)
{
  GstObject *res;
  GstBin *bin;

  bin = GST_BIN_CAST (child_proxy);

  GST_OBJECT_LOCK (bin);
  if ((res = g_list_nth_data (bin->children, index)))
    gst_object_ref (res);
  GST_OBJECT_UNLOCK (bin);

  return (GObject *) res;
}

static guint
gst_bin_child_proxy_get_children_count (GstChildProxy * child_proxy)
{
  guint num;
  GstBin *bin;

  bin = GST_BIN_CAST (child_proxy);

  GST_OBJECT_LOCK (bin);
  num = bin->numchildren;
  GST_OBJECT_UNLOCK (bin);

  return num;
}

static void
gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data)
{
  GstChildProxyInterface *iface = g_iface;

  iface->get_children_count = gst_bin_child_proxy_get_children_count;
  iface->get_child_by_index = gst_bin_child_proxy_get_child_by_index;
}

static gboolean
_gst_boolean_accumulator (GSignalInvocationHint * ihint,
    GValue * return_accu, const GValue * handler_return, gpointer dummy)
{
  gboolean myboolean;

  myboolean = g_value_get_boolean (handler_return);
  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
    g_value_set_boolean (return_accu, myboolean);

  GST_DEBUG ("invocation %d, %d", ihint->run_type, myboolean);

  /* stop emission */
  return FALSE;
}

static void
gst_bin_class_init (GstBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GError *err;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  g_type_class_add_private (klass, sizeof (GstBinPrivate));

  gobject_class->set_property = gst_bin_set_property;
  gobject_class->get_property = gst_bin_get_property;

  /**
   * GstBin:async-handling:
   *
   * If set to #TRUE, the bin will handle asynchronous state changes.
   * This should be used only if the bin subclass is modifying the state
   * of its children on its own.
   */
  g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
      g_param_spec_boolean ("async-handling", "Async Handling",
          "The bin will handle Asynchronous state changes",
          DEFAULT_ASYNC_HANDLING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstBin::element-added:
   * @bin: the #GstBin
   * @element: the #GstElement that was added to the bin
   *
   * Will be emitted after the element was added to the bin.
   */
  gst_bin_signals[ELEMENT_ADDED] =
      g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
      NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
  /**
   * GstBin::element-removed:
   * @bin: the #GstBin
   * @element: the #GstElement that was removed from the bin
   *
   * Will be emitted after the element was removed from the bin.
   */
  gst_bin_signals[ELEMENT_REMOVED] =
      g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
      NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
  /**
   * GstBin::do-latency:
   * @bin: the #GstBin
   *
   * Will be emitted when the bin needs to perform latency calculations. This
   * signal is only emited for toplevel bins or when async-handling is
   * enabled.
   *
   * Only one signal handler is invoked. If no signals are connected, the
   * default handler is invoked, which will query and distribute the lowest
   * possible latency to all sinks.
   *
   * Connect to this signal if the default latency calculations are not
   * sufficient, like when you need different latencies for different sinks in
   * the same pipeline.
   */
  gst_bin_signals[DO_LATENCY] =
      g_signal_new ("do-latency", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstBinClass, do_latency),
      _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
      G_TYPE_BOOLEAN, 0, G_TYPE_NONE);

  /**
   * GstBin:message-forward:
   *
   * Forward all children messages, even those that would normally be filtered by
   * the bin. This can be interesting when one wants to be notified of the EOS
   * state of individual elements, for example.
   *
   * The messages are converted to an ELEMENT message with the bin as the
   * source. The structure of the message is named 'GstBinForwarded' and contains
   * a field named 'message' of type GST_TYPE_MESSAGE that contains the original
   * forwarded message.
   */
  g_object_class_install_property (gobject_class, PROP_MESSAGE_FORWARD,
      g_param_spec_boolean ("message-forward", "Message Forward",
          "Forwards all children messages",
          DEFAULT_MESSAGE_FORWARD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gobject_class->dispose = gst_bin_dispose;

  gst_element_class_set_metadata (gstelement_class, "Generic bin",
      "Generic/Bin",
      "Simple container object",
      "Erik Walthinsen <omega@cse.ogi.edu>,"
      "Wim Taymans <wim.taymans@gmail.com>");

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
  gstelement_class->state_changed = GST_DEBUG_FUNCPTR (gst_bin_state_changed);
  gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
#if 0
  gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_bin_get_index_func);
  gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
#endif
  gstelement_class->provide_clock =
      GST_DEBUG_FUNCPTR (gst_bin_provide_clock_func);
  gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);

  gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
  gstelement_class->query = GST_DEBUG_FUNCPTR (gst_bin_query);

  klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
  klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
  klass->handle_message = GST_DEBUG_FUNCPTR (gst_bin_handle_message_func);

  klass->do_latency = GST_DEBUG_FUNCPTR (gst_bin_do_latency_func);

  GST_DEBUG ("creating bin thread pool");
  err = NULL;
  klass->pool =
      g_thread_pool_new ((GFunc) gst_bin_continue_func, NULL, -1, FALSE, &err);
  if (err != NULL) {
    g_critical ("could alloc threadpool %s", err->message);
  }
}

static void
gst_bin_init (GstBin * bin)
{
  GstBus *bus;

  bin->numchildren = 0;
  bin->children = NULL;
  bin->children_cookie = 0;
  bin->messages = NULL;
  bin->provided_clock = NULL;
  bin->clock_dirty = FALSE;

  /* Set up a bus for listening to child elements */
  bus = g_object_new (GST_TYPE_BUS, "enable-async", FALSE, NULL);
  bin->child_bus = bus;
  GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
      bus);
  gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin,
      NULL);

  bin->priv = GST_BIN_GET_PRIVATE (bin);
  bin->priv->asynchandling = DEFAULT_ASYNC_HANDLING;
  bin->priv->structure_cookie = 0;
  bin->priv->message_forward = DEFAULT_MESSAGE_FORWARD;
}

static void
gst_bin_dispose (GObject * object)
{
  GstBin *bin = GST_BIN_CAST (object);
  GstBus **child_bus_p = &bin->child_bus;
  GstClock **provided_clock_p = &bin->provided_clock;
  GstElement **clock_provider_p = &bin->clock_provider;

  GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");

  GST_OBJECT_LOCK (object);
  gst_object_replace ((GstObject **) child_bus_p, NULL);
  gst_object_replace ((GstObject **) provided_clock_p, NULL);
  gst_object_replace ((GstObject **) clock_provider_p, NULL);
  bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
  GST_OBJECT_UNLOCK (object);

  while (bin->children) {
    gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
  }
  if (G_UNLIKELY (bin->children != NULL)) {
    g_critical ("could not remove elements from bin '%s'",
        GST_STR_NULL (GST_OBJECT_NAME (object)));
  }

  G_OBJECT_CLASS (parent_class)->dispose (object);
}

/**
 * gst_bin_new:
 * @name: the name of the new bin
 *
 * Creates a new bin with the given name.
 *
 * Returns: (transfer floating): a new #GstBin
 */
GstElement *
gst_bin_new (const gchar * name)
{
  return gst_element_factory_make ("bin", name);
}

static void
gst_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstBin *gstbin;

  gstbin = GST_BIN_CAST (object);

  switch (prop_id) {
    case PROP_ASYNC_HANDLING:
      GST_OBJECT_LOCK (gstbin);
      gstbin->priv->asynchandling = g_value_get_boolean (value);
      GST_OBJECT_UNLOCK (gstbin);
      break;
    case PROP_MESSAGE_FORWARD:
      GST_OBJECT_LOCK (gstbin);
      gstbin->priv->message_forward = g_value_get_boolean (value);
      GST_OBJECT_UNLOCK (gstbin);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstBin *gstbin;

  gstbin = GST_BIN_CAST (object);

  switch (prop_id) {
    case PROP_ASYNC_HANDLING:
      GST_OBJECT_LOCK (gstbin);
      g_value_set_boolean (value, gstbin->priv->asynchandling);
      GST_OBJECT_UNLOCK (gstbin);
      break;
    case PROP_MESSAGE_FORWARD:
      GST_OBJECT_LOCK (gstbin);
      g_value_set_boolean (value, gstbin->priv->message_forward);
      GST_OBJECT_UNLOCK (gstbin);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

#if 0
/* return the cached index */
static GstIndex *
gst_bin_get_index_func (GstElement * element)
{
  GstBin *bin;
  GstIndex *result;

  bin = GST_BIN_CAST (element);

  GST_OBJECT_LOCK (bin);
  if ((result = bin->priv->index))
    gst_object_ref (result);
  GST_OBJECT_UNLOCK (bin);

  return result;
}

/* set the index on all elements in this bin
 *
 * MT safe
 */
static void
gst_bin_set_index_func (GstElement * element, GstIndex * index)
{
  GstBin *bin;
  gboolean done;
  GstIterator *it;
  GstIndex *old;
  GValue data = { 0, };

  bin = GST_BIN_CAST (element);

  GST_OBJECT_LOCK (bin);
  old = bin->priv->index;
  if (G_UNLIKELY (old == index))
    goto was_set;
  if (index)
    gst_object_ref (index);
  bin->priv->index = index;
  GST_OBJECT_UNLOCK (bin);

  if (old)
    gst_object_unref (old);

  it = gst_bin_iterate_elements (bin);

  /* set the index on all elements in the bin */
  done = FALSE;
  while (!done) {
    switch (gst_iterator_next (it, &data)) {
      case GST_ITERATOR_OK:
      {
        GstElement *child = g_value_get_object (&data);

        GST_DEBUG_OBJECT (bin, "setting index on '%s'",
            GST_ELEMENT_NAME (child));
        gst_element_set_index (child, index);

        g_value_reset (&data);
        break;
      }
      case GST_ITERATOR_RESYNC:
        GST_DEBUG_OBJECT (bin, "iterator doing resync");
        gst_iterator_resync (it);
        break;
      default:
      case GST_ITERATOR_DONE:
        GST_DEBUG_OBJECT (bin, "iterator done");
        done = TRUE;
        break;
    }
  }
  g_value_unset (&data);
  gst_iterator_free (it);
  return;

was_set:
  {
    GST_DEBUG_OBJECT (bin, "index was already set");
    GST_OBJECT_UNLOCK (bin);
    return;
  }
}
#endif

/* set the clock on all elements in this bin
 *
 * MT safe
 */
static gboolean
gst_bin_set_clock_func (GstElement * element, GstClock * clock)
{
  GstBin *bin;
  gboolean done;
  GstIterator *it;
  gboolean res = TRUE;
  GValue data = { 0, };

  bin = GST_BIN_CAST (element);

  it = gst_bin_iterate_elements (bin);

  done = FALSE;
  while (!done) {
    switch (gst_iterator_next (it, &data)) {
      case GST_ITERATOR_OK:
      {
        GstElement *child = g_value_get_object (&data);

        res &= gst_element_set_clock (child, clock);

        g_value_reset (&data);
        break;
      }
      case GST_ITERATOR_RESYNC:
        GST_DEBUG_OBJECT (bin, "iterator doing resync");
        gst_iterator_resync (it);
        res = TRUE;
        break;
      default:
      case GST_ITERATOR_DONE:
        GST_DEBUG_OBJECT (bin, "iterator done");
        done = TRUE;
        break;
    }
  }
  g_value_unset (&data);
  gst_iterator_free (it);

  if (res)
    res = GST_ELEMENT_CLASS (parent_class)->set_clock (element, clock);

  return res;
}

/* get the clock for this bin by asking all of the children in this bin
 *
 * The ref of the returned clock in increased so unref after usage.
 *
 * We loop the elements in state order and pick the last clock we can
 * get. This makes sure we get a clock from the source.
 *
 * MT safe
 */
static GstClock *
gst_bin_provide_clock_func (GstElement * element)
{
  GstClock *result = NULL;
  GstElement *provider = NULL;
  GstBin *bin;
  GstIterator *it;
  gboolean done;
  GValue val = { 0, };
  GstClock **provided_clock_p;
  GstElement **clock_provider_p;

  bin = GST_BIN_CAST (element);

  GST_OBJECT_LOCK (bin);
  if (!bin->clock_dirty)
    goto not_dirty;

  GST_DEBUG_OBJECT (bin, "finding new clock");

  it = gst_bin_sort_iterator_new (bin);
  GST_OBJECT_UNLOCK (bin);

  done = FALSE;
  while (!done) {
    switch (gst_iterator_next (it, &val)) {
      case GST_ITERATOR_OK:
      {
        GstElement *child = g_value_get_object (&val);
        GstClock *clock;

        clock = gst_element_provide_clock (child);
        if (clock) {
          GST_DEBUG_OBJECT (bin, "found candidate clock %p by element %s",
              clock, GST_ELEMENT_NAME (child));
          if (result) {
            gst_object_unref (result);
            gst_object_unref (provider);
          }
          result = clock;
          provider = gst_object_ref (child);
        }

        g_value_reset (&val);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (it);
        break;
      default:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }
  g_value_unset (&val);
  gst_iterator_free (it);

  GST_OBJECT_LOCK (bin);
  if (!bin->clock_dirty) {
    if (provider)
      gst_object_unref (provider);
    if (result)
      gst_object_unref (result);
    result = NULL;

    goto not_dirty;
  }

  provided_clock_p = &bin->provided_clock;
  clock_provider_p = &bin->clock_provider;
  gst_object_replace ((GstObject **) provided_clock_p, (GstObject *) result);
  gst_object_replace ((GstObject **) clock_provider_p, (GstObject *) provider);
  bin->clock_dirty = FALSE;
  GST_DEBUG_OBJECT (bin,
      "provided new clock %" GST_PTR_FORMAT " by provider %" GST_PTR_FORMAT,
      result, provider);
  /* Provider is not being returned to caller, just the result */
  if (provider)
    gst_object_unref (provider);
  GST_OBJECT_UNLOCK (bin);

  return result;

not_dirty:
  {
    if ((result = bin->provided_clock))
      gst_object_ref (result);
    GST_DEBUG_OBJECT (bin, "returning old clock %p", result);
    GST_OBJECT_UNLOCK (bin);

    return result;
  }
}

/*
 * functions for manipulating cached messages
 */
typedef struct
{
  GstObject *src;
  GstMessageType types;
} MessageFind;

/* check if a message is of given src and type */
static gint
message_check (GstMessage * message, MessageFind * target)
{
  gboolean eq = TRUE;

  if (target->src)
    eq &= GST_MESSAGE_SRC (message) == target->src;
  if (target->types)
    eq &= (GST_MESSAGE_TYPE (message) & target->types) != 0;
  GST_LOG ("looking at message %p: %d", message, eq);

  return (eq ? 0 : 1);
}

static GList *
find_message (GstBin * bin, GstObject * src, GstMessageType types)
{
  GList *result;
  MessageFind find;

  find.src = src;
  find.types = types;

  result = g_list_find_custom (bin->messages, &find,
      (GCompareFunc) message_check);

  if (result) {
    GST_DEBUG_OBJECT (bin, "we found a message %p from %s matching types %08x",
        result->data, GST_OBJECT_NAME (GST_MESSAGE_CAST (result->data)->src),
        types);
  } else {
    GST_DEBUG_OBJECT (bin, "no message found matching types %08x", types);
#ifndef GST_DISABLE_GST_DEBUG
    {
      guint i;

      for (i = 0; i < 32; i++)
        if (types & (1 << i))
          GST_DEBUG_OBJECT (bin, "  %s", gst_message_type_get_name (1 << i));
    }
#endif
  }

  return result;
}

/* with LOCK, returns TRUE if message had a valid SRC, takes ownership of
 * the message.
 *
 * A message that is cached and has the same SRC and type is replaced
 * by the given message.
 */
static gboolean
bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
{
  GList *previous;
  GstObject *src;
  gboolean res = TRUE;

  if ((src = GST_MESSAGE_SRC (message))) {
    /* first find the previous message posted by this element */
    if ((previous = find_message (bin, src, types))) {
      GstMessage *previous_msg;

      /* if we found a previous message, replace it */
      previous_msg = previous->data;
      previous->data = message;

      GST_DEBUG_OBJECT (bin, "replace old message %s from %s with %s message",
          GST_MESSAGE_TYPE_NAME (previous_msg), GST_ELEMENT_NAME (src),
          GST_MESSAGE_TYPE_NAME (message));

      gst_message_unref (previous_msg);
    } else {
      /* keep new message */
      bin->messages = g_list_prepend (bin->messages, message);

      GST_DEBUG_OBJECT (bin, "got new message %p, %s from %s",
          message, GST_MESSAGE_TYPE_NAME (message), GST_ELEMENT_NAME (src));
    }
  } else {
    GST_DEBUG_OBJECT (bin, "got message %s from (NULL), not processing",
        GST_MESSAGE_TYPE_NAME (message));
    res = FALSE;
    gst_message_unref (message);
  }
  return res;
}

/* with LOCK. Remove all messages of given types */
static void
bin_remove_messages (GstBin * bin, GstObject * src, GstMessageType types)
{
  MessageFind find;
  GList *walk, *next;

  find.src = src;
  find.types = types;

  for (walk = bin->messages; walk; walk = next) {
    GstMessage *message = (GstMessage *) walk->data;

    next = g_list_next (walk);

    if (message_check (message, &find) == 0) {
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
          "deleting message %p of types 0x%08x", message, types);
      bin->messages = g_list_delete_link (bin->messages, walk);
      gst_message_unref (message);
    } else {
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
          "not deleting message %p of type 0x%08x", message,
          GST_MESSAGE_TYPE (message));
    }
  }
}


/* Check if the bin is EOS. We do this by scanning all sinks and
 * checking if they posted an EOS message.
 *
 * call with bin LOCK */
static gboolean
is_eos (GstBin * bin, guint32 * seqnum)
{
  gboolean result;
  gint n_eos = 0;
  GList *walk, *msgs;

  result = TRUE;
  for (walk = bin->children; walk; walk = g_list_next (walk)) {
    GstElement *element;

    element = GST_ELEMENT_CAST (walk->data);
    if (bin_element_is_sink (element, bin) == 0) {
      /* check if element posted EOS */
      if ((msgs =
              find_message (bin, GST_OBJECT_CAST (element), GST_MESSAGE_EOS))) {
        GST_DEBUG ("sink '%s' posted EOS", GST_ELEMENT_NAME (element));
        *seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data));
        n_eos++;
      } else {
        GST_DEBUG ("sink '%s' did not post EOS yet",
            GST_ELEMENT_NAME (element));
        result = FALSE;
        break;
      }
    }
  }
  /* FIXME: Some tests (e.g. elements/capsfilter) use
   * pipelines with a dangling sinkpad but no sink element.
   * These tests assume that no EOS message is ever
   * posted on the bus so let's keep that behaviour.
   * In valid pipelines this doesn't make a difference.
   */
  return result && n_eos > 0;
}


/* Check if the bin is STREAM_START. We do this by scanning all sinks and
 * checking if they posted an STREAM_START message.
 *
 * call with bin LOCK */
static gboolean
is_stream_start (GstBin * bin, guint32 * seqnum)
{
  gboolean result;
  gint n_stream_start = 0;
  GList *walk, *msgs;

  result = TRUE;
  for (walk = bin->children; walk; walk = g_list_next (walk)) {
    GstElement *element;

    element = GST_ELEMENT_CAST (walk->data);
    if (bin_element_is_sink (element, bin) == 0) {
      /* check if element posted STREAM_START */
      if ((msgs =
              find_message (bin, GST_OBJECT_CAST (element),
                  GST_MESSAGE_STREAM_START))) {
        GST_DEBUG ("sink '%s' posted STREAM_START", GST_ELEMENT_NAME (element));
        *seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data));
        n_stream_start++;
      } else {
        GST_DEBUG ("sink '%s' did not post STREAM_START yet",
            GST_ELEMENT_NAME (element));
        result = FALSE;
        break;
      }
    }
  }

  return result;
}

static void
unlink_pads (const GValue * item, gpointer user_data)
{
  GstPad *pad;
  GstPad *peer;

  pad = g_value_get_object (item);

  if ((peer = gst_pad_get_peer (pad))) {
    if (gst_pad_get_direction (pad) == GST_PAD_SRC)
      gst_pad_unlink (pad, peer);
    else
      gst_pad_unlink (peer, pad);
    gst_object_unref (peer);
  }
}

/* vmethod that adds an element to a bin
 *
 * MT safe
 */
static gboolean
gst_bin_add_func (GstBin * bin, GstElement * element)
{
  gchar *elem_name;
  GstIterator *it;
  gboolean is_sink, is_source, provides_clock, requires_clock;
  GstMessage *clock_message = NULL, *async_message = NULL;
  GstStateChangeReturn ret;

  GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));

  /* we obviously can't add ourself to ourself */
  if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
    goto adding_itself;

  /* get the element name to make sure it is unique in this bin. */
  GST_OBJECT_LOCK (element);
  elem_name = g_strdup (GST_ELEMENT_NAME (element));
  is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
  is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SOURCE);
  provides_clock =
      GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  requires_clock =
      GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
  GST_OBJECT_UNLOCK (element);

  GST_OBJECT_LOCK (bin);

  /* then check to see if the element's name is already taken in the bin,
   * we can safely take the lock here. This check is probably bogus because
   * you can safely change the element name after this check and before setting
   * the object parent. The window is very small though... */
  if (G_UNLIKELY (!gst_object_check_uniqueness (bin->children, elem_name)))
    goto duplicate_name;

  /* set the element's parent and add the element to the bin's list of children */
  if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (element),
              GST_OBJECT_CAST (bin))))
    goto had_parent;

  /* if we add a sink we become a sink */
  if (is_sink) {
    GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was sink",
        elem_name);
    GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SINK);
  }
  if (is_source) {
    GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was source",
        elem_name);
    GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
  }
  if (provides_clock) {
    GST_DEBUG_OBJECT (bin, "element \"%s\" can provide a clock", elem_name);
    clock_message =
        gst_message_new_clock_provide (GST_OBJECT_CAST (element), NULL, TRUE);
    GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  }
  if (requires_clock) {
    GST_DEBUG_OBJECT (bin, "element \"%s\" requires a clock", elem_name);
    GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
  }

  bin->children = g_list_prepend (bin->children, element);
  bin->numchildren++;
  bin->children_cookie++;
  bin->priv->structure_cookie++;

  /* distribute the bus */
  gst_element_set_bus (element, bin->child_bus);

  /* propagate the current base_time, start_time and clock */
  gst_element_set_base_time (element, GST_ELEMENT_CAST (bin)->base_time);
  gst_element_set_start_time (element, GST_ELEMENT_START_TIME (bin));
  /* it's possible that the element did not accept the clock but
   * that is not important right now. When the pipeline goes to PLAYING,
   * a new clock will be selected */
  gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));

#if 0
  /* set the cached index on the children */
  if (bin->priv->index)
    gst_element_set_index (element, bin->priv->index);
#endif

  ret = GST_STATE_RETURN (bin);
  /* no need to update the state if we are in error */
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto no_state_recalc;

  /* update the bin state, the new element could have been an ASYNC or
   * NO_PREROLL element */
  ret = GST_STATE_RETURN (element);
  GST_DEBUG_OBJECT (bin, "added %s element",
      gst_element_state_change_return_get_name (ret));

  switch (ret) {
    case GST_STATE_CHANGE_ASYNC:
    {
      /* create message to track this aync element when it posts an async-done
       * message */
      async_message = gst_message_new_async_start (GST_OBJECT_CAST (element));
      break;
    }
    case GST_STATE_CHANGE_NO_PREROLL:
      /* ignore all async elements we might have and commit our state */
      bin_handle_async_done (bin, ret, FALSE, GST_CLOCK_TIME_NONE);
      break;
    case GST_STATE_CHANGE_FAILURE:
      break;
    default:
      break;
  }

no_state_recalc:
  GST_OBJECT_UNLOCK (bin);

  /* post the messages on the bus of the element so that the bin can handle
   * them */
  if (clock_message)
    gst_element_post_message (GST_ELEMENT_CAST (element), clock_message);

  if (async_message)
    gst_element_post_message (GST_ELEMENT_CAST (element), async_message);

  /* unlink all linked pads */
  it = gst_element_iterate_pads (element);
  gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
  gst_iterator_free (it);

  GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
      elem_name);

  g_signal_emit (bin, gst_bin_signals[ELEMENT_ADDED], 0, element);
  gst_child_proxy_child_added ((GstChildProxy *) bin, (GObject *) element,
      elem_name);

  g_free (elem_name);

  return TRUE;

  /* ERROR handling here */
adding_itself:
  {
    GST_OBJECT_LOCK (bin);
    g_warning ("Cannot add bin '%s' to itself", GST_ELEMENT_NAME (bin));
    GST_OBJECT_UNLOCK (bin);
    return FALSE;
  }
duplicate_name:
  {
    g_warning ("Name '%s' is not unique in bin '%s', not adding",
        elem_name, GST_ELEMENT_NAME (bin));
    GST_OBJECT_UNLOCK (bin);
    g_free (elem_name);
    return FALSE;
  }
had_parent:
  {
    g_warning ("Element '%s' already has parent", elem_name);
    GST_OBJECT_UNLOCK (bin);
    g_free (elem_name);
    return FALSE;
  }
}

/**
 * gst_bin_add:
 * @bin: a #GstBin
 * @element: (transfer full): the #GstElement to add
 *
 * Adds the given element to the bin.  Sets the element's parent, and thus
 * takes ownership of the element. An element can only be added to one bin.
 *
 * If the element's pads are linked to other pads, the pads will be unlinked
 * before the element is added to the bin.
 *
 * <note>
 * When you add an element to an already-running pipeline, you will have to
 * take care to set the state of the newly-added element to the desired
 * state (usually PLAYING or PAUSED, same you set the pipeline to originally)
 * with gst_element_set_state(), or use gst_element_sync_state_with_parent().
 * The bin or pipeline will not take care of this for you.
 * </note>
 *
 * MT safe.
 *
 * Returns: TRUE if the element could be added, FALSE if
 * the bin does not want to accept the element.
 */
gboolean
gst_bin_add (GstBin * bin, GstElement * element)
{
  GstBinClass *bclass;
  gboolean result;

  g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);

  bclass = GST_BIN_GET_CLASS (bin);

  if (G_UNLIKELY (bclass->add_element == NULL))
    goto no_function;

  GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
      GST_STR_NULL (GST_ELEMENT_NAME (element)),
      GST_STR_NULL (GST_ELEMENT_NAME (bin)));

  result = bclass->add_element (bin, element);

  return result;

  /* ERROR handling */
no_function:
  {
    g_warning ("adding elements to bin '%s' is not supported",
        GST_ELEMENT_NAME (bin));
    return FALSE;
  }
}

/* remove an element from the bin
 *
 * MT safe
 */
static gboolean
gst_bin_remove_func (GstBin * bin, GstElement * element)
{
  gchar *elem_name;
  GstIterator *it;
  gboolean is_sink, is_source, provides_clock, requires_clock;
  gboolean othersink, othersource, otherprovider, otherrequirer, found;
  GstMessage *clock_message = NULL;
  GstClock **provided_clock_p;
  GstElement **clock_provider_p;
  GList *walk, *next;
  gboolean other_async, this_async, have_no_preroll;
  GstStateChangeReturn ret;

  GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));

  GST_OBJECT_LOCK (bin);

  GST_OBJECT_LOCK (element);
  elem_name = g_strdup (GST_ELEMENT_NAME (element));

  if (GST_OBJECT_PARENT (element) != GST_OBJECT_CAST (bin))
    goto not_in_bin;

  /* remove the parent ref */
  GST_OBJECT_PARENT (element) = NULL;

  /* grab element name so we can print it */
  is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
  is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SOURCE);
  provides_clock =
      GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  requires_clock =
      GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
  GST_OBJECT_UNLOCK (element);

  found = FALSE;
  othersink = FALSE;
  othersource = FALSE;
  otherprovider = FALSE;
  otherrequirer = FALSE;
  have_no_preroll = FALSE;
  /* iterate the elements, we collect which ones are async and no_preroll. We
   * also remove the element when we find it. */
  for (walk = bin->children; walk; walk = next) {
    GstElement *child = GST_ELEMENT_CAST (walk->data);

    next = g_list_next (walk);

    if (child == element) {
      found = TRUE;
      /* remove the element */
      bin->children = g_list_delete_link (bin->children, walk);
    } else {
      gboolean child_sink, child_source, child_provider, child_requirer;

      GST_OBJECT_LOCK (child);
      child_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SINK);
      child_source = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SOURCE);
      child_provider =
          GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
      child_requirer =
          GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
      /* when we remove a sink, check if there are other sinks. */
      if (is_sink && !othersink && child_sink)
        othersink = TRUE;
      if (is_source && !othersource && child_source)
        othersource = TRUE;
      if (provides_clock && !otherprovider && child_provider)
        otherprovider = TRUE;
      if (requires_clock && !otherrequirer && child_requirer)
        otherrequirer = TRUE;
      /* check if we have NO_PREROLL children */
      if (GST_STATE_RETURN (child) == GST_STATE_CHANGE_NO_PREROLL)
        have_no_preroll = TRUE;
      GST_OBJECT_UNLOCK (child);
    }
  }

  /* the element must have been in the bin's list of children */
  if (G_UNLIKELY (!found))
    goto not_in_bin;

  /* we now removed the element from the list of elements, increment the cookie
   * so that others can detect a change in the children list. */
  bin->numchildren--;
  bin->children_cookie++;
  bin->priv->structure_cookie++;

  if (is_sink && !othersink) {
    /* we're not a sink anymore */
    GST_DEBUG_OBJECT (bin, "we removed the last sink");
    GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_SINK);
  }
  if (is_source && !othersource) {
    /* we're not a source anymore */
    GST_DEBUG_OBJECT (bin, "we removed the last source");
    GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_SOURCE);
  }
  if (provides_clock && !otherprovider) {
    /* we're not a clock provider anymore */
    GST_DEBUG_OBJECT (bin, "we removed the last clock provider");
    GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
  }
  if (requires_clock && !otherrequirer) {
    /* we're not a clock requirer anymore */
    GST_DEBUG_OBJECT (bin, "we removed the last clock requirer");
    GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
  }

  /* if the clock provider for this element is removed, we lost
   * the clock as well, we need to inform the parent of this
   * so that it can select a new clock */
  if (bin->clock_provider == element) {
    GST_DEBUG_OBJECT (bin, "element \"%s\" provided the clock", elem_name);
    bin->clock_dirty = TRUE;
    clock_message =
        gst_message_new_clock_lost (GST_OBJECT_CAST (bin), bin->provided_clock);
    provided_clock_p = &bin->provided_clock;
    clock_provider_p = &bin->clock_provider;
    gst_object_replace ((GstObject **) provided_clock_p, NULL);
    gst_object_replace ((GstObject **) clock_provider_p, NULL);
  }

  /* remove messages for the element, if there was a pending ASYNC_START
   * message we must see if removing the element caused the bin to lose its
   * async state. */
  this_async = FALSE;
  other_async = FALSE;
  for (walk = bin->messages; walk; walk = next) {
    GstMessage *message = (GstMessage *) walk->data;
    GstElement *src = GST_ELEMENT_CAST (GST_MESSAGE_SRC (message));
    gboolean remove;

    next = g_list_next (walk);
    remove = FALSE;

    switch (GST_MESSAGE_TYPE (message)) {
      case GST_MESSAGE_ASYNC_START:
        if (src == element)
          this_async = TRUE;
        else
          other_async = TRUE;

        GST_DEBUG_OBJECT (src, "looking at message %p", message);
        break;
      case GST_MESSAGE_STRUCTURE_CHANGE:
      {
        GstElement *owner;

        GST_DEBUG_OBJECT (src, "looking at structure change message %p",
            message);
        /* it's unlikely that this message is still in the list of messages
         * because this would mean that a link/unlink is busy in another thread
         * while we remove the element. We still have to remove the message
         * because we might not receive the done message anymore when the element
         * is removed from the bin. */
        gst_message_parse_structure_change (message, NULL, &owner, NULL);
        if (owner == element)
          remove = TRUE;
        break;
      }
      default:
        break;
    }
    if (src == element)
      remove = TRUE;

    if (remove) {
      /* delete all message types */
      GST_DEBUG_OBJECT (src, "deleting message %p of element \"%s\"",
          message, elem_name);
      bin->messages = g_list_delete_link (bin->messages, walk);
      gst_message_unref (message);
    }
  }

  /* get last return */
  ret = GST_STATE_RETURN (bin);

  /* no need to update the state if we are in error */
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto no_state_recalc;

  if (!other_async && this_async) {
    /* all other elements were not async and we removed the async one,
     * handle the async-done case because we are not async anymore now. */
    GST_DEBUG_OBJECT (bin,
        "we removed the last async element, have no_preroll %d",
        have_no_preroll);

    /* the current state return of the bin depends on if there are no_preroll
     * elements in the pipeline or not */
    if (have_no_preroll)
      ret = GST_STATE_CHANGE_NO_PREROLL;
    else
      ret = GST_STATE_CHANGE_SUCCESS;

    bin_handle_async_done (bin, ret, FALSE, GST_CLOCK_TIME_NONE);
  } else {
    GST_DEBUG_OBJECT (bin,
        "recalc state preroll: %d, other async: %d, this async %d",
        have_no_preroll, other_async, this_async);

    if (have_no_preroll) {
      ret = GST_STATE_CHANGE_NO_PREROLL;
    } else if (other_async) {
      /* there are other async elements and we were not doing an async state
       * change, change our pending state and go async */
      if (GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) {
        GST_STATE_NEXT (bin) = GST_STATE (bin);
        GST_STATE_PENDING (bin) = GST_STATE (bin);
      }
      ret = GST_STATE_CHANGE_ASYNC;
    }
    GST_STATE_RETURN (bin) = ret;
  }
no_state_recalc:
  /* clear bus */
  gst_element_set_bus (element, NULL);
  /* Clear the clock we provided to the element */
  gst_element_set_clock (element, NULL);
  GST_OBJECT_UNLOCK (bin);

  if (clock_message)
    gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);

  /* unlink all linked pads */
  it = gst_element_iterate_pads (element);
  gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
  gst_iterator_free (it);

  GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
      elem_name);

  g_signal_emit (bin, gst_bin_signals[ELEMENT_REMOVED], 0, element);
  gst_child_proxy_child_removed ((GstChildProxy *) bin, (GObject *) element,
      elem_name);

  g_free (elem_name);
  /* element is really out of our control now */
  gst_object_unref (element);

  return TRUE;

  /* ERROR handling */
not_in_bin:
  {
    g_warning ("Element '%s' is not in bin '%s'", elem_name,
        GST_ELEMENT_NAME (bin));
    GST_OBJECT_UNLOCK (element);
    GST_OBJECT_UNLOCK (bin);
    g_free (elem_name);
    return FALSE;
  }
}

/**
 * gst_bin_remove:
 * @bin: a #GstBin
 * @element: (transfer none): the #GstElement to remove
 *
 * Removes the element from the bin, unparenting it as well.
 * Unparenting the element means that the element will be dereferenced,
 * so if the bin holds the only reference to the element, the element
 * will be freed in the process of removing it from the bin.  If you
 * want the element to still exist after removing, you need to call
 * gst_object_ref() before removing it from the bin.
 *
 * If the element's pads are linked to other pads, the pads will be unlinked
 * before the element is removed from the bin.
 *
 * MT safe.
 *
 * Returns: TRUE if the element could be removed, FALSE if
 * the bin does not want to remove the element.
 */
gboolean
gst_bin_remove (GstBin * bin, GstElement * element)
{
  GstBinClass *bclass;
  gboolean result;

  g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);

  bclass = GST_BIN_GET_CLASS (bin);

  if (G_UNLIKELY (bclass->remove_element == NULL))
    goto no_function;

  GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
      GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));

  result = bclass->remove_element (bin, element);

  return result;

  /* ERROR handling */
no_function:
  {
    g_warning ("removing elements from bin '%s' is not supported",
        GST_ELEMENT_NAME (bin));
    return FALSE;
  }
}

/**
 * gst_bin_iterate_elements:
 * @bin: a #GstBin
 *
 * Gets an iterator for the elements in this bin.
 *
 * Each element yielded by the iterator will have its refcount increased, so
 * unref after use.
 *
 * MT safe.  Caller owns returned value.
 *
 * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
 */
GstIterator *
gst_bin_iterate_elements (GstBin * bin)
{
  GstIterator *result;

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);

  GST_OBJECT_LOCK (bin);
  result = gst_iterator_new_list (GST_TYPE_ELEMENT,
      GST_OBJECT_GET_LOCK (bin),
      &bin->children_cookie, &bin->children, (GObject *) bin, NULL);
  GST_OBJECT_UNLOCK (bin);

  return result;
}

static GstIteratorItem
iterate_child_recurse (GstIterator * it, const GValue * item)
{
  GstElement *child = g_value_get_object (item);

  if (GST_IS_BIN (child)) {
    GstIterator *other = gst_bin_iterate_recurse (GST_BIN_CAST (child));

    gst_iterator_push (it, other);
  }
  return GST_ITERATOR_ITEM_PASS;
}

/**
 * gst_bin_iterate_recurse:
 * @bin: a #GstBin
 *
 * Gets an iterator for the elements in this bin.
 * This iterator recurses into GstBin children.
 *
 * Each element yielded by the iterator will have its refcount increased, so
 * unref after use.
 *
 * MT safe.  Caller owns returned value.
 *
 * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
 */
GstIterator *
gst_bin_iterate_recurse (GstBin * bin)
{
  GstIterator *result;

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);

  GST_OBJECT_LOCK (bin);
  result = gst_iterator_new_list (GST_TYPE_ELEMENT,
      GST_OBJECT_GET_LOCK (bin),
      &bin->children_cookie,
      &bin->children,
      (GObject *) bin, (GstIteratorItemFunction) iterate_child_recurse);
  GST_OBJECT_UNLOCK (bin);

  return result;
}

/* returns 0 when TRUE because this is a GCompareFunc */
/* MT safe */
static gint
bin_element_is_sink (GstElement * child, GstBin * bin)
{
  gboolean is_sink;

  /* we lock the child here for the remainder of the function to
   * get its name and flag safely. */
  GST_OBJECT_LOCK (child);
  is_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SINK);

  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
      "child %s %s sink", GST_OBJECT_NAME (child), is_sink ? "is" : "is not");

  GST_OBJECT_UNLOCK (child);
  return is_sink ? 0 : 1;
}

static gint
sink_iterator_filter (const GValue * vchild, GValue * vbin)
{
  GstBin *bin = g_value_get_object (vbin);
  GstElement *child = g_value_get_object (vchild);

  return (bin_element_is_sink (child, bin));
}

/**
 * gst_bin_iterate_sinks:
 * @bin: a #GstBin
 *
 * Gets an iterator for all elements in the bin that have the
 * #GST_ELEMENT_FLAG_SINK flag set.
 *
 * Each element yielded by the iterator will have its refcount increased, so
 * unref after use.
 *
 * MT safe.  Caller owns returned value.
 *
 * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
 */
GstIterator *
gst_bin_iterate_sinks (GstBin * bin)
{
  GstIterator *children;
  GstIterator *result;
  GValue vbin = { 0, };

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);

  g_value_init (&vbin, GST_TYPE_BIN);
  g_value_set_object (&vbin, bin);

  children = gst_bin_iterate_elements (bin);
  result = gst_iterator_filter (children,
      (GCompareFunc) sink_iterator_filter, &vbin);

  g_value_unset (&vbin);

  return result;
}

/* returns 0 when TRUE because this is a GCompareFunc */
/* MT safe */
static gint
bin_element_is_src (GstElement * child, GstBin * bin)
{
  gboolean is_src;

  /* we lock the child here for the remainder of the function to
   * get its name and other info safely. */
  GST_OBJECT_LOCK (child);
  is_src = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SOURCE);

  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
      "child %s %s src", GST_OBJECT_NAME (child), is_src ? "is" : "is not");

  GST_OBJECT_UNLOCK (child);
  return is_src ? 0 : 1;
}

static gint
src_iterator_filter (const GValue * vchild, GValue * vbin)
{
  GstBin *bin = g_value_get_object (vbin);
  GstElement *child = g_value_get_object (vchild);

  return (bin_element_is_src (child, bin));
}

/**
 * gst_bin_iterate_sources:
 * @bin: a #GstBin
 *
 * Gets an iterator for all elements in the bin that have the
 * #GST_ELEMENT_FLAG_SOURCE flag set.
 *
 * Each element yielded by the iterator will have its refcount increased, so
 * unref after use.
 *
 * MT safe.  Caller owns returned value.
 *
 * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
 */
GstIterator *
gst_bin_iterate_sources (GstBin * bin)
{
  GstIterator *children;
  GstIterator *result;
  GValue vbin = { 0, };

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);

  g_value_init (&vbin, GST_TYPE_BIN);
  g_value_set_object (&vbin, bin);

  children = gst_bin_iterate_elements (bin);
  result = gst_iterator_filter (children,
      (GCompareFunc) src_iterator_filter, &vbin);

  g_value_unset (&vbin);

  return result;
}

/*
 * MT safe
 */
static GstStateChangeReturn
gst_bin_get_state_func (GstElement * element, GstState * state,
    GstState * pending, GstClockTime timeout)
{
  GstStateChangeReturn ret;

  GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");

  ret =
      GST_ELEMENT_CLASS (parent_class)->get_state (element, state, pending,
      timeout);

  return ret;
}

/***********************************************
 * Topologically sorted iterator
 * see http://en.wikipedia.org/wiki/Topological_sorting
 *
 * For each element in the graph, an entry is kept in a HashTable
 * with its number of srcpad connections (degree).
 * We then change state of all elements without dependencies
 * (degree 0) and decrement the degree of all elements connected
 * on the sinkpads. When an element reaches degree 0, its state is
 * changed next.
 * When all elements are handled the algorithm stops.
 */
typedef struct _GstBinSortIterator
{
  GstIterator it;
  GQueue queue;                 /* elements queued for state change */
  GstBin *bin;                  /* bin we iterate */
  gint mode;                    /* adding or removing dependency */
  GstElement *best;             /* next element with least dependencies */
  gint best_deg;                /* best degree */
  GHashTable *hash;             /* hashtable with element dependencies */
  gboolean dirty;               /* we detected structure change */
} GstBinSortIterator;

static void
gst_bin_sort_iterator_copy (const GstBinSortIterator * it,
    GstBinSortIterator * copy)
{
  GHashTableIter iter;
  gpointer key, value;

  copy->queue = it->queue;
  g_queue_foreach (&copy->queue, (GFunc) gst_object_ref, NULL);

  copy->bin = gst_object_ref (it->bin);
  if (it->best)
    copy->best = gst_object_ref (it->best);

  copy->hash = g_hash_table_new (NULL, NULL);
  g_hash_table_iter_init (&iter, it->hash);
  while (g_hash_table_iter_next (&iter, &key, &value))
    g_hash_table_insert (copy->hash, key, value);
}

/* we add and subtract 1 to make sure we don't confuse NULL and 0 */
#define HASH_SET_DEGREE(bit, elem, deg) \
    g_hash_table_replace (bit->hash, elem, GINT_TO_POINTER(deg+1))
#define HASH_GET_DEGREE(bit, elem) \
    (GPOINTER_TO_INT(g_hash_table_lookup (bit->hash, elem))-1)

/* add element to queue of next elements in the iterator.
 * We push at the tail to give higher priority elements a
 * chance first */
static void
add_to_queue (GstBinSortIterator * bit, GstElement * element)
{
  GST_DEBUG_OBJECT (bit->bin, "adding '%s' to queue",
      GST_ELEMENT_NAME (element));
  gst_object_ref (element);
  g_queue_push_tail (&bit->queue, element);
  HASH_SET_DEGREE (bit, element, -1);
}

static void
remove_from_queue (GstBinSortIterator * bit, GstElement * element)
{
  GList *find;

  if ((find = g_queue_find (&bit->queue, element))) {
    GST_DEBUG_OBJECT (bit->bin, "removing '%s' from queue",
        GST_ELEMENT_NAME (element));

    g_queue_delete_link (&bit->queue, find);
    gst_object_unref (element);
  } else {
    GST_DEBUG_OBJECT (bit->bin, "unable to remove '%s' from queue",
        GST_ELEMENT_NAME (element));
  }
}

/* clear the queue, unref all objects as we took a ref when
 * we added them to the queue */
static void
clear_queue (GQueue * queue)
{
  gpointer p;

  while ((p = g_queue_pop_head (queue)))
    gst_object_unref (p);
}

/* set all degrees to 0. Elements marked as a sink are
 * added to the queue immediately. Since we only look at the SINK flag of the
 * element, it is possible that we add non-sinks to the queue. These will be
 * removed from the queue again when we can prove that it provides data for some
 * other element. */
static void
reset_degree (GstElement * element, GstBinSortIterator * bit)
{
  gboolean is_sink;

  /* sinks are added right away */
  GST_OBJECT_LOCK (element);
  is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
  GST_OBJECT_UNLOCK (element);

  if (is_sink) {
    add_to_queue (bit, element);
  } else {
    /* others are marked with 0 and handled when sinks are done */
    HASH_SET_DEGREE (bit, element, 0);
  }
}

/* adjust the degree of all elements connected to the given
 * element. If a degree of an element drops to 0, it is
 * added to the queue of elements to schedule next.
 *
 * We have to make sure not to cross the bin boundary this element
 * belongs to.
 */
static void
update_degree (GstElement * element, GstBinSortIterator * bit)
{
  gboolean linked = FALSE;

  GST_OBJECT_LOCK (element);
  /* don't touch degree if element has no sinkpads */
  if (element->numsinkpads != 0) {
    /* loop over all sinkpads, decrement degree for all connected
     * elements in this bin */
    GList *pads;

    for (pads = element->sinkpads; pads; pads = g_list_next (pads)) {
      GstPad *pad, *peer;

      pad = GST_PAD_CAST (pads->data);

      /* we're iterating over the sinkpads, check if it's busy in a link/unlink */
      if (G_UNLIKELY (find_message (bit->bin, GST_OBJECT_CAST (pad),
                  GST_MESSAGE_STRUCTURE_CHANGE))) {
        /* mark the iterator as dirty because we won't be updating the degree
         * of the peer parent now. This would result in the 'loop detected'
         * later on because the peer parent element could become the best next
         * element with a degree > 0. We will simply continue our state
         * changes and we'll eventually resync when the unlink completed and
         * the iterator cookie is updated. */
        bit->dirty = TRUE;
        continue;
      }

      if ((peer = gst_pad_get_peer (pad))) {
        GstElement *peer_element;

        if ((peer_element = gst_pad_get_parent_element (peer))) {
          GST_OBJECT_LOCK (peer_element);
          /* check that we don't go outside of this bin */
          if (GST_OBJECT_CAST (peer_element)->parent ==
              GST_OBJECT_CAST (bit->bin)) {
            gint old_deg, new_deg;

            old_deg = HASH_GET_DEGREE (bit, peer_element);

            /* check to see if we added an element as sink that was not really a
             * sink because it was connected to some other element. */
            if (old_deg == -1) {
              remove_from_queue (bit, peer_element);
              old_deg = 0;
            }
            new_deg = old_deg + bit->mode;

            GST_DEBUG_OBJECT (bit->bin,
                "change element %s, degree %d->%d, linked to %s",
                GST_ELEMENT_NAME (peer_element), old_deg, new_deg,
                GST_ELEMENT_NAME (element));

            /* update degree, it is possible that an element was in 0 and
             * reaches -1 here. This would mean that the element had no sinkpads
             * but became linked while the state change was happening. We will
             * resync on this with the structure change message. */
            if (new_deg == 0) {
              /* degree hit 0, add to queue */
              add_to_queue (bit, peer_element);
            } else {
              HASH_SET_DEGREE (bit, peer_element, new_deg);
            }
            linked = TRUE;
          }
          GST_OBJECT_UNLOCK (peer_element);
          gst_object_unref (peer_element);
        }
        gst_object_unref (peer);
      }
    }
  }
  if (!linked) {
    GST_DEBUG_OBJECT (bit->bin, "element %s not linked on any sinkpads",
        GST_ELEMENT_NAME (element));
  }
  GST_OBJECT_UNLOCK (element);
}

/* find the next best element not handled yet. This is the one
 * with the lowest non-negative degree */
static void
find_element (GstElement * element, GstBinSortIterator * bit)
{
  gint degree;

  /* element is already handled */
  if ((degree = HASH_GET_DEGREE (bit, element)) < 0)
    return;

  /* first element or element with smaller degree */
  if (bit->best == NULL || bit->best_deg > degree) {
    bit->best = element;
    bit->best_deg = degree;
  }
}

/* get next element in iterator. the returned element has the
 * refcount increased */
static GstIteratorResult
gst_bin_sort_iterator_next (GstBinSortIterator * bit, GValue * result)
{
  GstElement *best;
  GstBin *bin = bit->bin;

  /* empty queue, we have to find a next best element */
  if (g_queue_is_empty (&bit->queue)) {
    bit->best = NULL;
    bit->best_deg = G_MAXINT;
    g_list_foreach (bin->children, (GFunc) find_element, bit);
    if ((best = bit->best)) {
      /* when we detected an unlink, don't warn because our degrees might be
       * screwed up. We will resync later */
      if (bit->best_deg != 0 && !bit->dirty) {
        /* we don't fail on this one yet */
        GST_WARNING_OBJECT (bin, "loop dected in graph");
        g_warning ("loop detected in the graph of bin '%s'!!",
            GST_ELEMENT_NAME (bin));
      }
      /* best unhandled element, schedule as next element */
      GST_DEBUG_OBJECT (bin, "queue empty, next best: %s",
          GST_ELEMENT_NAME (best));
      HASH_SET_DEGREE (bit, best, -1);
      g_value_set_object (result, best);
    } else {
      GST_DEBUG_OBJECT (bin, "queue empty, elements exhausted");
      /* no more unhandled elements, we are done */
      return GST_ITERATOR_DONE;
    }
  } else {
    /* everything added to the queue got reffed */
    best = g_queue_pop_head (&bit->queue);
    g_value_set_object (result, best);
    gst_object_unref (best);
  }

  GST_DEBUG_OBJECT (bin, "queue head gives %s", GST_ELEMENT_NAME (best));
  /* update degrees of linked elements */
  update_degree (best, bit);

  return GST_ITERATOR_OK;
}

/* clear queues, recalculate the degrees and restart. */
static void
gst_bin_sort_iterator_resync (GstBinSortIterator * bit)
{
  GstBin *bin = bit->bin;

  GST_DEBUG_OBJECT (bin, "resync");
  bit->dirty = FALSE;
  clear_queue (&bit->queue);
  /* reset degrees */
  g_list_foreach (bin->children, (GFunc) reset_degree, bit);
  /* calc degrees, incrementing */
  bit->mode = 1;
  g_list_foreach (bin->children, (GFunc) update_degree, bit);
  /* for the rest of the function we decrement the degrees */
  bit->mode = -1;
}

/* clear queues, unref bin and free iterator. */
static void
gst_bin_sort_iterator_free (GstBinSortIterator * bit)
{
  GstBin *bin = bit->bin;

  GST_DEBUG_OBJECT (bin, "free");
  clear_queue (&bit->queue);
  g_hash_table_destroy (bit->hash);
  gst_object_unref (bin);
}

/* should be called with the bin LOCK held */
static GstIterator *
gst_bin_sort_iterator_new (GstBin * bin)
{
  GstBinSortIterator *result;

  /* we don't need an ItemFunction because we ref the items in the _next
   * method already */
  result = (GstBinSortIterator *)
      gst_iterator_new (sizeof (GstBinSortIterator),
      GST_TYPE_ELEMENT,
      GST_OBJECT_GET_LOCK (bin),
      &bin->priv->structure_cookie,
      (GstIteratorCopyFunction) gst_bin_sort_iterator_copy,
      (GstIteratorNextFunction) gst_bin_sort_iterator_next,
      (GstIteratorItemFunction) NULL,
      (GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
      (GstIteratorFreeFunction) gst_bin_sort_iterator_free);
  g_queue_init (&result->queue);
  result->hash = g_hash_table_new (NULL, NULL);
  gst_object_ref (bin);
  result->bin = bin;
  gst_bin_sort_iterator_resync (result);

  return (GstIterator *) result;
}

/**
 * gst_bin_iterate_sorted:
 * @bin: a #GstBin
 *
 * Gets an iterator for the elements in this bin in topologically
 * sorted order. This means that the elements are returned from
 * the most downstream elements (sinks) to the sources.
 *
 * This function is used internally to perform the state changes
 * of the bin elements and for clock selection.
 *
 * Each element yielded by the iterator will have its refcount increased, so
 * unref after use.
 *
 * MT safe.  Caller owns returned value.
 *
 * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
 */
GstIterator *
gst_bin_iterate_sorted (GstBin * bin)
{
  GstIterator *result;

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);

  GST_OBJECT_LOCK (bin);
  result = gst_bin_sort_iterator_new (bin);
  GST_OBJECT_UNLOCK (bin);

  return result;
}

static GstStateChangeReturn
gst_bin_element_set_state (GstBin * bin, GstElement * element,
    GstClockTime base_time, GstClockTime start_time, GstState current,
    GstState next)
{
  GstStateChangeReturn ret;
  GstState child_current, child_pending;
  gboolean locked;
  GList *found;

  GST_STATE_LOCK (element);

  GST_OBJECT_LOCK (element);
  /* set base_time and start time on child */
  GST_ELEMENT_START_TIME (element) = start_time;
  element->base_time = base_time;
  /* peel off the locked flag */
  locked = GST_ELEMENT_IS_LOCKED_STATE (element);
  /* 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 */
  if (G_UNLIKELY (locked))
    goto locked;

  /* if the element was no preroll, just start changing the state regardless
   * if it had async elements (in the case of a bin) because they won't preroll
   * anyway. */
  if (G_UNLIKELY (ret == GST_STATE_CHANGE_NO_PREROLL)) {
    GST_DEBUG_OBJECT (element, "element is NO_PREROLL, ignore async elements");
    goto no_preroll;
  }

  GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
      "current %s pending %s, desired next %s",
      gst_element_state_get_name (child_current),
      gst_element_state_get_name (child_pending),
      gst_element_state_get_name (next));

  /* always recurse into bins so that we can set the base time */
  if (GST_IS_BIN (element))
    goto do_state;

  /* Try not to change the state of elements that are already in the state we're
   * going to */
  if (child_current == next && child_pending == GST_STATE_VOID_PENDING) {
    /* child is already at the requested state, return previous return. Note that
     * if the child has a pending state to next, we will still call the
     * set_state function */
    goto unneeded;
  } else if (next > current) {
    /* upward state change */
    if (child_pending == GST_STATE_VOID_PENDING) {
      /* .. and the child is not busy doing anything */
      if (child_current > next) {
        /* .. and is already past the requested state, assume it got there
         * without error */
        ret = GST_STATE_CHANGE_SUCCESS;
        goto unneeded;
      }
    } else if (child_pending > child_current) {
      /* .. and the child is busy going upwards */
      if (child_current >= next) {
        /* .. and is already past the requested state, assume it got there
         * without error */
        ret = GST_STATE_CHANGE_SUCCESS;
        goto unneeded;
      }
    } else {
      /* .. and the child is busy going downwards */
      if (child_current > next) {
        /* .. and is already past the requested state, assume it got there
         * without error */
        ret = GST_STATE_CHANGE_SUCCESS;
        goto unneeded;
      }
    }
  } else if (next < current) {
    /* downward state change */
    if (child_pending == GST_STATE_VOID_PENDING) {
      /* .. and the child is not busy doing anything */
      if (child_current < next) {
        /* .. and is already past the requested state, assume it got there
         * without error */
        ret = GST_STATE_CHANGE_SUCCESS;
        goto unneeded;
      }
    } else if (child_pending < child_current) {
      /* .. and the child is busy going downwards */
      if (child_current <= next) {
        /* .. and is already past the requested state, assume it got there
         * without error */
        ret = GST_STATE_CHANGE_SUCCESS;
        goto unneeded;
      }
    } else {
      /* .. and the child is busy going upwards */
      if (child_current < next) {
        /* .. and is already past the requested state, assume it got there
         * without error */
        ret = GST_STATE_CHANGE_SUCCESS;
        goto unneeded;
      }
    }
  }

do_state:
  GST_OBJECT_LOCK (bin);
  /* 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 =
          find_message (bin, GST_OBJECT_CAST (element),
              GST_MESSAGE_ASYNC_START))) {
#ifndef GST_DISABLE_GST_DEBUG
    GstMessage *message = GST_MESSAGE_CAST (found->data);

    GST_DEBUG_OBJECT (element, "element message %p, %s async busy",
        message, GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)));
#endif
    /* only wait for upward state changes */
    if (next > current) {
      /* We found an async element check if we can force its state to change or
       * if we have to wait for it to preroll. */
      goto was_busy;
    }
  }
  GST_OBJECT_UNLOCK (bin);

no_preroll:
  GST_DEBUG_OBJECT (bin,
      "setting element %s to %s, base_time %" GST_TIME_FORMAT,
      GST_ELEMENT_NAME (element), gst_element_state_get_name (next),
      GST_TIME_ARGS (base_time));

  /* change state */
  ret = gst_element_set_state (element, next);

  GST_STATE_UNLOCK (element);

  return ret;

locked:
  {
    GST_DEBUG_OBJECT (element,
        "element is locked, return previous return %s",
        gst_element_state_change_return_get_name (ret));
    GST_STATE_UNLOCK (element);
    return ret;
  }
unneeded:
  {
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
        "skipping transition from %s to  %s",
        gst_element_state_get_name (child_current),
        gst_element_state_get_name (next));
    GST_STATE_UNLOCK (element);
    return ret;
  }
was_busy:
  {
    GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
    GST_OBJECT_UNLOCK (bin);
    GST_STATE_UNLOCK (element);
    return GST_STATE_CHANGE_ASYNC;
  }
}

/* gst_iterator_fold functions for pads_activate
 * Stop the iterator if activating one pad failed. */
static gboolean
activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
{
  GstPad *pad = g_value_get_object (vpad);
  gboolean cont = TRUE;

  if (!(cont = gst_pad_set_active (pad, *active)))
    g_value_set_boolean (ret, FALSE);

  return cont;
}

/* returns false on error or early cutout of the fold, true if all
 * pads in @iter were (de)activated successfully. */
static gboolean
iterator_activate_fold_with_resync (GstIterator * iter, gpointer user_data)
{
  GstIteratorResult ires;
  GValue ret = { 0 };

  /* no need to unset this later, it's just a boolean */
  g_value_init (&ret, G_TYPE_BOOLEAN);
  g_value_set_boolean (&ret, TRUE);

  while (1) {
    ires = gst_iterator_fold (iter, (GstIteratorFoldFunction) activate_pads,
        &ret, user_data);
    switch (ires) {
      case GST_ITERATOR_RESYNC:
        /* need to reset the result again */
        g_value_set_boolean (&ret, TRUE);
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_DONE:
        /* all pads iterated, return collected value */
        goto done;
      default:
        /* iterator returned _ERROR or premature end with _OK,
         * mark an error and exit */
        g_value_set_boolean (&ret, FALSE);
        goto done;
    }
  }
done:
  /* return collected value */
  return g_value_get_boolean (&ret);
}

/* is called with STATE_LOCK
 */
static gboolean
gst_bin_src_pads_activate (GstBin * bin, gboolean active)
{
  GstIterator *iter;
  gboolean fold_ok;

  GST_DEBUG_OBJECT (bin, "%s pads", active ? "activate" : "deactivate");

  iter = gst_element_iterate_src_pads ((GstElement *) bin);
  fold_ok = iterator_activate_fold_with_resync (iter, &active);
  gst_iterator_free (iter);
  if (G_UNLIKELY (!fold_ok))
    goto failed;

  GST_DEBUG_OBJECT (bin, "pad %sactivation successful", active ? "" : "de");

  return TRUE;

  /* ERRORS */
failed:
  {
    GST_DEBUG_OBJECT (bin, "pad %sactivation failed", active ? "" : "de");
    return FALSE;
  }
}

/**
 * gst_bin_recalculate_latency:
 * @bin: a #GstBin
 *
 * Query @bin for the current latency using and reconfigures this latency to all the
 * elements with a LATENCY event.
 *
 * This method is typically called on the pipeline when a #GST_MESSAGE_LATENCY
 * is posted on the bus.
 *
 * This function simply emits the 'do-latency' signal so any custom latency
 * calculations will be performed.
 *
 * Returns: %TRUE if the latency could be queried and reconfigured.
 */
gboolean
gst_bin_recalculate_latency (GstBin * bin)
{
  gboolean res;

  g_signal_emit (bin, gst_bin_signals[DO_LATENCY], 0, &res);
  GST_DEBUG_OBJECT (bin, "latency returned %d", res);

  return res;
}

static gboolean
gst_bin_do_latency_func (GstBin * bin)
{
  GstQuery *query;
  GstElement *element;
  GstClockTime min_latency, max_latency;
  gboolean res;

  g_return_val_if_fail (GST_IS_BIN (bin), FALSE);

  element = GST_ELEMENT_CAST (bin);

  GST_DEBUG_OBJECT (element, "querying latency");

  query = gst_query_new_latency ();
  if ((res = gst_element_query (element, query))) {
    gboolean live;

    gst_query_parse_latency (query, &live, &min_latency, &max_latency);

    GST_DEBUG_OBJECT (element,
        "got min latency %" GST_TIME_FORMAT ", max latency %"
        GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
        GST_TIME_ARGS (max_latency), live);

    if (max_latency < min_latency) {
      /* this is an impossible situation, some parts of the pipeline might not
       * work correctly. We post a warning for now. */
      GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
          ("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
              GST_TIME_FORMAT ". Add queues or other buffering elements.",
              GST_TIME_ARGS (max_latency), GST_TIME_ARGS (min_latency)));
    }

    /* configure latency on elements */
    res = gst_element_send_event (element, gst_event_new_latency (min_latency));
    if (res) {
      GST_INFO_OBJECT (element, "configured latency of %" GST_TIME_FORMAT,
          GST_TIME_ARGS (min_latency));
    } else {
      GST_WARNING_OBJECT (element,
          "did not really configure latency of %" GST_TIME_FORMAT,
          GST_TIME_ARGS (min_latency));
    }
  } else {
    /* this is not a real problem, we just don't configure any latency. */
    GST_WARNING_OBJECT (element, "failed to query latency");
  }
  gst_query_unref (query);

  return res;
}

static void
gst_bin_state_changed (GstElement * element, GstState oldstate,
    GstState newstate, GstState pending)
{
  GstElementClass *pklass = (GstElementClass *) parent_class;

  if (newstate == GST_STATE_PLAYING && pending == GST_STATE_VOID_PENDING)
    bin_do_eos (GST_BIN_CAST (element));

  if (pklass->state_changed)
    pklass->state_changed (element, oldstate, newstate, pending);
}

static GstStateChangeReturn
gst_bin_change_state_func (GstElement * element, GstStateChange transition)
{
  GstBin *bin;
  GstStateChangeReturn ret;
  GstState current, next;
  gboolean have_async;
  gboolean have_no_preroll;
  GstClockTime base_time, start_time;
  GstIterator *it;
  gboolean done;
  GValue data = { 0, };

  /* we don't need to take the STATE_LOCK, it is already taken */
  current = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
  next = (GstState) GST_STATE_TRANSITION_NEXT (transition);

  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
      "changing state of children from %s to %s",
      gst_element_state_get_name (current), gst_element_state_get_name (next));

  bin = GST_BIN_CAST (element);

  switch (next) {
    case GST_STATE_PLAYING:
    {
      gboolean toplevel;

      GST_OBJECT_LOCK (bin);
      toplevel = BIN_IS_TOPLEVEL (bin);
      GST_OBJECT_UNLOCK (bin);

      if (toplevel)
        gst_bin_recalculate_latency (bin);
      break;
    }
    case GST_STATE_PAUSED:
      /* Clear EOS list on next PAUSED */
      GST_OBJECT_LOCK (bin);
      GST_DEBUG_OBJECT (element, "clearing EOS elements");
      bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
      bin->priv->posted_eos = FALSE;
      if (current == GST_STATE_READY)
        bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START);
      GST_OBJECT_UNLOCK (bin);
      if (current == GST_STATE_READY)
        if (!(gst_bin_src_pads_activate (bin, TRUE)))
          goto activate_failure;
      break;
    case GST_STATE_READY:
      /* Clear message list on next READY */
      GST_OBJECT_LOCK (bin);
      GST_DEBUG_OBJECT (element, "clearing all cached messages");
      bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
      GST_OBJECT_UNLOCK (bin);
      if (current == GST_STATE_PAUSED)
        if (!(gst_bin_src_pads_activate (bin, FALSE)))
          goto activate_failure;
      break;
    case GST_STATE_NULL:
      if (current == GST_STATE_READY)
        if (!(gst_bin_src_pads_activate (bin, FALSE)))
          goto activate_failure;
      break;
    default:
      break;
  }

  /* this flag is used to make the async state changes return immediately. We
   * don't want them to interfere with this state change */
  GST_OBJECT_LOCK (bin);
  bin->polling = TRUE;
  GST_OBJECT_UNLOCK (bin);

  /* iterate in state change order */
  it = gst_bin_iterate_sorted (bin);

  /* mark if we've seen an ASYNC element in the bin when we did a state change.
   * Note how we don't reset this value when a resync happens, the reason being
   * that the async element posted ASYNC_START and we want to post ASYNC_DONE
   * even after a resync when the async element is gone */
  have_async = FALSE;

restart:
  /* take base_time */
  base_time = gst_element_get_base_time (element);
  start_time = gst_element_get_start_time (element);

  have_no_preroll = FALSE;

  done = FALSE;
  while (!done) {
    switch (gst_iterator_next (it, &data)) {
      case GST_ITERATOR_OK:
      {
        GstElement *child;

        child = g_value_get_object (&data);

        /* set state and base_time now */
        ret = gst_bin_element_set_state (bin, child, base_time, start_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:{
            GstObject *parent;

            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));

            /* Only fail if the child is still inside
             * this bin. It might've been removed already
             * because of the error by the bin subclass
             * to ignore the error.  */
            parent = gst_object_get_parent (GST_OBJECT_CAST (child));
            if (parent == GST_OBJECT_CAST (element)) {
              /* element is still in bin, really error now */
              gst_object_unref (parent);
              goto done;
            }
            /* child removed from bin, let the resync code redo the state
             * change */
            GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
                "child '%s' was removed from the bin",
                GST_ELEMENT_NAME (child));

            if (parent)
              gst_object_unref (parent);

            break;
          }
          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;
        }
        g_value_reset (&data);
        break;
      }
      case GST_ITERATOR_RESYNC:
        GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "iterator doing resync");
        gst_iterator_resync (it);
        goto restart;
      default:
      case GST_ITERATOR_DONE:
        GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "iterator done");
        done = TRUE;
        break;
    }
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (G_UNLIKELY (ret == GST_STATE_CHANGE_FAILURE))
    goto done;

  if (have_no_preroll) {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
        "we have NO_PREROLL elements %s -> NO_PREROLL",
        gst_element_state_change_return_get_name (ret));
    ret = GST_STATE_CHANGE_NO_PREROLL;
  } else if (have_async) {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
        "we have ASYNC elements %s -> ASYNC",
        gst_element_state_change_return_get_name (ret));
    ret = GST_STATE_CHANGE_ASYNC;
  }

done:
  g_value_unset (&data);
  gst_iterator_free (it);

  GST_OBJECT_LOCK (bin);
  bin->polling = FALSE;
  /* it's possible that we did not get ASYNC from the children while the bin is
   * simulating ASYNC behaviour by posting an ASYNC_DONE message on the bus with
   * itself as the source. In that case we still want to check if the state
   * change completed. */
  if (ret != GST_STATE_CHANGE_ASYNC && !bin->priv->pending_async_done) {
    /* no element returned ASYNC and there are no pending async_done messages,
     * we can just complete. */
    GST_DEBUG_OBJECT (bin, "no async elements");
    goto state_end;
  }
  /* when we get here an ASYNC element was found */
  if (GST_STATE_TARGET (bin) <= GST_STATE_READY) {
    /* we ignore ASYNC state changes when we go to READY or NULL */
    GST_DEBUG_OBJECT (bin, "target state %s <= READY",
        gst_element_state_get_name (GST_STATE_TARGET (bin)));
    goto state_end;
  }

  GST_DEBUG_OBJECT (bin, "check async elements");
  /* check if all elements managed to commit their state already */
  if (!find_message (bin, NULL, GST_MESSAGE_ASYNC_START)) {
    /* nothing found, remove all old ASYNC_DONE messages. This can happen when
     * all the elements commited their state while we were doing the state
     * change. We will still return ASYNC for consistency but we commit the
     * state already so that a _get_state() will return immediately. */
    bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);

    GST_DEBUG_OBJECT (bin, "async elements commited");
    bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, FALSE,
        GST_CLOCK_TIME_NONE);
  }

state_end:
  bin->priv->pending_async_done = FALSE;
  GST_OBJECT_UNLOCK (bin);

  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
      "done changing bin's state from %s to %s, now in %s, ret %s",
      gst_element_state_get_name (current),
      gst_element_state_get_name (next),
      gst_element_state_get_name (GST_STATE (element)),
      gst_element_state_change_return_get_name (ret));

  return ret;

  /* ERRORS */
activate_failure:
  {
    GST_CAT_WARNING_OBJECT (GST_CAT_STATES, element,
        "failure (de)activating src pads");
    return GST_STATE_CHANGE_FAILURE;
  }
}

/*
 * This function is a utility event handler for seek events.
 * It will send the event to all sinks or sources depending on the
 * event-direction.
 *
 * Applications are free to override this behaviour and
 * implement their own seek handler, but this will work for
 * pretty much all cases in practice.
 */
static gboolean
gst_bin_send_event (GstElement * element, GstEvent * event)
{
  GstBin *bin = GST_BIN_CAST (element);
  GstIterator *iter;
  gboolean res = TRUE;
  gboolean done = FALSE;
  GValue data = { 0, };

  if (GST_EVENT_IS_DOWNSTREAM (event)) {
    iter = gst_bin_iterate_sources (bin);
    GST_DEBUG_OBJECT (bin, "Sending %s event to src children",
        GST_EVENT_TYPE_NAME (event));
  } else {
    iter = gst_bin_iterate_sinks (bin);
    GST_DEBUG_OBJECT (bin, "Sending %s event to sink children",
        GST_EVENT_TYPE_NAME (event));
  }

  while (!done) {
    switch (gst_iterator_next (iter, &data)) {
      case GST_ITERATOR_OK:
      {
        GstElement *child = g_value_get_object (&data);;

        gst_event_ref (event);
        res &= gst_element_send_event (child, event);
        GST_LOG_OBJECT (child, "After handling %s event: %d",
            GST_EVENT_TYPE_NAME (event), res);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        res = TRUE;
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_ERROR:
        g_assert_not_reached ();
        break;
    }
  }
  g_value_unset (&data);
  gst_iterator_free (iter);
  gst_event_unref (event);

  return res;
}

/* this is the function called by the threadpool. When async elements commit
 * their state, this function will attempt to bring the bin to the next state.
 */
static void
gst_bin_continue_func (BinContinueData * data)
{
  GstBin *bin;
  GstState current, next, pending;
  GstStateChange transition;

  bin = data->bin;
  pending = data->pending;

  GST_DEBUG_OBJECT (bin, "waiting for state lock");
  GST_STATE_LOCK (bin);

  GST_DEBUG_OBJECT (bin, "doing state continue");
  GST_OBJECT_LOCK (bin);

  /* if a new state change happened after this thread was scheduled, we return
   * immediately. */
  if (data->cookie != GST_ELEMENT_CAST (bin)->state_cookie)
    goto interrupted;

  current = GST_STATE (bin);
  next = GST_STATE_GET_NEXT (current, pending);
  transition = (GstStateChange) GST_STATE_TRANSITION (current, next);

  GST_STATE_NEXT (bin) = next;
  GST_STATE_PENDING (bin) = pending;
  /* mark busy */
  GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
  GST_OBJECT_UNLOCK (bin);

  GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
      "continue state change %s to %s, final %s",
      gst_element_state_get_name (current),
      gst_element_state_get_name (next), gst_element_state_get_name (pending));

  gst_element_change_state (GST_ELEMENT_CAST (bin), transition);

  GST_STATE_UNLOCK (bin);
  GST_DEBUG_OBJECT (bin, "state continue done");

  gst_object_unref (bin);
  g_slice_free (BinContinueData, data);
  return;

interrupted:
  {
    GST_OBJECT_UNLOCK (bin);
    GST_STATE_UNLOCK (bin);
    GST_DEBUG_OBJECT (bin, "state continue aborted due to intervening change");
    gst_object_unref (bin);
    g_slice_free (BinContinueData, data);
    return;
  }
}

static GstBusSyncReply
bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
{
  GstBinClass *bclass;

  bclass = GST_BIN_GET_CLASS (bin);
  if (bclass->handle_message)
    bclass->handle_message (bin, message);
  else
    gst_message_unref (message);

  return GST_BUS_DROP;
}

static void
bin_push_state_continue (BinContinueData * data)
{
  GstBinClass *klass;
  GstBin *bin;

  /* ref was taken */
  bin = data->bin;
  klass = GST_BIN_GET_CLASS (bin);

  GST_DEBUG_OBJECT (bin, "pushing continue on thread pool");
  g_thread_pool_push (klass->pool, data, NULL);
}

/* an element started an async state change, if we were not busy with a state
 * change, we perform a lost state.
 * This function is called with the OBJECT lock.
 */
static void
bin_handle_async_start (GstBin * bin)
{
  GstState old_state, new_state;
  gboolean toplevel;
  GstMessage *amessage = NULL;

  if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
    goto had_error;

  /* get our toplevel state */
  toplevel = BIN_IS_TOPLEVEL (bin);

  /* prepare an ASYNC_START message, we always post the start message even if we
   * are busy with a state change or when we are NO_PREROLL. */
  if (!toplevel)
    /* non toplevel bin, prepare async-start for the parent */
    amessage = gst_message_new_async_start (GST_OBJECT_CAST (bin));

  if (bin->polling || GST_STATE_PENDING (bin) != GST_STATE_VOID_PENDING)
    goto was_busy;

  /* async starts are ignored when we are NO_PREROLL */
  if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_NO_PREROLL)
    goto was_no_preroll;

  old_state = GST_STATE (bin);

  /* when we PLAYING we go back to PAUSED, when preroll happens, we go back to
   * PLAYING after optionally redistributing the base_time. */
  if (old_state > GST_STATE_PAUSED)
    new_state = GST_STATE_PAUSED;
  else
    new_state = old_state;

  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
      "lost state of %s, new %s", gst_element_state_get_name (old_state),
      gst_element_state_get_name (new_state));

  GST_STATE (bin) = new_state;
  GST_STATE_NEXT (bin) = new_state;
  GST_STATE_PENDING (bin) = new_state;
  GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
  GST_OBJECT_UNLOCK (bin);

  /* post message */
  _priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), new_state, new_state,
      new_state);

post_start:
  if (amessage) {
    /* post our ASYNC_START. */
    GST_DEBUG_OBJECT (bin, "posting ASYNC_START to parent");
    gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
  }
  GST_OBJECT_LOCK (bin);

  return;

had_error:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "we had an error");
    return;
  }
was_busy:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "state change busy");
    GST_OBJECT_UNLOCK (bin);
    goto post_start;
  }
was_no_preroll:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "ignoring, we are NO_PREROLL");
    GST_OBJECT_UNLOCK (bin);
    goto post_start;
  }
}

/* this function is called when there are no more async elements in the bin. We
 * post a state changed message and an ASYNC_DONE message.
 * This function is called with the OBJECT lock.
 */
static void
bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
    gboolean flag_pending, GstClockTime running_time)
{
  GstState current, pending, target;
  GstStateChangeReturn old_ret;
  GstState old_state, old_next;
  gboolean toplevel, state_changed = FALSE;
  GstMessage *amessage = NULL;
  BinContinueData *cont = NULL;

  if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
    goto had_error;

  pending = GST_STATE_PENDING (bin);

  if (bin->polling)
    goto was_busy;

  /* check if there is something to commit */
  if (pending == GST_STATE_VOID_PENDING)
    goto nothing_pending;

  old_ret = GST_STATE_RETURN (bin);
  GST_STATE_RETURN (bin) = ret;

  /* move to the next target state */
  target = GST_STATE_TARGET (bin);
  pending = GST_STATE_PENDING (bin) = target;

  amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin), running_time);

  old_state = GST_STATE (bin);
  /* this is the state we should go to next */
  old_next = GST_STATE_NEXT (bin);

  if (old_next != GST_STATE_PLAYING) {
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
        "committing state from %s to %s, old pending %s",
        gst_element_state_get_name (old_state),
        gst_element_state_get_name (old_next),
        gst_element_state_get_name (pending));

    /* update current state */
    current = GST_STATE (bin) = old_next;
  } else {
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
        "setting state from %s to %s, pending %s",
        gst_element_state_get_name (old_state),
        gst_element_state_get_name (old_state),
        gst_element_state_get_name (pending));
    current = old_state;
  }

  /* get our toplevel state */
  toplevel = BIN_IS_TOPLEVEL (bin);

  /* see if we reached the final state. If we are not toplevel, we also have to
   * stop here, the parent will continue our state. */
  if ((pending == current) || !toplevel) {
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
        "completed state change, pending VOID");

    /* mark VOID pending */
    pending = GST_STATE_VOID_PENDING;
    GST_STATE_PENDING (bin) = pending;
    GST_STATE_NEXT (bin) = GST_STATE_VOID_PENDING;
  } else {
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
        "continue state change, pending %s",
        gst_element_state_get_name (pending));

    cont = g_slice_new (BinContinueData);

    /* ref to the bin */
    cont->bin = gst_object_ref (bin);
    /* cookie to detect concurrent state change */
    cont->cookie = GST_ELEMENT_CAST (bin)->state_cookie;
    /* pending target state */
    cont->pending = pending;
    /* mark busy */
    GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
    GST_STATE_NEXT (bin) = GST_STATE_GET_NEXT (old_state, pending);
  }

  if (old_next != GST_STATE_PLAYING) {
    if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
      state_changed = TRUE;
    }
  }
  GST_OBJECT_UNLOCK (bin);

  if (state_changed) {
    _priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), old_state,
        old_next, pending);
  }
  if (amessage) {
    /* post our combined ASYNC_DONE when all is ASYNC_DONE. */
    GST_DEBUG_OBJECT (bin, "posting ASYNC_DONE to parent");
    gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
  }

  GST_OBJECT_LOCK (bin);
  if (cont) {
    /* toplevel, start continue state */
    GST_DEBUG_OBJECT (bin, "all async-done, starting state continue");
    bin_push_state_continue (cont);
  } else {
    GST_DEBUG_OBJECT (bin, "state change complete");
    GST_STATE_BROADCAST (bin);
  }
  return;

had_error:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "we had an error");
    return;
  }
was_busy:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "state change busy");
    /* if we were busy with a state change and we are requested to flag a
     * pending async done, we do so here */
    if (flag_pending)
      bin->priv->pending_async_done = TRUE;
    return;
  }
nothing_pending:
  {
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin, "nothing pending");
    return;
  }
}

static void
bin_do_eos (GstBin * bin)
{
  guint32 seqnum = 0;
  gboolean eos;

  GST_OBJECT_LOCK (bin);
  /* If all sinks are EOS, we're in PLAYING and no state change is pending
   * we forward the EOS message to the parent bin or application
   */
  eos = GST_STATE (bin) == GST_STATE_PLAYING
      && GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING
      && is_eos (bin, &seqnum);
  GST_OBJECT_UNLOCK (bin);

  if (eos
      && g_atomic_int_compare_and_exchange (&bin->priv->posted_eos, FALSE,
          TRUE)) {
    GstMessage *tmessage;

    /* Clear out any further messages, and reset posted_eos so we can
       detect any new EOS that happens (eg, after a seek). Since all
       sinks have now posted an EOS, there will be no further EOS events
       seen unless there is a new logical EOS */
    GST_OBJECT_LOCK (bin);
    bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
    bin->priv->posted_eos = FALSE;
    GST_OBJECT_UNLOCK (bin);

    tmessage = gst_message_new_eos (GST_OBJECT_CAST (bin));
    gst_message_set_seqnum (tmessage, seqnum);
    GST_DEBUG_OBJECT (bin,
        "all sinks posted EOS, posting seqnum #%" G_GUINT32_FORMAT, seqnum);
    gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
  }
}

static void
bin_do_stream_start (GstBin * bin)
{
  guint32 seqnum = 0;
  gboolean stream_start;

  GST_OBJECT_LOCK (bin);
  /* If all sinks are STREAM_START we forward the STREAM_START message
   * to the parent bin or application
   */
  stream_start = is_stream_start (bin, &seqnum);
  GST_OBJECT_UNLOCK (bin);

  if (stream_start) {
    GstMessage *tmessage;

    GST_OBJECT_LOCK (bin);
    bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START);
    GST_OBJECT_UNLOCK (bin);

    tmessage = gst_message_new_stream_start (GST_OBJECT_CAST (bin));
    gst_message_set_seqnum (tmessage, seqnum);
    GST_DEBUG_OBJECT (bin,
        "all sinks posted STREAM_START, posting seqnum #%" G_GUINT32_FORMAT,
        seqnum);
    gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
  }
}

/* must be called with the object lock. This function releases the lock to post
 * the message. */
static void
bin_do_message_forward (GstBin * bin, GstMessage * message)
{
  if (bin->priv->message_forward) {
    GstMessage *forwarded;

    GST_DEBUG_OBJECT (bin, "pass %s message upward",
        GST_MESSAGE_TYPE_NAME (message));
    GST_OBJECT_UNLOCK (bin);

    /* we need to convert these messages to element messages so that our parent
     * bin can easily ignore them and so that the application can easily
     * distinguish between the internally forwarded and the real messages. */
    forwarded = gst_message_new_element (GST_OBJECT_CAST (bin),
        gst_structure_new ("GstBinForwarded",
            "message", GST_TYPE_MESSAGE, message, NULL));

    gst_element_post_message (GST_ELEMENT_CAST (bin), forwarded);

    GST_OBJECT_LOCK (bin);
  }
}

/* handle child messages:
 *
 * This method is called synchronously when a child posts a message on
 * the internal bus.
 *
 * GST_MESSAGE_EOS: This message is only posted by sinks
 *     in the PLAYING state. If all sinks posted the EOS message, post
 *     one upwards.
 *
 * GST_MESSAGE_STATE_DIRTY: Deprecated
 *
 * GST_MESSAGE_SEGMENT_START: just collect, never forward upwards. If an
 *     element posts segment_start twice, only the last message is kept.
 *
 * GST_MESSAGE_SEGMENT_DONE: replace SEGMENT_START message from same poster
 *     with the segment_done message. If there are no more segment_start
 *     messages, post segment_done message upwards.
 *
 * GST_MESSAGE_DURATION: remove all previously cached duration messages.
 *     Whenever someone performs a duration query on the bin, we store the
 *     result so we can answer it quicker the next time. Any element that
 *     changes its duration marks our cached values invalid.
 *     This message is also posted upwards. This is currently disabled
 *     because too many elements don't post DURATION messages when the
 *     duration changes.
 *
 * GST_MESSAGE_CLOCK_LOST: This message is posted by an element when it
 *     can no longer provide a clock. The default bin behaviour is to
 *     check if the lost clock was the one provided by the bin. If so and
 *     we are currently in the PLAYING state, we forward the message to
 *     our parent.
 *     This message is also generated when we remove a clock provider from
 *     a bin. If this message is received by the application, it should
 *     PAUSE the pipeline and set it back to PLAYING to force a new clock
 *     and a new base_time distribution.
 *
 * GST_MESSAGE_CLOCK_PROVIDE: This message is generated when an element
 *     can provide a clock. This mostly happens when we add a new clock
 *     provider to the bin. The default behaviour of the bin is to mark the
 *     currently selected clock as dirty, which will perform a clock
 *     recalculation the next time we are asked to provide a clock.
 *     This message is never sent to the application but is forwarded to
 *     the parent.
 *
 * GST_MESSAGE_ASYNC_START: Create an internal ELEMENT message that stores
 *     the state of the element and the fact that the element will need a
 *     new base_time. This message is not forwarded to the application.
 *
 * GST_MESSAGE_ASYNC_DONE: Find the internal ELEMENT message we kept for the
 *     element when it posted ASYNC_START. If all elements are done, post a
 *     ASYNC_DONE message to the parent.
 *
 * OTHER: post upwards.
 */
static void
gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
{
  GstObject *src;
  GstMessageType type;
  GstMessage *tmessage;
  guint32 seqnum;

  src = GST_MESSAGE_SRC (message);
  type = GST_MESSAGE_TYPE (message);

  GST_DEBUG_OBJECT (bin, "[msg %p] handling child %s message of type %s",
      message, src ? GST_ELEMENT_NAME (src) : "(NULL)",
      GST_MESSAGE_TYPE_NAME (message));

  switch (type) {
    case GST_MESSAGE_ERROR:
    {
      GST_OBJECT_LOCK (bin);
      /* flag error */
      GST_DEBUG_OBJECT (bin, "got ERROR message, unlocking state change");
      GST_STATE_RETURN (bin) = GST_STATE_CHANGE_FAILURE;
      GST_STATE_BROADCAST (bin);
      GST_OBJECT_UNLOCK (bin);

      goto forward;
    }
    case GST_MESSAGE_EOS:
    {

      /* collect all eos messages from the children */
      GST_OBJECT_LOCK (bin);
      bin_do_message_forward (bin, message);
      /* ref message for future use  */
      bin_replace_message (bin, message, GST_MESSAGE_EOS);
      GST_OBJECT_UNLOCK (bin);

      bin_do_eos (bin);
      break;
    }
    case GST_MESSAGE_STREAM_START:
    {

      /* collect all stream_start messages from the children */
      GST_OBJECT_LOCK (bin);
      /* ref message for future use  */
      bin_replace_message (bin, message, GST_MESSAGE_STREAM_START);
      GST_OBJECT_UNLOCK (bin);

      bin_do_stream_start (bin);
      break;
    }
    case GST_MESSAGE_STATE_DIRTY:
    {
      GST_WARNING_OBJECT (bin, "received deprecated STATE_DIRTY message");

      /* free message */
      gst_message_unref (message);
      break;
    }
    case GST_MESSAGE_SEGMENT_START:{
      gboolean post = FALSE;
      GstFormat format;
      gint64 position;

      gst_message_parse_segment_start (message, &format, &position);
      seqnum = gst_message_get_seqnum (message);

      GST_OBJECT_LOCK (bin);
      bin_do_message_forward (bin, message);
      /* if this is the first segment-start, post to parent but not to the
       * application */
      if (!find_message (bin, NULL, GST_MESSAGE_SEGMENT_START) &&
          (GST_OBJECT_PARENT (bin) != NULL)) {
        post = TRUE;
      }
      /* replace any previous segment_start message from this source
       * with the new segment start message */
      bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
      GST_OBJECT_UNLOCK (bin);
      if (post) {
        tmessage = gst_message_new_segment_start (GST_OBJECT_CAST (bin),
            format, position);
        gst_message_set_seqnum (tmessage, seqnum);

        /* post segment start with initial format and position. */
        GST_DEBUG_OBJECT (bin, "posting SEGMENT_START (%u) bus message: %p",
            seqnum, message);
        gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
      }
      break;
    }
    case GST_MESSAGE_SEGMENT_DONE:
    {
      gboolean post = FALSE;
      GstFormat format;
      gint64 position;

      gst_message_parse_segment_done (message, &format, &position);
      seqnum = gst_message_get_seqnum (message);

      GST_OBJECT_LOCK (bin);
      bin_do_message_forward (bin, message);
      bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
      /* if there are no more segment_start messages, everybody posted
       * a segment_done and we can post one on the bus. */

      /* we don't care who still has a pending segment start */
      if (!find_message (bin, NULL, GST_MESSAGE_SEGMENT_START)) {
        /* nothing found */
        post = TRUE;
        /* remove all old segment_done messages */
        bin_remove_messages (bin, NULL, GST_MESSAGE_SEGMENT_DONE);
      }
      GST_OBJECT_UNLOCK (bin);
      if (post) {
        tmessage = gst_message_new_segment_done (GST_OBJECT_CAST (bin),
            format, position);
        gst_message_set_seqnum (tmessage, seqnum);

        /* post segment done with latest format and position. */
        GST_DEBUG_OBJECT (bin, "posting SEGMENT_DONE (%u) bus message: %p",
            seqnum, message);
        gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
      }
      break;
    }
    case GST_MESSAGE_DURATION:
    {
      /* remove all cached duration messages, next time somebody asks
       * for duration, we will recalculate. */
      GST_OBJECT_LOCK (bin);
      bin_remove_messages (bin, NULL, GST_MESSAGE_DURATION);
      GST_OBJECT_UNLOCK (bin);
      goto forward;
    }
    case GST_MESSAGE_CLOCK_LOST:
    {
      GstClock **provided_clock_p;
      GstElement **clock_provider_p;
      gboolean playing, provided, forward;
      GstClock *clock;

      gst_message_parse_clock_lost (message, &clock);

      GST_OBJECT_LOCK (bin);
      bin->clock_dirty = TRUE;
      /* if we lost the clock that we provided, post to parent but
       * only if we are PLAYING. */
      provided = (clock == bin->provided_clock);
      playing = (GST_STATE (bin) == GST_STATE_PLAYING);
      forward = playing & provided;
      if (provided) {
        GST_DEBUG_OBJECT (bin,
            "Lost clock %" GST_PTR_FORMAT " provided by %" GST_PTR_FORMAT,
            bin->provided_clock, bin->clock_provider);
        provided_clock_p = &bin->provided_clock;
        clock_provider_p = &bin->clock_provider;
        gst_object_replace ((GstObject **) provided_clock_p, NULL);
        gst_object_replace ((GstObject **) clock_provider_p, NULL);
      }
      GST_DEBUG_OBJECT (bin, "provided %d, playing %d, forward %d",
          provided, playing, forward);
      GST_OBJECT_UNLOCK (bin);

      if (forward)
        goto forward;

      /* free message */
      gst_message_unref (message);
      break;
    }
    case GST_MESSAGE_CLOCK_PROVIDE:
    {
      gboolean forward;

      GST_OBJECT_LOCK (bin);
      bin->clock_dirty = TRUE;
      /* a new clock is available, post to parent but not
       * to the application */
      forward = GST_OBJECT_PARENT (bin) != NULL;
      GST_OBJECT_UNLOCK (bin);

      if (forward)
        goto forward;

      /* free message */
      gst_message_unref (message);
      break;
    }
    case GST_MESSAGE_ASYNC_START:
    {
      GstState target;

      GST_DEBUG_OBJECT (bin, "ASYNC_START message %p, %s", message,
          src ? GST_OBJECT_NAME (src) : "(NULL)");

      GST_OBJECT_LOCK (bin);
      bin_do_message_forward (bin, message);

      /* we ignore the message if we are going to <= READY */
      if ((target = GST_STATE_TARGET (bin)) <= GST_STATE_READY)
        goto ignore_start_message;

      /* takes ownership of the message */
      bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);

      bin_handle_async_start (bin);
      GST_OBJECT_UNLOCK (bin);
      break;

    ignore_start_message:
      {
        GST_DEBUG_OBJECT (bin, "ignoring message, target %s",
            gst_element_state_get_name (target));
        GST_OBJECT_UNLOCK (bin);
        gst_message_unref (message);
        break;
      }
    }
    case GST_MESSAGE_ASYNC_DONE:
    {
      GstClockTime running_time;
      GstState target;

      GST_DEBUG_OBJECT (bin, "ASYNC_DONE message %p, %s", message,
          src ? GST_OBJECT_NAME (src) : "(NULL)");

      gst_message_parse_async_done (message, &running_time);

      GST_OBJECT_LOCK (bin);
      bin_do_message_forward (bin, message);

      /* ignore messages if we are shutting down */
      if ((target = GST_STATE_TARGET (bin)) <= GST_STATE_READY)
        goto ignore_done_message;

      bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);
      /* if there are no more ASYNC_START messages, everybody posted
       * a ASYNC_DONE and we can post one on the bus. When checking, we
       * don't care who still has a pending ASYNC_START */
      if (!find_message (bin, NULL, GST_MESSAGE_ASYNC_START)) {
        /* nothing found, remove all old ASYNC_DONE messages */
        bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);

        GST_DEBUG_OBJECT (bin, "async elements commited");
        /* when we get an async done message when a state change was busy, we
         * need to set the pending_done flag so that at the end of the state
         * change we can see if we need to verify pending async elements, hence
         * the TRUE argument here. */
        bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, TRUE,
            running_time);
      } else {
        GST_DEBUG_OBJECT (bin, "there are more async elements pending");
      }
      GST_OBJECT_UNLOCK (bin);
      break;

    ignore_done_message:
      {
        GST_DEBUG_OBJECT (bin, "ignoring message, target %s",
            gst_element_state_get_name (target));
        GST_OBJECT_UNLOCK (bin);
        gst_message_unref (message);
        break;
      }
    }
    case GST_MESSAGE_STRUCTURE_CHANGE:
    {
      gboolean busy;

      gst_message_parse_structure_change (message, NULL, NULL, &busy);

      GST_OBJECT_LOCK (bin);
      if (busy) {
        /* while the pad is busy, avoid following it when doing state changes.
         * Don't update the cookie yet, we will do that after the structure
         * change finished and we are ready to inspect the new updated
         * structure. */
        bin_replace_message (bin, message, GST_MESSAGE_STRUCTURE_CHANGE);
        message = NULL;
      } else {
        /* a pad link/unlink ended, signal the state change iterator that we
         * need to resync by updating the structure_cookie. */
        bin_remove_messages (bin, GST_MESSAGE_SRC (message),
            GST_MESSAGE_STRUCTURE_CHANGE);
        bin->priv->structure_cookie++;
      }
      GST_OBJECT_UNLOCK (bin);

      if (message)
        gst_message_unref (message);

      break;
    }
    default:
      goto forward;
  }
  return;

forward:
  {
    /* Send all other messages upward */
    GST_DEBUG_OBJECT (bin, "posting message upward");
    gst_element_post_message (GST_ELEMENT_CAST (bin), message);
    return;
  }
}

/* generic struct passed to all query fold methods */
typedef struct
{
  GstQuery *query;
  gint64 min;
  gint64 max;
  gboolean live;
} QueryFold;

typedef void (*QueryInitFunction) (GstBin * bin, QueryFold * fold);
typedef void (*QueryDoneFunction) (GstBin * bin, QueryFold * fold);

/* for duration/position we collect all durations/positions and take
 * the MAX of all valid results */
static void
bin_query_min_max_init (GstBin * bin, QueryFold * fold)
{
  fold->min = 0;
  fold->max = -1;
  fold->live = FALSE;
}

static gboolean
bin_query_duration_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
{
  GstElement *item = g_value_get_object (vitem);

  if (gst_element_query (item, fold->query)) {
    gint64 duration;

    g_value_set_boolean (ret, TRUE);

    gst_query_parse_duration (fold->query, NULL, &duration);

    GST_DEBUG_OBJECT (item, "got duration %" G_GINT64_FORMAT, duration);

    if (duration == -1) {
      /* duration query succeeded, but duration is unknown */
      fold->max = -1;
      return FALSE;
    }

    if (duration > fold->max)
      fold->max = duration;
  }

  return TRUE;
}

static void
bin_query_duration_done (GstBin * bin, QueryFold * fold)
{
  GstFormat format;

  gst_query_parse_duration (fold->query, &format, NULL);
  /* store max in query result */
  gst_query_set_duration (fold->query, format, fold->max);

  GST_DEBUG_OBJECT (bin, "max duration %" G_GINT64_FORMAT, fold->max);

  /* and cache now */
  GST_OBJECT_LOCK (bin);
  bin->messages = g_list_prepend (bin->messages,
      gst_message_new_duration (GST_OBJECT_CAST (bin), format, fold->max));
  GST_OBJECT_UNLOCK (bin);
}

static gboolean
bin_query_position_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
{
  GstElement *item = g_value_get_object (vitem);

  if (gst_element_query (item, fold->query)) {
    gint64 position;

    g_value_set_boolean (ret, TRUE);

    gst_query_parse_position (fold->query, NULL, &position);

    GST_DEBUG_OBJECT (item, "got position %" G_GINT64_FORMAT, position);

    if (position > fold->max)
      fold->max = position;
  }

  return TRUE;
}

static void
bin_query_position_done (GstBin * bin, QueryFold * fold)
{
  GstFormat format;

  gst_query_parse_position (fold->query, &format, NULL);
  /* store max in query result */
  gst_query_set_position (fold->query, format, fold->max);

  GST_DEBUG_OBJECT (bin, "max position %" G_GINT64_FORMAT, fold->max);
}

static gboolean
bin_query_latency_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
{
  GstElement *item = g_value_get_object (vitem);

  if (gst_element_query (item, fold->query)) {
    GstClockTime min, max;
    gboolean live;

    gst_query_parse_latency (fold->query, &live, &min, &max);

    GST_DEBUG_OBJECT (item,
        "got latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
        ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live);

    /* for the combined latency we collect the MAX of all min latencies and
     * the MIN of all max latencies */
    if (live) {
      if (min > fold->min)
        fold->min = min;
      if (fold->max == -1)
        fold->max = max;
      else if (max < fold->max)
        fold->max = max;
      if (fold->live == FALSE)
        fold->live = live;
    }
  } else {
    g_value_set_boolean (ret, FALSE);
    GST_DEBUG_OBJECT (item, "failed query");
  }

  return TRUE;
}

static void
bin_query_latency_done (GstBin * bin, QueryFold * fold)
{
  /* store max in query result */
  gst_query_set_latency (fold->query, fold->live, fold->min, fold->max);

  GST_DEBUG_OBJECT (bin,
      "latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
      ", live %d", GST_TIME_ARGS (fold->min), GST_TIME_ARGS (fold->max),
      fold->live);
}

/* generic fold, return first valid result */
static gboolean
bin_query_generic_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
{
  GstElement *item = g_value_get_object (vitem);
  gboolean res;

  if ((res = gst_element_query (item, fold->query))) {
    g_value_set_boolean (ret, TRUE);
    GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
  }

  /* and stop as soon as we have a valid result */
  return !res;
}

static gboolean
gst_bin_query (GstElement * element, GstQuery * query)
{
  GstBin *bin = GST_BIN_CAST (element);
  GstIterator *iter;
  gboolean res = FALSE;
  GstIteratorFoldFunction fold_func;
  QueryInitFunction fold_init = NULL;
  QueryDoneFunction fold_done = NULL;
  QueryFold fold_data;
  GValue ret = { 0 };

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
    {
      GList *cached;
      GstFormat qformat;

      gst_query_parse_duration (query, &qformat, NULL);

      /* find cached duration query */
      GST_OBJECT_LOCK (bin);
      for (cached = bin->messages; cached; cached = g_list_next (cached)) {
        GstMessage *message = (GstMessage *) cached->data;

        if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION &&
            GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (bin)) {
          GstFormat format;
          gint64 duration;

          gst_message_parse_duration (message, &format, &duration);

          /* if cached same format, copy duration in query result */
          if (format == qformat) {
            GST_DEBUG_OBJECT (bin, "return cached duration %" G_GINT64_FORMAT,
                duration);
            GST_OBJECT_UNLOCK (bin);

            gst_query_set_duration (query, qformat, duration);
            res = TRUE;
            goto exit;
          }
        }
      }
      GST_OBJECT_UNLOCK (bin);
      /* no cached value found, iterate and collect durations */
      fold_func = (GstIteratorFoldFunction) bin_query_duration_fold;
      fold_init = bin_query_min_max_init;
      fold_done = bin_query_duration_done;
      break;
    }
    case GST_QUERY_POSITION:
    {
      fold_func = (GstIteratorFoldFunction) bin_query_position_fold;
      fold_init = bin_query_min_max_init;
      fold_done = bin_query_position_done;
      break;
    }
    case GST_QUERY_LATENCY:
    {
      fold_func = (GstIteratorFoldFunction) bin_query_latency_fold;
      fold_init = bin_query_min_max_init;
      fold_done = bin_query_latency_done;
      res = TRUE;
      break;
    }
    default:
      fold_func = (GstIteratorFoldFunction) bin_query_generic_fold;
      break;
  }

  fold_data.query = query;

  /* set the result of the query to FALSE initially */
  g_value_init (&ret, G_TYPE_BOOLEAN);
  g_value_set_boolean (&ret, res);

  iter = gst_bin_iterate_sinks (bin);
  GST_DEBUG_OBJECT (bin, "Sending query %p (type %s) to sink children",
      query, GST_QUERY_TYPE_NAME (query));

  if (fold_init)
    fold_init (bin, &fold_data);

  while (TRUE) {
    GstIteratorResult ires;

    ires = gst_iterator_fold (iter, fold_func, &ret, &fold_data);

    switch (ires) {
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        if (fold_init)
          fold_init (bin, &fold_data);
        g_value_set_boolean (&ret, res);
        break;
      case GST_ITERATOR_OK:
      case GST_ITERATOR_DONE:
        res = g_value_get_boolean (&ret);
        if (fold_done != NULL && res)
          fold_done (bin, &fold_data);
        goto done;
      default:
        res = FALSE;
        goto done;
    }
  }
done:
  gst_iterator_free (iter);

exit:
  GST_DEBUG_OBJECT (bin, "query %p result %d", query, res);

  return res;
}

static gint
compare_name (const GValue * velement, const gchar * name)
{
  gint eq;
  GstElement *element = g_value_get_object (velement);

  GST_OBJECT_LOCK (element);
  eq = strcmp (GST_ELEMENT_NAME (element), name);
  GST_OBJECT_UNLOCK (element);

  return eq;
}

/**
 * gst_bin_get_by_name:
 * @bin: a #GstBin
 * @name: the element name to search for
 *
 * Gets the element with the given name from a bin. This
 * function recurses into child bins.
 *
 * Returns NULL if no element with the given name is found in the bin.
 *
 * MT safe.  Caller owns returned reference.
 *
 * Returns: (transfer full): the #GstElement with the given name, or NULL
 */
GstElement *
gst_bin_get_by_name (GstBin * bin, const gchar * name)
{
  GstIterator *children;
  GValue result = { 0, };
  GstElement *element;
  gboolean found;

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);

  GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
      GST_ELEMENT_NAME (bin), name);

  children = gst_bin_iterate_recurse (bin);
  found = gst_iterator_find_custom (children,
      (GCompareFunc) compare_name, &result, (gpointer) name);
  gst_iterator_free (children);

  if (found) {
    element = g_value_dup_object (&result);
    g_value_unset (&result);
  } else {
    element = NULL;
  }

  return element;
}

/**
 * gst_bin_get_by_name_recurse_up:
 * @bin: a #GstBin
 * @name: the element name to search for
 *
 * Gets the element with the given name from this bin. If the
 * element is not found, a recursion is performed on the parent bin.
 *
 * Returns NULL if:
 * - no element with the given name is found in the bin
 *
 * MT safe.  Caller owns returned reference.
 *
 * Returns: (transfer full): the #GstElement with the given name, or NULL
 */
GstElement *
gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
{
  GstElement *result;

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);
  g_return_val_if_fail (name != NULL, NULL);

  result = gst_bin_get_by_name (bin, name);

  if (!result) {
    GstObject *parent;

    parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
    if (parent) {
      if (GST_IS_BIN (parent)) {
        result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
      }
      gst_object_unref (parent);
    }
  }

  return result;
}

static gint
compare_interface (const GValue * velement, GValue * interface)
{
  GstElement *element = g_value_get_object (velement);
  GType interface_type = (GType) g_value_get_pointer (interface);
  gint ret;

  if (G_TYPE_CHECK_INSTANCE_TYPE (element, interface_type)) {
    ret = 0;
  } else {
    ret = 1;
  }
  return ret;
}

/**
 * gst_bin_get_by_interface:
 * @bin: a #GstBin
 * @iface: the #GType of an interface
 *
 * Looks for an element inside the bin that implements the given
 * interface. If such an element is found, it returns the element.
 * You can cast this element to the given interface afterwards.  If you want
 * all elements that implement the interface, use
 * gst_bin_iterate_all_by_interface(). This function recurses into child bins.
 *
 * MT safe.  Caller owns returned reference.
 *
 * Returns: (transfer full): A #GstElement inside the bin implementing the interface
 */
GstElement *
gst_bin_get_by_interface (GstBin * bin, GType iface)
{
  GstIterator *children;
  GValue result = { 0, };
  GstElement *element;
  gboolean found;
  GValue viface = { 0, };

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);
  g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);

  g_value_init (&viface, G_TYPE_POINTER);
  g_value_set_pointer (&viface, (gpointer) iface);

  children = gst_bin_iterate_recurse (bin);
  found = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
      &result, &viface);
  gst_iterator_free (children);

  if (found) {
    element = g_value_dup_object (&result);
    g_value_unset (&result);
  } else {
    element = NULL;
  }
  g_value_unset (&viface);

  return element;
}

/**
 * gst_bin_iterate_all_by_interface:
 * @bin: a #GstBin
 * @iface: the #GType of an interface
 *
 * Looks for all elements inside the bin that implements the given
 * interface. You can safely cast all returned elements to the given interface.
 * The function recurses inside child bins. The iterator will yield a series
 * of #GstElement that should be unreffed after use.
 *
 * Each element yielded by the iterator will have its refcount increased, so
 * unref after use.
 *
 * MT safe.  Caller owns returned value.
 *
 * Returns: (transfer full): a #GstIterator of #GstElement for all elements
 *          in the bin implementing the given interface, or NULL
 */
GstIterator *
gst_bin_iterate_all_by_interface (GstBin * bin, GType iface)
{
  GstIterator *children;
  GstIterator *result;
  GValue viface = { 0, };

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);
  g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);

  g_value_init (&viface, G_TYPE_POINTER);
  g_value_set_pointer (&viface, (gpointer) iface);

  children = gst_bin_iterate_recurse (bin);
  result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
      &viface);

  g_value_unset (&viface);

  return result;
}
