/* GStreamer
 * Copyright (C) <2006> Edward Hervey <edward@fluendo.com>
 * Copyright (C) <2009> Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) <2011> Hewlett-Packard Development Company, L.P.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
 * Copyright (C) <2013> Collabora Ltd.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>
 * Copyright (C) <2015-2016> Centricular Ltd
 *  @author: Edward Hervey <edward@centricular.com>
 *  @author: Jan Schmidt <jan@centricular.com>
 *
 * 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., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-parsebin
 * @title: parsebin
 *
 * #GstBin that auto-magically constructs a parsing pipeline
 * using available parsers and demuxers via auto-plugging.
 *
 * parsebin unpacks the contents of the input stream to the
 * level of parsed elementary streams, but unlike decodebin
 * it doesn't connect decoder elements. The output pads
 * produce packetised encoded data with timestamps where possible,
 * or send missing-element messages where not.
 *
 * <emphasis>parsebin is still experimental API and a technology preview.
 * Its behaviour and exposed API is subject to change.</emphasis>
 */

/* Implementation notes:
 *
 * The following section describes how ParseBin works internally.
 *
 * The first part of ParseBin is its typefind element, which tries
 * to determine the media type of the input stream. If the type is found
 * autoplugging starts.
 *
 * ParseBin internally organizes the elements it autoplugged into
 * GstParseChains and GstParseGroups. A parse chain is a single chain
 * of parsing, this
 * means that if ParseBin ever autoplugs an element with two+ srcpads
 * (e.g. a demuxer) this will end the chain and everything following this
 * demuxer will be put into parse groups below the chain. Otherwise,
 * if an element has a single srcpad that outputs raw data the parse chain
 * is ended too and a GstParsePad is stored and blocked.
 *
 * A parse group combines a number of chains that are created by a
 * demuxer element.
 *
 * This continues until the top-level parse chain is complete. A parse
 * chain is complete if it either ends with a blocked elementary stream,
 * if autoplugging stopped because no suitable plugins could be found
 * or if the active group is complete. A parse group on the other hand
 * is complete if all child chains are complete.
 *
 * If this happens at some point, all end pads of all active groups are exposed.
 * For this ParseBin adds the end pads, and then unblocks them. Now playback starts.
 *
 * If one of the chains that end on a endpad receives EOS ParseBin checks
 * if all chains and groups are drained. In that case everything goes into EOS.
 * If there is a chain where the active group is drained but there exist next
 * groups, the active group is hidden (endpads are removed) and the next group
 * is exposed. This means that in some cases more pads may be created even
 * after the initial no-more-pads signal. This happens for example with
 * so-called "chained oggs", most commonly found among ogg/vorbis internet
 * radio streams.
 *
 * Note 1: If we're talking about blocked endpads this really means that the
 * *target* pads of the endpads are blocked. Pads that are exposed to the outside
 * should never ever be blocked!
 *
 * Note 2: If a group is complete and the parent's chain demuxer adds new pads
 * but never signaled no-more-pads this additional pads will be ignored!
 *
 */

/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
 * with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/gst-i18n-plugin.h>

#include <string.h>
#include <gst/gst.h>
#include <gst/pbutils/pbutils.h>

#include "gstplay-enum.h"
#include "gstplayback.h"
#include "gstplaybackutils.h"

/* generic templates */
static GstStaticPadTemplate parse_bin_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate parse_bin_src_template =
GST_STATIC_PAD_TEMPLATE ("src_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS_ANY);

GST_DEBUG_CATEGORY_STATIC (gst_parse_bin_debug);
#define GST_CAT_DEFAULT gst_parse_bin_debug

typedef struct _GstPendingPad GstPendingPad;
typedef struct _GstParseElement GstParseElement;
typedef struct _GstParseChain GstParseChain;
typedef struct _GstParseGroup GstParseGroup;
typedef struct _GstParsePad GstParsePad;
typedef GstGhostPadClass GstParsePadClass;
typedef struct _GstParseBin GstParseBin;
typedef struct _GstParseBinClass GstParseBinClass;

#define GST_TYPE_PARSE_BIN             (gst_parse_bin_get_type())
#define GST_PARSE_BIN_CAST(obj)        ((GstParseBin*)(obj))
#define GST_PARSE_BIN(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PARSE_BIN,GstParseBin))
#define GST_PARSE_BIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_PARSE_BIN,GstParseBinClass))
#define GST_IS_parse_bin(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_PARSE_BIN))
#define GST_IS_parse_bin_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_PARSE_BIN))

/**
 *  GstParseBin:
 *
 *  The opaque #GstParseBin data structure
 */
struct _GstParseBin
{
  GstBin bin;                   /* we extend GstBin */

  /* properties */
  gchar *encoding;              /* encoding of subtitles */
  guint64 connection_speed;

  GstElement *typefind;         /* this holds the typefind object */

  GMutex expose_lock;           /* Protects exposal and removal of groups */
  GstParseChain *parse_chain;   /* Top level parse chain */
  guint nbpads;                 /* unique identifier for source pads */

  GMutex factories_lock;
  guint32 factories_cookie;     /* Cookie from last time when factories was updated */
  GList *factories;             /* factories we can use for selecting elements */

  GMutex subtitle_lock;         /* Protects changes to subtitles and encoding */
  GList *subtitles;             /* List of elements with subtitle-encoding,
                                 * protected by above mutex! */

  gboolean have_type;           /* if we received the have_type signal */
  guint have_type_id;           /* signal id for have-type from typefind */

  gboolean async_pending;       /* async-start has been emitted */

  GMutex dyn_lock;              /* lock protecting pad blocking */
  gboolean shutdown;            /* if we are shutting down */
  GList *blocked_pads;          /* pads that have set to block */

  gboolean expose_allstreams;   /* Whether to expose unknow type streams or not */

  GList *filtered;              /* elements for which error messages are filtered */
  GList *filtered_errors;       /* filtered error messages */
};

struct _GstParseBinClass
{
  GstBinClass parent_class;

  /* signal fired when we found a pad that we cannot parse */
  void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);

  /* signal fired to know if we continue trying to parse the given caps */
    gboolean (*autoplug_continue) (GstElement * element, GstPad * pad,
      GstCaps * caps);
  /* signal fired to get a list of factories to try to autoplug */
  GValueArray *(*autoplug_factories) (GstElement * element, GstPad * pad,
      GstCaps * caps);
  /* signal fired to sort the factories */
  GValueArray *(*autoplug_sort) (GstElement * element, GstPad * pad,
      GstCaps * caps, GValueArray * factories);
  /* signal fired to select from the proposed list of factories */
    GstAutoplugSelectResult (*autoplug_select) (GstElement * element,
      GstPad * pad, GstCaps * caps, GstElementFactory * factory);
  /* signal fired when a autoplugged element that is not linked downstream
   * or exposed wants to query something */
    gboolean (*autoplug_query) (GstElement * element, GstPad * pad,
      GstQuery * query);

  /* fired when the last group is drained */
  void (*drained) (GstElement * element);
};

/* signals */
enum
{
  SIGNAL_UNKNOWN_TYPE,
  SIGNAL_AUTOPLUG_CONTINUE,
  SIGNAL_AUTOPLUG_FACTORIES,
  SIGNAL_AUTOPLUG_SELECT,
  SIGNAL_AUTOPLUG_SORT,
  SIGNAL_AUTOPLUG_QUERY,
  SIGNAL_DRAINED,
  LAST_SIGNAL
};

#define DEFAULT_SUBTITLE_ENCODING NULL
#define DEFAULT_USE_BUFFERING     FALSE
#define DEFAULT_LOW_PERCENT       10
#define DEFAULT_HIGH_PERCENT      99
/* by default we use the automatic values above */
#define DEFAULT_EXPOSE_ALL_STREAMS  TRUE
#define DEFAULT_CONNECTION_SPEED    0

/* Properties */
enum
{
  PROP_0,
  PROP_SUBTITLE_ENCODING,
  PROP_SINK_CAPS,
  PROP_EXPOSE_ALL_STREAMS,
  PROP_CONNECTION_SPEED
};

static GstBinClass *parent_class;
static guint gst_parse_bin_signals[LAST_SIGNAL] = { 0 };

static void do_async_start (GstParseBin * parsebin);
static void do_async_done (GstParseBin * parsebin);

static void type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstParseBin * parse_bin);

static gboolean gst_parse_bin_autoplug_continue (GstElement * element,
    GstPad * pad, GstCaps * caps);
static GValueArray *gst_parse_bin_autoplug_factories (GstElement *
    element, GstPad * pad, GstCaps * caps);
static GValueArray *gst_parse_bin_autoplug_sort (GstElement * element,
    GstPad * pad, GstCaps * caps, GValueArray * factories);
static GstAutoplugSelectResult gst_parse_bin_autoplug_select (GstElement *
    element, GstPad * pad, GstCaps * caps, GstElementFactory * factory);
static gboolean gst_parse_bin_autoplug_query (GstElement * element,
    GstPad * pad, GstQuery * query);

static void gst_parse_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_parse_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void caps_notify_cb (GstPad * pad, GParamSpec * unused,
    GstParseChain * chain);

static GstStateChangeReturn gst_parse_bin_change_state (GstElement * element,
    GstStateChange transition);
static void gst_parse_bin_handle_message (GstBin * bin, GstMessage * message);
static void gst_parse_pad_update_caps (GstParsePad * parsepad, GstCaps * caps);
static void gst_parse_pad_update_tags (GstParsePad * parsepad,
    GstTagList * tags);
static GstEvent *gst_parse_pad_stream_start_event (GstParsePad * parsepad,
    GstEvent * event);
static void gst_parse_pad_update_stream_collection (GstParsePad * parsepad,
    GstStreamCollection * collection);

static GstCaps *get_pad_caps (GstPad * pad);

#define EXPOSE_LOCK(parsebin) G_STMT_START {				\
    GST_LOG_OBJECT (parsebin,						\
		    "expose locking from thread %p",			\
		    g_thread_self ());					\
    g_mutex_lock (&GST_PARSE_BIN_CAST(parsebin)->expose_lock);		\
    GST_LOG_OBJECT (parsebin,						\
		    "expose locked from thread %p",			\
		    g_thread_self ());					\
} G_STMT_END

#define EXPOSE_UNLOCK(parsebin) G_STMT_START {				\
    GST_LOG_OBJECT (parsebin,						\
		    "expose unlocking from thread %p",			\
		    g_thread_self ());					\
    g_mutex_unlock (&GST_PARSE_BIN_CAST(parsebin)->expose_lock);		\
} G_STMT_END

#define DYN_LOCK(parsebin) G_STMT_START {			\
    GST_LOG_OBJECT (parsebin,						\
		    "dynlocking from thread %p",			\
		    g_thread_self ());					\
    g_mutex_lock (&GST_PARSE_BIN_CAST(parsebin)->dyn_lock);			\
    GST_LOG_OBJECT (parsebin,						\
		    "dynlocked from thread %p",				\
		    g_thread_self ());					\
} G_STMT_END

#define DYN_UNLOCK(parsebin) G_STMT_START {			\
    GST_LOG_OBJECT (parsebin,						\
		    "dynunlocking from thread %p",			\
		    g_thread_self ());					\
    g_mutex_unlock (&GST_PARSE_BIN_CAST(parsebin)->dyn_lock);		\
} G_STMT_END

#define SUBTITLE_LOCK(parsebin) G_STMT_START {				\
    GST_LOG_OBJECT (parsebin,						\
		    "subtitle locking from thread %p",			\
		    g_thread_self ());					\
    g_mutex_lock (&GST_PARSE_BIN_CAST(parsebin)->subtitle_lock);		\
    GST_LOG_OBJECT (parsebin,						\
		    "subtitle lock from thread %p",			\
		    g_thread_self ());					\
} G_STMT_END

#define SUBTITLE_UNLOCK(parsebin) G_STMT_START {				\
    GST_LOG_OBJECT (parsebin,						\
		    "subtitle unlocking from thread %p",		\
		    g_thread_self ());					\
    g_mutex_unlock (&GST_PARSE_BIN_CAST(parsebin)->subtitle_lock);		\
} G_STMT_END

struct _GstPendingPad
{
  GstPad *pad;
  GstParseChain *chain;
  gulong event_probe_id;
  gulong notify_caps_id;
};

struct _GstParseElement
{
  GstElement *element;
  GstElement *capsfilter;       /* Optional capsfilter for Parser/Convert */
  gulong pad_added_id;
  gulong pad_removed_id;
  gulong no_more_pads_id;
};

/* GstParseGroup
 *
 * Streams belonging to the same group/chain of a media file
 *
 * When changing something here lock the parent chain!
 */
struct _GstParseGroup
{
  GstParseBin *parsebin;
  GstParseChain *parent;

  gboolean no_more_pads;        /* TRUE if the demuxer signaled no-more-pads */
  gboolean drained;             /* TRUE if the all children are drained */

  GList *children;              /* List of GstParseChains in this group */
};

struct _GstParseChain
{
  GstParseGroup *parent;
  GstParseBin *parsebin;

  GMutex lock;                  /* Protects this chain and its groups */

  GstPad *pad;                  /* srcpad that caused creation of this chain */
  GstCaps *start_caps;          /* The initial caps of this chain */

  gboolean drained;             /* TRUE if the all children are drained */
  gboolean demuxer;             /* TRUE if elements->data is a demuxer */
  gboolean parsed;              /* TRUE if any elements are a parser */
  GList *elements;              /* All elements in this group, first
                                   is the latest and most downstream element */

  /* Note: there are only groups if the last element of this chain
   * is a demuxer, otherwise the chain will end with an endpad.
   * The other way around this means, that endpad only exists if this
   * chain doesn't end with a demuxer! */

  GstParseGroup *active_group;  /* Currently active group */
  GList *next_groups;           /* head is newest group, tail is next group.
                                   a new group will be created only if the head
                                   group had no-more-pads. If it's only exposed
                                   all new pads will be ignored! */
  GList *pending_pads;          /* Pads that have no fixed caps yet */

  GstParsePad *current_pad;     /* Current ending pad of the chain that can't
                                 * be exposed yet but would be the same as endpad
                                 * once it can be exposed */
  GstParsePad *endpad;          /* Pad of this chain that could be exposed */
  gboolean deadend;             /* This chain is incomplete and can't be completed,
                                   e.g. no suitable parser could be found
                                   e.g. stream got EOS without buffers
                                 */
  gchar *deadend_details;
  GstCaps *endcaps;             /* Caps that were used when linking to the endpad
                                   or that resulted in the deadend
                                 */

  /* FIXME: This should be done directly via a thread! */
  GList *old_groups;            /* Groups that should be freed later */
};

static void gst_parse_chain_free (GstParseChain * chain);
static GstParseChain *gst_parse_chain_new (GstParseBin * parsebin,
    GstParseGroup * group, GstPad * pad, GstCaps * start_caps);
static void gst_parse_group_hide (GstParseGroup * group);
static void gst_parse_group_free (GstParseGroup * group);
static GstParseGroup *gst_parse_group_new (GstParseBin * parsebin,
    GstParseChain * chain);
static gboolean gst_parse_chain_is_complete (GstParseChain * chain);
static gboolean gst_parse_chain_expose (GstParseChain * chain,
    GList ** endpads, gboolean * missing_plugin,
    GString * missing_plugin_details, gboolean * last_group,
    gboolean * uncollected_streams);
static void build_fallback_collection (GstParseChain * chain,
    GstStreamCollection * collection);
static gboolean gst_parse_chain_is_drained (GstParseChain * chain);
static gboolean gst_parse_group_is_complete (GstParseGroup * group);
static gboolean gst_parse_group_is_drained (GstParseGroup * group);

static gboolean gst_parse_bin_expose (GstParseBin * parsebin);

#define CHAIN_MUTEX_LOCK(chain) G_STMT_START {				\
    GST_LOG_OBJECT (chain->parsebin,					\
		    "locking chain %p from thread %p",			\
		    chain, g_thread_self ());				\
    g_mutex_lock (&chain->lock);						\
    GST_LOG_OBJECT (chain->parsebin,					\
		    "locked chain %p from thread %p",			\
		    chain, g_thread_self ());				\
} G_STMT_END

#define CHAIN_MUTEX_UNLOCK(chain) G_STMT_START {                        \
    GST_LOG_OBJECT (chain->parsebin,					\
		    "unlocking chain %p from thread %p",		\
		    chain, g_thread_self ());				\
    g_mutex_unlock (&chain->lock);					\
} G_STMT_END

/* GstParsePad
 *
 * GstPad private used for source pads of chains
 */
struct _GstParsePad
{
  GstGhostPad parent;
  GstParseBin *parsebin;
  GstParseChain *chain;

  gboolean blocked;             /* the *target* pad is blocked */
  gboolean exposed;             /* the pad is exposed */
  gboolean drained;             /* an EOS has been seen on the pad */

  gulong block_id;

  gboolean in_a_fallback_collection;
  GstStreamCollection *active_collection;
  GstStream *active_stream;
};

GType gst_parse_pad_get_type (void);
G_DEFINE_TYPE (GstParsePad, gst_parse_pad, GST_TYPE_GHOST_PAD);
#define GST_TYPE_PARSE_PAD (gst_parse_pad_get_type ())
#define GST_PARSE_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_PARSE_PAD,GstParsePad))

static GstParsePad *gst_parse_pad_new (GstParseBin * parsebin,
    GstParseChain * chain);
static void gst_parse_pad_activate (GstParsePad * parsepad,
    GstParseChain * chain);
static void gst_parse_pad_unblock (GstParsePad * parsepad);
static void gst_parse_pad_set_blocked (GstParsePad * parsepad,
    gboolean blocked);
static gboolean gst_parse_pad_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstPadProbeReturn
gst_parse_pad_event (GstPad * pad, GstPadProbeInfo * info, gpointer user_data);


static void gst_pending_pad_free (GstPendingPad * ppad);
static GstPadProbeReturn pad_event_cb (GstPad * pad, GstPadProbeInfo * info,
    gpointer data);

/********************************
 * Standard GObject boilerplate *
 ********************************/

static void gst_parse_bin_class_init (GstParseBinClass * klass);
static void gst_parse_bin_init (GstParseBin * parse_bin);
static void gst_parse_bin_dispose (GObject * object);
static void gst_parse_bin_finalize (GObject * object);

static GType
gst_parse_bin_get_type (void)
{
  static GType gst_parse_bin_type = 0;

  if (!gst_parse_bin_type) {
    static const GTypeInfo gst_parse_bin_info = {
      sizeof (GstParseBinClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_parse_bin_class_init,
      NULL,
      NULL,
      sizeof (GstParseBin),
      0,
      (GInstanceInitFunc) gst_parse_bin_init,
      NULL
    };

    gst_parse_bin_type =
        g_type_register_static (GST_TYPE_BIN, "GstParseBin",
        &gst_parse_bin_info, 0);
  }

  return gst_parse_bin_type;
}

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

  /* stop emission if FALSE */
  return myboolean;
}

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

  myboolean = g_value_get_boolean (handler_return);
  retboolean = g_value_get_boolean (return_accu);

  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
    g_value_set_boolean (return_accu, myboolean || retboolean);

  return TRUE;
}

/* we collect the first result */
static gboolean
_gst_array_accumulator (GSignalInvocationHint * ihint,
    GValue * return_accu, const GValue * handler_return, gpointer dummy)
{
  gpointer array;

  array = g_value_get_boxed (handler_return);
  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
    g_value_set_boxed (return_accu, array);

  return FALSE;
}

static gboolean
_gst_select_accumulator (GSignalInvocationHint * ihint,
    GValue * return_accu, const GValue * handler_return, gpointer dummy)
{
  GstAutoplugSelectResult res;

  res = g_value_get_enum (handler_return);
  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
    g_value_set_enum (return_accu, res);

  /* Call the next handler in the chain (if any) when the current callback
   * returns TRY. This makes it possible to register separate autoplug-select
   * handlers that implement different TRY/EXPOSE/SKIP strategies.
   */
  if (res == GST_AUTOPLUG_SELECT_TRY)
    return TRUE;

  return FALSE;
}

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

  array = g_value_get_boxed (handler_return);
  if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
    g_value_set_boxed (return_accu, array);

  if (array != NULL)
    return FALSE;

  return TRUE;
}

static void
gst_parse_bin_class_init (GstParseBinClass * klass)
{
  GObjectClass *gobject_klass;
  GstElementClass *gstelement_klass;
  GstBinClass *gstbin_klass;

  gobject_klass = (GObjectClass *) klass;
  gstelement_klass = (GstElementClass *) klass;
  gstbin_klass = (GstBinClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_klass->dispose = gst_parse_bin_dispose;
  gobject_klass->finalize = gst_parse_bin_finalize;
  gobject_klass->set_property = gst_parse_bin_set_property;
  gobject_klass->get_property = gst_parse_bin_get_property;

  /**
   * GstParseBin::unknown-type:
   * @bin: The ParseBin.
   * @pad: The new pad containing caps that cannot be resolved to a 'final'
   *       stream type.
   * @caps: The #GstCaps of the pad that cannot be resolved.
   *
   * This signal is emitted when a pad for which there is no further possible
   * parsing is added to the ParseBin.
   */
  gst_parse_bin_signals[SIGNAL_UNKNOWN_TYPE] =
      g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, unknown_type),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
      GST_TYPE_PAD, GST_TYPE_CAPS);

  /**
   * GstParseBin::autoplug-continue:
   * @bin: The ParseBin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps found.
   *
   * This signal is emitted whenever ParseBin finds a new stream. It is
   * emitted before looking for any elements that can handle that stream.
   *
   * >   Invocation of signal handlers stops after the first signal handler
   * >   returns #FALSE. Signal handlers are invoked in the order they were
   * >   connected in.
   *
   * Returns: #TRUE if you wish ParseBin to look for elements that can
   * handle the given @caps. If #FALSE, those caps will be considered as
   * final and the pad will be exposed as such (see 'pad-added' signal of
   * #GstElement).
   */
  gst_parse_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
      g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_continue),
      _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
      G_TYPE_BOOLEAN, 2, GST_TYPE_PAD, GST_TYPE_CAPS);

  /**
   * GstParseBin::autoplug-factories:
   * @bin: The ParseBin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps found.
   *
   * This function is emited when an array of possible factories for @caps on
   * @pad is needed. ParseBin will by default return an array with all
   * compatible factories, sorted by rank.
   *
   * If this function returns NULL, @pad will be exposed as a final caps.
   *
   * If this function returns an empty array, the pad will be considered as
   * having an unhandled type media type.
   *
   * >   Only the signal handler that is connected first will ever by invoked.
   * >   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
   * >   signal, they will never be invoked!
   *
   * Returns: a #GValueArray* with a list of factories to try. The factories are
   * by default tried in the returned order or based on the index returned by
   * "autoplug-select".
   */
  gst_parse_bin_signals[SIGNAL_AUTOPLUG_FACTORIES] =
      g_signal_new ("autoplug-factories", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass,
          autoplug_factories), _gst_array_accumulator, NULL,
      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 2,
      GST_TYPE_PAD, GST_TYPE_CAPS);

  /**
   * GstParseBin::autoplug-sort:
   * @bin: The ParseBin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps.
   * @factories: A #GValueArray of possible #GstElementFactory to use.
   *
   * Once ParseBin has found the possible #GstElementFactory objects to try
   * for @caps on @pad, this signal is emited. The purpose of the signal is for
   * the application to perform additional sorting or filtering on the element
   * factory array.
   *
   * The callee should copy and modify @factories or return #NULL if the
   * order should not change.
   *
   * >   Invocation of signal handlers stops after one signal handler has
   * >   returned something else than #NULL. Signal handlers are invoked in
   * >   the order they were connected in.
   * >   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
   * >   signal, they will never be invoked!
   *
   * Returns: A new sorted array of #GstElementFactory objects.
   */
  gst_parse_bin_signals[SIGNAL_AUTOPLUG_SORT] =
      g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_sort),
      _gst_array_hasvalue_accumulator, NULL,
      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 3, GST_TYPE_PAD,
      GST_TYPE_CAPS, G_TYPE_VALUE_ARRAY | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GstParseBin::autoplug-select:
   * @bin: The ParseBin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps.
   * @factory: A #GstElementFactory to use.
   *
   * This signal is emitted once ParseBin has found all the possible
   * #GstElementFactory that can be used to handle the given @caps. For each of
   * those factories, this signal is emitted.
   *
   * The signal handler should return a #GST_TYPE_AUTOPLUG_SELECT_RESULT enum
   * value indicating what ParseBin should do next.
   *
   * A value of #GST_AUTOPLUG_SELECT_TRY will try to autoplug an element from
   * @factory.
   *
   * A value of #GST_AUTOPLUG_SELECT_EXPOSE will expose @pad without plugging
   * any element to it.
   *
   * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the
   * next factory.
   *
   * >   The signal handler will not be invoked if any of the previously
   * >   registered signal handlers (if any) return a value other than
   * >   GST_AUTOPLUG_SELECT_TRY. Which also means that if you return
   * >   GST_AUTOPLUG_SELECT_TRY from one signal handler, handlers that get
   * >   registered next (again, if any) can override that decision.
   *
   * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
   * operation. the default handler will always return
   * #GST_AUTOPLUG_SELECT_TRY.
   */
  gst_parse_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
      g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_select),
      _gst_select_accumulator, NULL,
      g_cclosure_marshal_generic,
      GST_TYPE_AUTOPLUG_SELECT_RESULT, 3, GST_TYPE_PAD, GST_TYPE_CAPS,
      GST_TYPE_ELEMENT_FACTORY);

  /**
   * GstParseBin::autoplug-query:
   * @bin: The ParseBin.
   * @child: The child element doing the query
   * @pad: The #GstPad.
   * @element: The #GstElement.
   * @query: The #GstQuery.
   *
   * This signal is emitted whenever an autoplugged element that is
   * not linked downstream yet and not exposed does a query. It can
   * be used to tell the element about the downstream supported caps
   * for example.
   *
   * Returns: #TRUE if the query was handled, #FALSE otherwise.
   */
  gst_parse_bin_signals[SIGNAL_AUTOPLUG_QUERY] =
      g_signal_new ("autoplug-query", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, autoplug_query),
      _gst_boolean_or_accumulator, NULL, g_cclosure_marshal_generic,
      G_TYPE_BOOLEAN, 3, GST_TYPE_PAD, GST_TYPE_ELEMENT,
      GST_TYPE_QUERY | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GstParseBin::drained
   * @bin: The ParseBin
   *
   * This signal is emitted once ParseBin has finished parsing all the data.
   */
  gst_parse_bin_signals[SIGNAL_DRAINED] =
      g_signal_new ("drained", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstParseBinClass, drained),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);

  g_object_class_install_property (gobject_klass, PROP_SUBTITLE_ENCODING,
      g_param_spec_string ("subtitle-encoding", "subtitle encoding",
          "Encoding to assume if input subtitles are not in UTF-8 encoding. "
          "If not set, the GST_SUBTITLE_ENCODING environment variable will "
          "be checked for an encoding to use. If that is not set either, "
          "ISO-8859-15 will be assumed.", NULL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_klass, PROP_SINK_CAPS,
      g_param_spec_boxed ("sink-caps", "Sink Caps",
          "The caps of the input data. (NULL = use typefind element)",
          GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstParseBin::expose-all-streams
   *
   * Expose streams of unknown type.
   *
   * If set to %FALSE, then only the streams that can be parsed to the final
   * caps (see 'caps' property) will have a pad exposed. Streams that do not
   * match those caps but could have been parsed will not have parser plugged
   * in internally and will not have a pad exposed.
   */
  g_object_class_install_property (gobject_klass, PROP_EXPOSE_ALL_STREAMS,
      g_param_spec_boolean ("expose-all-streams", "Expose All Streams",
          "Expose all streams, including those of unknown type or that don't match the 'caps' property",
          DEFAULT_EXPOSE_ALL_STREAMS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstParseBin2::connection-speed
   *
   * Network connection speed in kbps (0 = unknownw)
   */
  g_object_class_install_property (gobject_klass, PROP_CONNECTION_SPEED,
      g_param_spec_uint64 ("connection-speed", "Connection Speed",
          "Network connection speed in kbps (0 = unknown)",
          0, G_MAXUINT64 / 1000, DEFAULT_CONNECTION_SPEED,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));



  klass->autoplug_continue =
      GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_continue);
  klass->autoplug_factories =
      GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_factories);
  klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_sort);
  klass->autoplug_select = GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_select);
  klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_parse_bin_autoplug_query);

  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&parse_bin_sink_template));
  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&parse_bin_src_template));

  gst_element_class_set_static_metadata (gstelement_klass,
      "Parse Bin", "Generic/Bin/Parser",
      "Parse and de-multiplex to elementary stream",
      "Jan Schmidt <jan@centricular.com>, "
      "Edward Hervey <edward@centricular.com>");

  gstelement_klass->change_state =
      GST_DEBUG_FUNCPTR (gst_parse_bin_change_state);

  gstbin_klass->handle_message =
      GST_DEBUG_FUNCPTR (gst_parse_bin_handle_message);

  g_type_class_ref (GST_TYPE_PARSE_PAD);
}

static void
gst_parse_bin_update_factories_list (GstParseBin * parsebin)
{
  guint cookie;

  cookie = gst_registry_get_feature_list_cookie (gst_registry_get ());
  if (!parsebin->factories || parsebin->factories_cookie != cookie) {
    if (parsebin->factories)
      gst_plugin_feature_list_free (parsebin->factories);
    parsebin->factories =
        gst_element_factory_list_get_elements
        (GST_ELEMENT_FACTORY_TYPE_DECODABLE, GST_RANK_MARGINAL);
    parsebin->factories =
        g_list_sort (parsebin->factories,
        gst_playback_utils_compare_factories_func);
    parsebin->factories_cookie = cookie;
  }
}

static void
gst_parse_bin_init (GstParseBin * parse_bin)
{
  /* first filter out the interesting element factories */
  g_mutex_init (&parse_bin->factories_lock);

  /* we create the typefind element only once */
  parse_bin->typefind = gst_element_factory_make ("typefind", "typefind");
  if (!parse_bin->typefind) {
    g_warning ("can't find typefind element, ParseBin will not work");
  } else {
    GstPad *pad;
    GstPad *gpad;
    GstPadTemplate *pad_tmpl;

    /* add the typefind element */
    if (!gst_bin_add (GST_BIN (parse_bin), parse_bin->typefind)) {
      g_warning ("Could not add typefind element, ParseBin will not work");
      gst_object_unref (parse_bin->typefind);
      parse_bin->typefind = NULL;
    }

    /* get the sinkpad */
    pad = gst_element_get_static_pad (parse_bin->typefind, "sink");

    /* get the pad template */
    pad_tmpl = gst_static_pad_template_get (&parse_bin_sink_template);

    /* ghost the sink pad to ourself */
    gpad = gst_ghost_pad_new_from_template ("sink", pad, pad_tmpl);
    gst_pad_set_active (gpad, TRUE);
    gst_element_add_pad (GST_ELEMENT (parse_bin), gpad);

    gst_object_unref (pad_tmpl);
    gst_object_unref (pad);
  }

  g_mutex_init (&parse_bin->expose_lock);
  parse_bin->parse_chain = NULL;

  g_mutex_init (&parse_bin->dyn_lock);
  parse_bin->shutdown = FALSE;
  parse_bin->blocked_pads = NULL;

  g_mutex_init (&parse_bin->subtitle_lock);

  parse_bin->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);

  parse_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
  parse_bin->connection_speed = DEFAULT_CONNECTION_SPEED;

  GST_OBJECT_FLAG_SET (parse_bin, GST_BIN_FLAG_STREAMS_AWARE);
}

static void
gst_parse_bin_dispose (GObject * object)
{
  GstParseBin *parse_bin;

  parse_bin = GST_PARSE_BIN (object);

  if (parse_bin->factories)
    gst_plugin_feature_list_free (parse_bin->factories);
  parse_bin->factories = NULL;

  if (parse_bin->parse_chain)
    gst_parse_chain_free (parse_bin->parse_chain);
  parse_bin->parse_chain = NULL;

  g_free (parse_bin->encoding);
  parse_bin->encoding = NULL;

  g_list_free (parse_bin->subtitles);
  parse_bin->subtitles = NULL;

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

static void
gst_parse_bin_finalize (GObject * object)
{
  GstParseBin *parse_bin;

  parse_bin = GST_PARSE_BIN (object);

  g_mutex_clear (&parse_bin->expose_lock);
  g_mutex_clear (&parse_bin->dyn_lock);
  g_mutex_clear (&parse_bin->subtitle_lock);
  g_mutex_clear (&parse_bin->factories_lock);

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

static void
gst_parse_bin_set_sink_caps (GstParseBin * parsebin, GstCaps * caps)
{
  GST_DEBUG_OBJECT (parsebin, "Setting new caps: %" GST_PTR_FORMAT, caps);

  g_object_set (parsebin->typefind, "force-caps", caps, NULL);
}

static GstCaps *
gst_parse_bin_get_sink_caps (GstParseBin * parsebin)
{
  GstCaps *caps;

  GST_DEBUG_OBJECT (parsebin, "Getting currently set caps");

  g_object_get (parsebin->typefind, "force-caps", &caps, NULL);

  return caps;
}

static void
gst_parse_bin_set_subs_encoding (GstParseBin * parsebin, const gchar * encoding)
{
  GList *walk;

  GST_DEBUG_OBJECT (parsebin, "Setting new encoding: %s",
      GST_STR_NULL (encoding));

  SUBTITLE_LOCK (parsebin);
  g_free (parsebin->encoding);
  parsebin->encoding = g_strdup (encoding);

  /* set the subtitle encoding on all added elements */
  for (walk = parsebin->subtitles; walk; walk = g_list_next (walk)) {
    g_object_set (G_OBJECT (walk->data), "subtitle-encoding",
        parsebin->encoding, NULL);
  }
  SUBTITLE_UNLOCK (parsebin);
}

static gchar *
gst_parse_bin_get_subs_encoding (GstParseBin * parsebin)
{
  gchar *encoding;

  GST_DEBUG_OBJECT (parsebin, "Getting currently set encoding");

  SUBTITLE_LOCK (parsebin);
  encoding = g_strdup (parsebin->encoding);
  SUBTITLE_UNLOCK (parsebin);

  return encoding;
}

static void
gst_parse_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstParseBin *parsebin;

  parsebin = GST_PARSE_BIN (object);

  switch (prop_id) {
    case PROP_SUBTITLE_ENCODING:
      gst_parse_bin_set_subs_encoding (parsebin, g_value_get_string (value));
      break;
    case PROP_SINK_CAPS:
      gst_parse_bin_set_sink_caps (parsebin, g_value_get_boxed (value));
      break;
    case PROP_EXPOSE_ALL_STREAMS:
      parsebin->expose_allstreams = g_value_get_boolean (value);
      break;
    case PROP_CONNECTION_SPEED:
      GST_OBJECT_LOCK (parsebin);
      parsebin->connection_speed = g_value_get_uint64 (value) * 1000;
      GST_OBJECT_UNLOCK (parsebin);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_parse_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstParseBin *parsebin;

  parsebin = GST_PARSE_BIN (object);
  switch (prop_id) {
    case PROP_SUBTITLE_ENCODING:
      g_value_take_string (value, gst_parse_bin_get_subs_encoding (parsebin));
      break;
    case PROP_SINK_CAPS:
      g_value_take_boxed (value, gst_parse_bin_get_sink_caps (parsebin));
      break;
    case PROP_EXPOSE_ALL_STREAMS:
      g_value_set_boolean (value, parsebin->expose_allstreams);
      break;
    case PROP_CONNECTION_SPEED:
      GST_OBJECT_LOCK (parsebin);
      g_value_set_uint64 (value, parsebin->connection_speed / 1000);
      GST_OBJECT_UNLOCK (parsebin);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


/*****
 * Default autoplug signal handlers
 *****/
static gboolean
gst_parse_bin_autoplug_continue (GstElement * element, GstPad * pad,
    GstCaps * caps)
{
  GST_DEBUG_OBJECT (element, "autoplug-continue returns TRUE");

  /* by default we always continue */
  return TRUE;
}

static GValueArray *
gst_parse_bin_autoplug_factories (GstElement * element, GstPad * pad,
    GstCaps * caps)
{
  GList *list, *tmp;
  GValueArray *result;
  GstParseBin *parsebin = GST_PARSE_BIN_CAST (element);

  GST_DEBUG_OBJECT (element, "finding factories");

  /* return all compatible factories for caps */
  g_mutex_lock (&parsebin->factories_lock);
  gst_parse_bin_update_factories_list (parsebin);
  list =
      gst_element_factory_list_filter (parsebin->factories, caps, GST_PAD_SINK,
      gst_caps_is_fixed (caps));
  g_mutex_unlock (&parsebin->factories_lock);

  result = g_value_array_new (g_list_length (list));
  for (tmp = list; tmp; tmp = tmp->next) {
    GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (tmp->data);
    GValue val = { 0, };

    g_value_init (&val, G_TYPE_OBJECT);
    g_value_set_object (&val, factory);
    g_value_array_append (result, &val);
    g_value_unset (&val);
  }
  gst_plugin_feature_list_free (list);

  GST_DEBUG_OBJECT (element, "autoplug-factories returns %p", result);

  return result;
}

static GValueArray *
gst_parse_bin_autoplug_sort (GstElement * element, GstPad * pad,
    GstCaps * caps, GValueArray * factories)
{
  return NULL;
}

static GstAutoplugSelectResult
gst_parse_bin_autoplug_select (GstElement * element, GstPad * pad,
    GstCaps * caps, GstElementFactory * factory)
{
  /* Try factory. */
  return GST_AUTOPLUG_SELECT_TRY;
}

static gboolean
gst_parse_bin_autoplug_query (GstElement * element, GstPad * pad,
    GstQuery * query)
{
  /* No query handled here */
  return FALSE;
}

/********
 * Discovery methods
 *****/

static gboolean is_demuxer_element (GstElement * srcelement);

static gboolean connect_pad (GstParseBin * parsebin, GstElement * src,
    GstParsePad * parsepad, GstPad * pad, GstCaps * caps,
    GValueArray * factories, GstParseChain * chain, gchar ** deadend_details);
static GList *connect_element (GstParseBin * parsebin, GstParseElement * pelem,
    GstParseChain * chain);
static void expose_pad (GstParseBin * parsebin, GstElement * src,
    GstParsePad * parsepad, GstPad * pad, GstCaps * caps,
    GstParseChain * chain);

static void pad_added_cb (GstElement * element, GstPad * pad,
    GstParseChain * chain);
static void pad_removed_cb (GstElement * element, GstPad * pad,
    GstParseChain * chain);
static void no_more_pads_cb (GstElement * element, GstParseChain * chain);

static GstParseGroup *gst_parse_chain_get_current_group (GstParseChain * chain);

static gboolean
clear_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  GST_DEBUG_OBJECT (pad, "clearing sticky event %" GST_PTR_FORMAT, *event);
  gst_event_unref (*event);
  *event = NULL;
  return TRUE;
}

static gboolean
copy_sticky_events (GstPad * pad, GstEvent ** eventptr, gpointer user_data)
{
  GstParsePad *ppad = GST_PARSE_PAD (user_data);
  GstEvent *event = gst_event_ref (*eventptr);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:{
      GstCaps *caps = NULL;
      gst_event_parse_caps (event, &caps);
      gst_parse_pad_update_caps (ppad, caps);
      break;
    }
    case GST_EVENT_STREAM_START:{
      event = gst_parse_pad_stream_start_event (ppad, event);
      break;
    }
    case GST_EVENT_STREAM_COLLECTION:{
      GstStreamCollection *collection = NULL;
      gst_event_parse_stream_collection (event, &collection);
      gst_parse_pad_update_stream_collection (ppad, collection);
      break;
    }
    default:
      break;
  }

  GST_DEBUG_OBJECT (ppad, "store sticky event %" GST_PTR_FORMAT, event);
  gst_pad_store_sticky_event (GST_PAD_CAST (ppad), event);
  gst_event_unref (event);

  return TRUE;
}

static void
parse_pad_set_target (GstParsePad * parsepad, GstPad * target)
{
  GstPad *old_target = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (parsepad));
  if (old_target)
    gst_object_unref (old_target);

  if (old_target == target)
    return;

  gst_pad_sticky_events_foreach (GST_PAD_CAST (parsepad),
      clear_sticky_events, NULL);
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (parsepad), target);

  if (target == NULL) {
    GST_LOG_OBJECT (parsepad->parsebin, "Setting pad %" GST_PTR_FORMAT
        " target to NULL", parsepad);
  } else {
    GST_LOG_OBJECT (parsepad->parsebin, "Setting pad %" GST_PTR_FORMAT
        " target to %" GST_PTR_FORMAT, parsepad, target);
    gst_pad_sticky_events_foreach (target, copy_sticky_events, parsepad);
  }
}

/* called when a new pad is discovered. It will perform some basic actions
 * before trying to link something to it.
 *
 *  - Check the caps, don't do anything when there are no caps or when they have
 *    no good type.
 *  - signal AUTOPLUG_CONTINUE to check if we need to continue autoplugging this
 *    pad.
 *  - if the caps are non-fixed, setup a handler to continue autoplugging when
 *    the caps become fixed (connect to notify::caps).
 *  - get list of factories to autoplug.
 *  - continue autoplugging to one of the factories.
 */
static void
analyze_new_pad (GstParseBin * parsebin, GstElement * src, GstPad * pad,
    GstCaps * caps, GstParseChain * chain)
{
  gboolean apcontinue = TRUE;
  GValueArray *factories = NULL, *result = NULL;
  GstParsePad *parsepad;
  GstElementFactory *factory;
  const gchar *classification;
  gboolean is_parser_converter = FALSE;
  gboolean res;
  gchar *deadend_details = NULL;

  GST_DEBUG_OBJECT (parsebin, "Pad %s:%s caps:%" GST_PTR_FORMAT,
      GST_DEBUG_PAD_NAME (pad), caps);

  if (chain->elements
      && src != ((GstParseElement *) chain->elements->data)->element
      && src != ((GstParseElement *) chain->elements->data)->capsfilter) {
    GST_ERROR_OBJECT (parsebin,
        "New pad from not the last element in this chain");
    return;
  }

  if (chain->demuxer) {
    GstParseGroup *group;
    GstParseChain *oldchain = chain;
    GstParseElement *demux = (chain->elements ? chain->elements->data : NULL);

    if (chain->current_pad)
      gst_object_unref (chain->current_pad);
    chain->current_pad = NULL;

    /* we are adding a new pad for a demuxer (see is_demuxer_element(),
     * start a new chain for it */
    CHAIN_MUTEX_LOCK (oldchain);
    group = gst_parse_chain_get_current_group (chain);
    if (group && !g_list_find (group->children, chain)) {
      chain = gst_parse_chain_new (parsebin, group, pad, caps);
      group->children = g_list_prepend (group->children, chain);
    }
    CHAIN_MUTEX_UNLOCK (oldchain);
    if (!group) {
      GST_WARNING_OBJECT (parsebin, "No current group");
      return;
    }

    /* If this is not a dynamic pad demuxer, we're no-more-pads
     * already before anything else happens
     */
    if (demux == NULL || !demux->no_more_pads_id)
      group->no_more_pads = TRUE;
  }

  /* From here on we own a reference to the caps as
   * we might create new caps below and would need
   * to unref them later */
  if (caps)
    gst_caps_ref (caps);

  if ((caps == NULL) || gst_caps_is_empty (caps))
    goto unknown_type;

  if (gst_caps_is_any (caps))
    goto any_caps;

  if (!chain->current_pad)
    chain->current_pad = gst_parse_pad_new (parsebin, chain);

  parsepad = gst_object_ref (chain->current_pad);
  gst_pad_set_active (GST_PAD_CAST (parsepad), TRUE);
  parse_pad_set_target (parsepad, pad);

  /* 1. Emit 'autoplug-continue' the result will tell us if this pads needs
   * further autoplugging. Only do this for fixed caps, for unfixed caps
   * we will later come here again from the notify::caps handler. The
   * problem with unfixed caps is that, we can't reliably tell if the output
   * is e.g. accepted by a sink because only parts of the possible final
   * caps might be accepted by the sink. */
  if (gst_caps_is_fixed (caps))
    g_signal_emit (G_OBJECT (parsebin),
        gst_parse_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, parsepad, caps,
        &apcontinue);
  else
    apcontinue = TRUE;

  /* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
  if (!apcontinue)
    goto expose_pad;

  /* 1.b For Parser/Converter that can output different stream formats
   * we insert a capsfilter with the sorted caps of all possible next
   * elements and continue with the capsfilter srcpad */
  factory = gst_element_get_factory (src);
  classification =
      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
  is_parser_converter = (strstr (classification, "Parser")
      && strstr (classification, "Converter"));

  /* FIXME: We just need to be sure that the next element is not a parser */
  /* 1.c when the caps are not fixed yet, we can't be sure what element to
   * connect. We delay autoplugging until the caps are fixed */
  if (!is_parser_converter && !gst_caps_is_fixed (caps)) {
    goto non_fixed;
  } else if (!is_parser_converter) {
    gst_caps_unref (caps);
    caps = gst_pad_get_current_caps (pad);
    if (!caps) {
      GST_DEBUG_OBJECT (parsebin,
          "No final caps set yet, delaying autoplugging");
      gst_object_unref (parsepad);
      goto setup_caps_delay;
    }
  }

  /* 1.d else get the factories and if there's no compatible factory goto
   * unknown_type */
  g_signal_emit (G_OBJECT (parsebin),
      gst_parse_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, parsepad, caps,
      &factories);

  /* NULL means that we can expose the pad */
  if (factories == NULL)
    goto expose_pad;

  /* if the array is empty, we have a type for which we have no parser */
  if (factories->n_values == 0) {
    /* if not we have a unhandled type with no compatible factories */
    g_value_array_free (factories);
    gst_object_unref (parsepad);
    goto unknown_type;
  }

  /* 1.e sort some more. */
  g_signal_emit (G_OBJECT (parsebin),
      gst_parse_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, parsepad, caps, factories,
      &result);
  if (result) {
    g_value_array_free (factories);
    factories = result;
  }

  /* 1.g now get the factory template caps and insert the capsfilter if this
   * is a parser/converter
   */
  if (is_parser_converter) {
    GstCaps *filter_caps;
    gint i;
    GstPad *p;
    GstParseElement *pelem;

    g_assert (chain->elements != NULL);
    pelem = (GstParseElement *) chain->elements->data;

    filter_caps = gst_caps_new_empty ();
    for (i = 0; i < factories->n_values; i++) {
      GstElementFactory *factory =
          g_value_get_object (g_value_array_get_nth (factories, i));
      GstCaps *tcaps, *intersection;
      const GList *tmps;

      GST_DEBUG ("Trying factory %s",
          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));

      if (gst_element_get_factory (src) == factory ||
          gst_element_factory_list_is_type (factory,
              GST_ELEMENT_FACTORY_TYPE_PARSER)) {
        GST_DEBUG ("Skipping factory");
        continue;
      }

      for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
          tmps = tmps->next) {
        GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
        if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
          continue;
        tcaps = gst_static_pad_template_get_caps (st);
        intersection =
            gst_caps_intersect_full (tcaps, caps, GST_CAPS_INTERSECT_FIRST);
        filter_caps = gst_caps_merge (filter_caps, intersection);
        gst_caps_unref (tcaps);
      }
    }

    /* Append the parser caps to prevent any not-negotiated errors */
    filter_caps = gst_caps_merge (filter_caps, gst_caps_ref (caps));

    pelem->capsfilter = gst_element_factory_make ("capsfilter", NULL);
    g_object_set (G_OBJECT (pelem->capsfilter), "caps", filter_caps, NULL);
    gst_caps_unref (filter_caps);
    gst_element_set_state (pelem->capsfilter, GST_STATE_PAUSED);
    gst_bin_add (GST_BIN_CAST (parsebin), gst_object_ref (pelem->capsfilter));

    parse_pad_set_target (parsepad, NULL);
    p = gst_element_get_static_pad (pelem->capsfilter, "sink");
    gst_pad_link_full (pad, p, GST_PAD_LINK_CHECK_NOTHING);
    gst_object_unref (p);
    p = gst_element_get_static_pad (pelem->capsfilter, "src");
    parse_pad_set_target (parsepad, p);
    pad = p;

    gst_caps_unref (caps);

    caps = gst_pad_get_current_caps (pad);
    if (!caps) {
      GST_DEBUG_OBJECT (parsebin,
          "No final caps set yet, delaying autoplugging");
      gst_object_unref (parsepad);
      g_value_array_free (factories);
      goto setup_caps_delay;
    }
  }

  /* 1.h else continue autoplugging something from the list. */
  GST_LOG_OBJECT (pad, "Let's continue discovery on this pad");
  res =
      connect_pad (parsebin, src, parsepad, pad, caps, factories, chain,
      &deadend_details);

  /* Need to unref the capsfilter srcpad here if
   * we inserted a capsfilter */
  if (is_parser_converter)
    gst_object_unref (pad);

  gst_object_unref (parsepad);
  g_value_array_free (factories);

  if (!res)
    goto unknown_type;

  gst_caps_unref (caps);

  return;

expose_pad:
  {
    GST_LOG_OBJECT (parsebin, "Pad is final. autoplug-continue:%d", apcontinue);
    expose_pad (parsebin, src, parsepad, pad, caps, chain);
    gst_object_unref (parsepad);
    gst_caps_unref (caps);
    return;
  }

unknown_type:
  {
    GST_LOG_OBJECT (pad, "Unknown type, posting message and firing signal");

    chain->deadend_details = deadend_details;
    chain->deadend = TRUE;
    chain->endcaps = caps;
    gst_object_replace ((GstObject **) & chain->current_pad, NULL);

    gst_element_post_message (GST_ELEMENT_CAST (parsebin),
        gst_missing_decoder_message_new (GST_ELEMENT_CAST (parsebin), caps));

    g_signal_emit (G_OBJECT (parsebin),
        gst_parse_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);

    /* Try to expose anything */
    EXPOSE_LOCK (parsebin);
    if (parsebin->parse_chain) {
      if (gst_parse_chain_is_complete (parsebin->parse_chain)) {
        gst_parse_bin_expose (parsebin);
      }
    }
    EXPOSE_UNLOCK (parsebin);

    if (src == parsebin->typefind) {
      if (!caps || gst_caps_is_empty (caps)) {
        GST_ELEMENT_ERROR (parsebin, STREAM, TYPE_NOT_FOUND,
            (_("Could not determine type of stream")), (NULL));
      }
      do_async_done (parsebin);
    }
    return;
  }
#if 1
non_fixed:
  {
    GST_DEBUG_OBJECT (pad, "pad has non-fixed caps delay autoplugging");
    gst_object_unref (parsepad);
    goto setup_caps_delay;
  }
#endif
any_caps:
  {
    GST_DEBUG_OBJECT (pad, "pad has ANY caps, delaying auto-plugging");
    goto setup_caps_delay;
  }
setup_caps_delay:
  {
    GstPendingPad *ppad;

    /* connect to caps notification */
    CHAIN_MUTEX_LOCK (chain);
    GST_LOG_OBJECT (parsebin, "Chain %p has now %d dynamic pads", chain,
        g_list_length (chain->pending_pads));
    ppad = g_slice_new0 (GstPendingPad);
    ppad->pad = gst_object_ref (pad);
    ppad->chain = chain;
    ppad->event_probe_id =
        gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
        pad_event_cb, ppad, NULL);
    chain->pending_pads = g_list_prepend (chain->pending_pads, ppad);
    ppad->notify_caps_id = g_signal_connect (pad, "notify::caps",
        G_CALLBACK (caps_notify_cb), chain);
    CHAIN_MUTEX_UNLOCK (chain);

    /* If we're here because we have a Parser/Converter
     * we have to unref the pad */
    if (is_parser_converter)
      gst_object_unref (pad);
    if (caps)
      gst_caps_unref (caps);

    return;
  }
}

static void
add_error_filter (GstParseBin * parsebin, GstElement * element)
{
  GST_OBJECT_LOCK (parsebin);
  parsebin->filtered = g_list_prepend (parsebin->filtered, element);
  GST_OBJECT_UNLOCK (parsebin);
}

static void
remove_error_filter (GstParseBin * parsebin, GstElement * element,
    GstMessage ** error)
{
  GList *l;

  GST_OBJECT_LOCK (parsebin);
  parsebin->filtered = g_list_remove (parsebin->filtered, element);

  if (error)
    *error = NULL;

  l = parsebin->filtered_errors;
  while (l) {
    GstMessage *msg = l->data;

    if (GST_MESSAGE_SRC (msg) == GST_OBJECT_CAST (element)) {
      /* Get the last error of this element, i.e. the earliest */
      if (error)
        gst_message_replace (error, msg);
      gst_message_unref (msg);
      l = parsebin->filtered_errors =
          g_list_delete_link (parsebin->filtered_errors, l);
    } else {
      l = l->next;
    }
  }
  GST_OBJECT_UNLOCK (parsebin);
}

typedef struct
{
  gboolean ret;
  GstPad *peer;
} SendStickyEventsData;

static gboolean
send_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  SendStickyEventsData *data = user_data;
  gboolean ret;

  ret = gst_pad_send_event (data->peer, gst_event_ref (*event));
  if (!ret)
    data->ret = FALSE;

  return data->ret;
}

static gboolean
send_sticky_events (GstParseBin * parsebin, GstPad * pad)
{
  SendStickyEventsData data;

  data.ret = TRUE;
  data.peer = gst_pad_get_peer (pad);

  gst_pad_sticky_events_foreach (pad, send_sticky_event, &data);

  gst_object_unref (data.peer);

  return data.ret;
}

static gchar *
error_message_to_string (GstMessage * msg)
{
  GError *err;
  gchar *debug, *message, *full_message;

  gst_message_parse_error (msg, &err, &debug);

  message = gst_error_get_message (err->domain, err->code);

  if (debug)
    full_message = g_strdup_printf ("%s\n%s\n%s", message, err->message, debug);
  else
    full_message = g_strdup_printf ("%s\n%s", message, err->message);

  g_free (message);
  g_free (debug);
  g_clear_error (&err);

  return full_message;
}

/* We consider elements as "simple demuxer" when they are a demuxer
 * with one and only one ALWAYS source pad.
 */
static gboolean
is_simple_demuxer_factory (GstElementFactory * factory)
{
  if (strstr (gst_element_factory_get_metadata (factory,
              GST_ELEMENT_METADATA_KLASS), "Demuxer")) {
    const GList *tmp;
    gint num_alway_srcpads = 0;

    for (tmp = gst_element_factory_get_static_pad_templates (factory);
        tmp; tmp = tmp->next) {
      GstStaticPadTemplate *template = tmp->data;

      if (template->direction == GST_PAD_SRC) {
        if (template->presence == GST_PAD_ALWAYS) {
          if (num_alway_srcpads >= 0)
            num_alway_srcpads++;
        } else {
          num_alway_srcpads = -1;
        }
      }

    }

    if (num_alway_srcpads == 1)
      return TRUE;
  }

  return FALSE;
}

/* connect_pad:
 *
 * Try to connect the given pad to an element created from one of the factories,
 * and recursively.
 *
 * Note that parsepad is ghosting pad, and so pad is linked; be sure to unset parsepad's
 * target before trying to link pad.
 *
 * Returns TRUE if an element was properly created and linked
 */
static gboolean
connect_pad (GstParseBin * parsebin, GstElement * src, GstParsePad * parsepad,
    GstPad * pad, GstCaps * caps, GValueArray * factories,
    GstParseChain * chain, gchar ** deadend_details)
{
  gboolean res = FALSE;
  GString *error_details = NULL;

  g_return_val_if_fail (factories != NULL, FALSE);
  g_return_val_if_fail (factories->n_values > 0, FALSE);

  GST_DEBUG_OBJECT (parsebin,
      "pad %s:%s , chain:%p, %d factories, caps %" GST_PTR_FORMAT,
      GST_DEBUG_PAD_NAME (pad), chain, factories->n_values, caps);

  error_details = g_string_new ("");

  /* 2. Try to create an element and link to it */
  while (factories->n_values > 0) {
    GstAutoplugSelectResult ret;
    GstElementFactory *factory;
    GstParseElement *pelem;
    GstElement *element;
    GstPad *sinkpad;
    GParamSpec *pspec;
    gboolean subtitle;
    GList *to_connect = NULL;
    gboolean is_parser_converter = FALSE, is_simple_demuxer = FALSE;

    /* Set parsepad target to pad again, it might've been unset
     * below but we came back here because something failed
     */
    parse_pad_set_target (parsepad, pad);

    /* take first factory */
    factory = g_value_get_object (g_value_array_get_nth (factories, 0));
    /* Remove selected factory from the list. */
    g_value_array_remove (factories, 0);

    GST_LOG_OBJECT (src, "trying factory %" GST_PTR_FORMAT, factory);

    /* Check if the caps are really supported by the factory. The
     * factory list is non-empty-subset filtered while caps
     * are only accepted by a pad if they are a subset of the
     * pad caps.
     *
     * FIXME: Only do this for fixed caps here. Non-fixed caps
     * can happen if a Parser/Converter was autoplugged before
     * this. We then assume that it will be able to convert to
     * everything that the parser would want.
     *
     * A subset check will fail here because the parser caps
     * will be generic and while the parser will only
     * support a subset of the parser caps.
     */
    if (gst_caps_is_fixed (caps)) {
      const GList *templs;
      gboolean skip = FALSE;

      templs = gst_element_factory_get_static_pad_templates (factory);

      while (templs) {
        GstStaticPadTemplate *templ = (GstStaticPadTemplate *) templs->data;

        if (templ->direction == GST_PAD_SINK) {
          GstCaps *templcaps = gst_static_caps_get (&templ->static_caps);

          if (!gst_caps_is_subset (caps, templcaps)) {
            GST_DEBUG_OBJECT (src,
                "caps %" GST_PTR_FORMAT " not subset of %" GST_PTR_FORMAT, caps,
                templcaps);
            gst_caps_unref (templcaps);
            skip = TRUE;
            break;
          }

          gst_caps_unref (templcaps);
        }
        templs = g_list_next (templs);
      }
      if (skip)
        continue;
    }

    /* If the factory is for a parser we first check if the factory
     * was already used for the current chain. If it was used already
     * we would otherwise create an infinite loop here because the
     * parser apparently accepts its own output as input.
     * This is only done for parsers because it's perfectly valid
     * to have other element classes after each other because a
     * parser is the only one that does not change the data. A
     * valid example for this would be multiple id3demux in a row.
     */
    is_parser_converter = strstr (gst_element_factory_get_metadata (factory,
            GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;
    is_simple_demuxer = is_simple_demuxer_factory (factory);

    if (is_parser_converter) {
      gboolean skip = FALSE;
      GList *l;

      CHAIN_MUTEX_LOCK (chain);
      for (l = chain->elements; l; l = l->next) {
        GstParseElement *pelem = (GstParseElement *) l->data;
        GstElement *otherelement = pelem->element;

        if (gst_element_get_factory (otherelement) == factory) {
          skip = TRUE;
          break;
        }
      }

      if (!skip && chain->parent && chain->parent->parent) {
        GstParseChain *parent_chain = chain->parent->parent;
        GstParseElement *pelem =
            parent_chain->elements ? parent_chain->elements->data : NULL;

        if (pelem && gst_element_get_factory (pelem->element) == factory)
          skip = TRUE;
      }
      CHAIN_MUTEX_UNLOCK (chain);
      if (skip) {
        GST_DEBUG_OBJECT (parsebin,
            "Skipping factory '%s' because it was already used in this chain",
            gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory)));
        continue;
      }

    }

    /* Expose pads if the next factory is a decoder */
    if (gst_element_factory_list_is_type (factory,
            GST_ELEMENT_FACTORY_TYPE_DECODER)) {
      ret = GST_AUTOPLUG_SELECT_EXPOSE;
    } else {
      /* emit autoplug-select to see what we should do with it. */
      g_signal_emit (G_OBJECT (parsebin),
          gst_parse_bin_signals[SIGNAL_AUTOPLUG_SELECT],
          0, parsepad, caps, factory, &ret);
    }

    switch (ret) {
      case GST_AUTOPLUG_SELECT_TRY:
        GST_DEBUG_OBJECT (parsebin, "autoplug select requested try");
        break;
      case GST_AUTOPLUG_SELECT_EXPOSE:
        GST_DEBUG_OBJECT (parsebin, "autoplug select requested expose");
        /* expose the pad, we don't have the source element */
        expose_pad (parsebin, src, parsepad, pad, caps, chain);
        res = TRUE;
        goto beach;
      case GST_AUTOPLUG_SELECT_SKIP:
        GST_DEBUG_OBJECT (parsebin, "autoplug select requested skip");
        continue;
      default:
        GST_WARNING_OBJECT (parsebin, "autoplug select returned unhandled %d",
            ret);
        break;
    }

    /* 2.0. Unlink pad */
    parse_pad_set_target (parsepad, NULL);

    /* 2.1. Try to create an element */
    if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
      GST_WARNING_OBJECT (parsebin, "Could not create an element from %s",
          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
      g_string_append_printf (error_details,
          "Could not create an element from %s\n",
          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
      continue;
    }

    /* Filter errors, this will prevent the element from causing the pipeline
     * to error while we test it using READY state. */
    add_error_filter (parsebin, element);

    /* We don't yet want the bin to control the element's state */
    gst_element_set_locked_state (element, TRUE);

    /* ... add it ... */
    if (!(gst_bin_add (GST_BIN_CAST (parsebin), element))) {
      GST_WARNING_OBJECT (parsebin, "Couldn't add %s to the bin",
          GST_ELEMENT_NAME (element));
      remove_error_filter (parsebin, element, NULL);
      g_string_append_printf (error_details, "Couldn't add %s to the bin\n",
          GST_ELEMENT_NAME (element));
      gst_object_unref (element);
      continue;
    }

    /* Find its sink pad. */
    sinkpad = NULL;
    GST_OBJECT_LOCK (element);
    if (element->sinkpads != NULL)
      sinkpad = gst_object_ref (element->sinkpads->data);
    GST_OBJECT_UNLOCK (element);

    if (sinkpad == NULL) {
      GST_WARNING_OBJECT (parsebin, "Element %s doesn't have a sink pad",
          GST_ELEMENT_NAME (element));
      remove_error_filter (parsebin, element, NULL);
      g_string_append_printf (error_details,
          "Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
      gst_bin_remove (GST_BIN (parsebin), element);
      continue;
    }

    /* ... and try to link */
    if ((gst_pad_link_full (pad, sinkpad,
                GST_PAD_LINK_CHECK_NOTHING)) != GST_PAD_LINK_OK) {
      GST_WARNING_OBJECT (parsebin, "Link failed on pad %s:%s",
          GST_DEBUG_PAD_NAME (sinkpad));
      remove_error_filter (parsebin, element, NULL);
      g_string_append_printf (error_details, "Link failed on pad %s:%s",
          GST_DEBUG_PAD_NAME (sinkpad));
      gst_object_unref (sinkpad);
      gst_bin_remove (GST_BIN (parsebin), element);
      continue;
    }

    /* ... activate it ... */
    if ((gst_element_set_state (element,
                GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) {
      GstMessage *error_msg;

      GST_WARNING_OBJECT (parsebin, "Couldn't set %s to READY",
          GST_ELEMENT_NAME (element));
      remove_error_filter (parsebin, element, &error_msg);

      if (error_msg) {
        gchar *error_string = error_message_to_string (error_msg);
        g_string_append_printf (error_details, "Couldn't set %s to READY:\n%s",
            GST_ELEMENT_NAME (element), error_string);
        gst_message_unref (error_msg);
        g_free (error_string);
      } else {
        g_string_append_printf (error_details, "Couldn't set %s to READY",
            GST_ELEMENT_NAME (element));
      }
      gst_object_unref (sinkpad);
      gst_bin_remove (GST_BIN (parsebin), element);
      continue;
    }

    /* check if we still accept the caps on the pad after setting
     * the element to READY */
    if (!gst_pad_query_accept_caps (sinkpad, caps)) {
      GstMessage *error_msg;

      GST_WARNING_OBJECT (parsebin, "Element %s does not accept caps",
          GST_ELEMENT_NAME (element));

      remove_error_filter (parsebin, element, &error_msg);

      if (error_msg) {
        gchar *error_string = error_message_to_string (error_msg);
        g_string_append_printf (error_details,
            "Element %s does not accept caps:\n%s", GST_ELEMENT_NAME (element),
            error_string);
        gst_message_unref (error_msg);
        g_free (error_string);
      } else {
        g_string_append_printf (error_details,
            "Element %s does not accept caps", GST_ELEMENT_NAME (element));
      }

      gst_element_set_state (element, GST_STATE_NULL);
      gst_object_unref (sinkpad);
      gst_bin_remove (GST_BIN (parsebin), element);
      continue;
    }

    gst_object_unref (sinkpad);
    GST_LOG_OBJECT (parsebin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad));

    CHAIN_MUTEX_LOCK (chain);
    pelem = g_slice_new0 (GstParseElement);
    pelem->element = gst_object_ref (element);
    pelem->capsfilter = NULL;
    chain->elements = g_list_prepend (chain->elements, pelem);
    chain->demuxer = is_demuxer_element (element);

    /* If we plugging a parser, mark the chain as parsed */
    chain->parsed |= is_parser_converter;

    CHAIN_MUTEX_UNLOCK (chain);

    /* Set connection-speed property if needed */
    if (chain->demuxer) {
      GParamSpec *pspec;

      if ((pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
                  "connection-speed"))) {
        guint64 speed = parsebin->connection_speed / 1000;
        gboolean wrong_type = FALSE;

        if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT) {
          GParamSpecUInt *pspecuint = G_PARAM_SPEC_UINT (pspec);

          speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
        } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT) {
          GParamSpecInt *pspecint = G_PARAM_SPEC_INT (pspec);

          speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
        } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_UINT64) {
          GParamSpecUInt64 *pspecuint = G_PARAM_SPEC_UINT64 (pspec);

          speed = CLAMP (speed, pspecuint->minimum, pspecuint->maximum);
        } else if (G_PARAM_SPEC_TYPE (pspec) == G_TYPE_PARAM_INT64) {
          GParamSpecInt64 *pspecint = G_PARAM_SPEC_INT64 (pspec);

          speed = CLAMP (speed, pspecint->minimum, pspecint->maximum);
        } else {
          GST_WARNING_OBJECT (parsebin,
              "The connection speed property %" G_GUINT64_FORMAT " of type %s"
              " is not usefull not setting it", speed,
              g_type_name (G_PARAM_SPEC_TYPE (pspec)));
          wrong_type = TRUE;
        }

        if (!wrong_type) {
          GST_DEBUG_OBJECT (parsebin,
              "setting connection-speed=%" G_GUINT64_FORMAT
              " to demuxer element", speed);

          g_object_set (element, "connection-speed", speed, NULL);
        }
      }
    }

    /* try to configure the subtitle encoding property when we can */
    pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (element),
        "subtitle-encoding");
    if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
      SUBTITLE_LOCK (parsebin);
      GST_DEBUG_OBJECT (parsebin,
          "setting subtitle-encoding=%s to element", parsebin->encoding);
      g_object_set (G_OBJECT (element), "subtitle-encoding", parsebin->encoding,
          NULL);
      SUBTITLE_UNLOCK (parsebin);
      subtitle = TRUE;
    } else {
      subtitle = FALSE;
    }

    /* link this element further */
    to_connect = connect_element (parsebin, pelem, chain);

    if ((is_simple_demuxer || is_parser_converter) && to_connect) {
      GList *l;
      for (l = to_connect; l; l = g_list_next (l)) {
        GstPad *opad = GST_PAD_CAST (l->data);
        GstCaps *ocaps;

        ocaps = get_pad_caps (opad);
        analyze_new_pad (parsebin, pelem->element, opad, ocaps, chain);
        if (ocaps)
          gst_caps_unref (ocaps);

        gst_object_unref (opad);
      }
      g_list_free (to_connect);
      to_connect = NULL;
    }

    /* Bring the element to the state of the parent */

    /* First lock element's sinkpad stream lock so no data reaches
     * the possible new element added when caps are sent by element
     * while we're still sending sticky events */
    GST_PAD_STREAM_LOCK (sinkpad);

    if ((gst_element_set_state (element,
                GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) {
      GstParseElement *dtmp = NULL;
      GstElement *tmp = NULL;
      GstMessage *error_msg;

      GST_PAD_STREAM_UNLOCK (sinkpad);

      GST_WARNING_OBJECT (parsebin, "Couldn't set %s to PAUSED",
          GST_ELEMENT_NAME (element));

      g_list_free_full (to_connect, (GDestroyNotify) gst_object_unref);
      to_connect = NULL;

      remove_error_filter (parsebin, element, &error_msg);

      if (error_msg) {
        gchar *error_string = error_message_to_string (error_msg);
        g_string_append_printf (error_details, "Couldn't set %s to PAUSED:\n%s",
            GST_ELEMENT_NAME (element), error_string);
        gst_message_unref (error_msg);
        g_free (error_string);
      } else {
        g_string_append_printf (error_details, "Couldn't set %s to PAUSED",
            GST_ELEMENT_NAME (element));
      }

      /* Remove all elements in this chain that were just added. No
       * other thread could've added elements in the meantime */
      CHAIN_MUTEX_LOCK (chain);
      do {
        GList *l;

        dtmp = chain->elements->data;
        tmp = dtmp->element;

        /* Disconnect any signal handlers that might be connected
         * in connect_element() or analyze_pad() */
        if (dtmp->pad_added_id)
          g_signal_handler_disconnect (tmp, dtmp->pad_added_id);
        if (dtmp->pad_removed_id)
          g_signal_handler_disconnect (tmp, dtmp->pad_removed_id);
        if (dtmp->no_more_pads_id)
          g_signal_handler_disconnect (tmp, dtmp->no_more_pads_id);

        for (l = chain->pending_pads; l;) {
          GstPendingPad *pp = l->data;
          GList *n;

          if (GST_PAD_PARENT (pp->pad) != tmp) {
            l = l->next;
            continue;
          }

          gst_pending_pad_free (pp);

          /* Remove element from the list, update list head and go to the
           * next element in the list */
          n = l->next;
          chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
          l = n;
        }

        if (dtmp->capsfilter) {
          gst_bin_remove (GST_BIN (parsebin), dtmp->capsfilter);
          gst_element_set_state (dtmp->capsfilter, GST_STATE_NULL);
          gst_object_unref (dtmp->capsfilter);
        }

        gst_bin_remove (GST_BIN (parsebin), tmp);
        gst_element_set_state (tmp, GST_STATE_NULL);

        gst_object_unref (tmp);
        g_slice_free (GstParseElement, dtmp);

        chain->elements = g_list_delete_link (chain->elements, chain->elements);
      } while (tmp != element);
      CHAIN_MUTEX_UNLOCK (chain);

      continue;
    } else {
      send_sticky_events (parsebin, pad);
      /* Everything went well, the spice must flow now */
      GST_PAD_STREAM_UNLOCK (sinkpad);
    }

    /* Remove error filter now, from now on we can't gracefully
     * handle errors of the element anymore */
    remove_error_filter (parsebin, element, NULL);

    /* Now let the bin handle the state */
    gst_element_set_locked_state (element, FALSE);

    if (subtitle) {
      SUBTITLE_LOCK (parsebin);
      /* we added the element now, add it to the list of subtitle-encoding
       * elements when we can set the property */
      parsebin->subtitles = g_list_prepend (parsebin->subtitles, element);
      SUBTITLE_UNLOCK (parsebin);
    }

    if (to_connect) {
      GList *l;
      for (l = to_connect; l; l = g_list_next (l)) {
        GstPad *opad = GST_PAD_CAST (l->data);
        GstCaps *ocaps;

        ocaps = get_pad_caps (opad);
        analyze_new_pad (parsebin, pelem->element, opad, ocaps, chain);
        if (ocaps)
          gst_caps_unref (ocaps);

        gst_object_unref (opad);
      }
      g_list_free (to_connect);
      to_connect = NULL;
    }

    res = TRUE;
    break;
  }

beach:
  if (error_details)
    *deadend_details = g_string_free (error_details, (error_details->len == 0
            || res));
  else
    *deadend_details = NULL;

  return res;
}

static GstCaps *
get_pad_caps (GstPad * pad)
{
  GstCaps *caps;

  /* first check the pad caps, if this is set, we are positively sure it is
   * fixed and exactly what the element will produce. */
  caps = gst_pad_get_current_caps (pad);

  /* then use the getcaps function if we don't have caps. These caps might not
   * be fixed in some cases, in which case analyze_new_pad will set up a
   * notify::caps signal to continue autoplugging. */
  if (caps == NULL)
    caps = gst_pad_query_caps (pad, NULL);

  return caps;
}

/* Returns a list of pads that can be connected to already and
 * connects to pad-added and related signals */
static GList *
connect_element (GstParseBin * parsebin, GstParseElement * pelem,
    GstParseChain * chain)
{
  GstElement *element = pelem->element;
  GList *pads;
  gboolean dynamic = FALSE;
  GList *to_connect = NULL;

  GST_DEBUG_OBJECT (parsebin,
      "Attempting to connect element %s [chain:%p] further",
      GST_ELEMENT_NAME (element), chain);

  /* 1. Loop over pad templates, grabbing existing pads along the way */
  for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
      pads = g_list_next (pads)) {
    GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
    const gchar *templ_name;

    /* we are only interested in source pads */
    if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
      continue;

    templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
    GST_DEBUG_OBJECT (parsebin, "got a source pad template %s", templ_name);

    /* figure out what kind of pad this is */
    switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
      case GST_PAD_ALWAYS:
      {
        /* get the pad that we need to autoplug */
        GstPad *pad = gst_element_get_static_pad (element, templ_name);

        if (pad) {
          GST_DEBUG_OBJECT (parsebin, "got the pad for always template %s",
              templ_name);
          /* here is the pad, we need to autoplug it */
          to_connect = g_list_prepend (to_connect, pad);
        } else {
          /* strange, pad is marked as always but it's not
           * there. Fix the element */
          GST_WARNING_OBJECT (parsebin,
              "could not get the pad for always template %s", templ_name);
        }
        break;
      }
      case GST_PAD_SOMETIMES:
      {
        /* try to get the pad to see if it is already created or
         * not */
        GstPad *pad = gst_element_get_static_pad (element, templ_name);

        if (pad) {
          GST_DEBUG_OBJECT (parsebin, "got the pad for sometimes template %s",
              templ_name);
          /* the pad is created, we need to autoplug it */
          to_connect = g_list_prepend (to_connect, pad);
        } else {
          GST_DEBUG_OBJECT (parsebin,
              "did not get the sometimes pad of template %s", templ_name);
          /* we have an element that will create dynamic pads */
          dynamic = TRUE;
        }
        break;
      }
      case GST_PAD_REQUEST:
        /* ignore request pads */
        GST_DEBUG_OBJECT (parsebin, "ignoring request padtemplate %s",
            templ_name);
        break;
    }
  }

  /* 2. if there are more potential pads, connect to relevant signals */
  if (dynamic) {
    GST_LOG_OBJECT (parsebin, "Adding signals to element %s in chain %p",
        GST_ELEMENT_NAME (element), chain);
    pelem->pad_added_id = g_signal_connect (element, "pad-added",
        G_CALLBACK (pad_added_cb), chain);
    pelem->pad_removed_id = g_signal_connect (element, "pad-removed",
        G_CALLBACK (pad_removed_cb), chain);
    pelem->no_more_pads_id = g_signal_connect (element, "no-more-pads",
        G_CALLBACK (no_more_pads_cb), chain);
  }

  /* 3. return all pads that can be connected to already */

  return to_connect;
}

/* expose_pad:
 *
 * Expose the given pad on the chain as a parsed pad.
 */
static void
expose_pad (GstParseBin * parsebin, GstElement * src, GstParsePad * parsepad,
    GstPad * pad, GstCaps * caps, GstParseChain * chain)
{
  GST_DEBUG_OBJECT (parsebin, "pad %s:%s, chain:%p",
      GST_DEBUG_PAD_NAME (pad), chain);

  gst_parse_pad_activate (parsepad, chain);
  chain->endpad = gst_object_ref (parsepad);
  if (caps)
    chain->endcaps = gst_caps_ref (caps);
  else
    chain->endcaps = NULL;
}

static void
type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstParseBin * parse_bin)
{
  GstPad *pad, *sink_pad;

  GST_DEBUG_OBJECT (parse_bin, "typefind found caps %" GST_PTR_FORMAT, caps);

  /* If the typefinder (but not something else) finds text/plain - i.e. that's
   * the top-level type of the file - then error out.
   */
  if (gst_structure_has_name (gst_caps_get_structure (caps, 0), "text/plain")) {
    GST_ELEMENT_ERROR (parse_bin, STREAM, WRONG_TYPE,
        (_("This appears to be a text file")),
        ("ParseBin cannot parse plain text files"));
    goto exit;
  }

  /* FIXME: we can only deal with one type, we don't yet support dynamically changing
   * caps from the typefind element */
  if (parse_bin->have_type || parse_bin->parse_chain)
    goto exit;

  parse_bin->have_type = TRUE;

  pad = gst_element_get_static_pad (typefind, "src");
  sink_pad = gst_element_get_static_pad (typefind, "sink");

  /* need some lock here to prevent race with shutdown state change
   * which might yank away e.g. parse_chain while building stuff here.
   * In typical cases, STREAM_LOCK is held and handles that, it need not
   * be held (if called from a proxied setcaps), so grab it anyway */
  GST_PAD_STREAM_LOCK (sink_pad);
  parse_bin->parse_chain = gst_parse_chain_new (parse_bin, NULL, pad, caps);
  analyze_new_pad (parse_bin, typefind, pad, caps, parse_bin->parse_chain);
  GST_PAD_STREAM_UNLOCK (sink_pad);

  gst_object_unref (sink_pad);
  gst_object_unref (pad);

exit:
  return;
}

static GstPadProbeReturn
pad_event_cb (GstPad * pad, GstPadProbeInfo * info, gpointer data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstPendingPad *ppad = (GstPendingPad *) data;
  GstParseChain *chain = ppad->chain;
  GstParseBin *parsebin = chain->parsebin;

  g_assert (ppad);
  g_assert (chain);
  g_assert (parsebin);
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      GST_DEBUG_OBJECT (pad, "Received EOS on a non final pad, this stream "
          "ended too early");
      chain->deadend = TRUE;
      chain->drained = TRUE;
      gst_object_replace ((GstObject **) & chain->current_pad, NULL);
      /* we don't set the endcaps because NULL endcaps means early EOS */

      EXPOSE_LOCK (parsebin);
      if (parsebin->parse_chain)
        if (gst_parse_chain_is_complete (parsebin->parse_chain))
          gst_parse_bin_expose (parsebin);
      EXPOSE_UNLOCK (parsebin);
      break;
    default:
      break;
  }
  return GST_PAD_PROBE_OK;
}

static void
pad_added_cb (GstElement * element, GstPad * pad, GstParseChain * chain)
{
  GstCaps *caps;
  GstParseBin *parsebin;

  parsebin = chain->parsebin;

  GST_DEBUG_OBJECT (pad, "pad added, chain:%p", chain);

  caps = get_pad_caps (pad);
  analyze_new_pad (parsebin, element, pad, caps, chain);
  if (caps)
    gst_caps_unref (caps);

  EXPOSE_LOCK (parsebin);
  if (parsebin->parse_chain) {
    if (gst_parse_chain_is_complete (parsebin->parse_chain)) {
      GST_LOG_OBJECT (parsebin,
          "That was the last dynamic object, now attempting to expose the group");
      if (!gst_parse_bin_expose (parsebin))
        GST_WARNING_OBJECT (parsebin, "Couldn't expose group");
    }
  } else {
    GST_DEBUG_OBJECT (parsebin, "No parse chain, new pad ignored");
  }
  EXPOSE_UNLOCK (parsebin);
}

static void
pad_removed_cb (GstElement * element, GstPad * pad, GstParseChain * chain)
{
  GList *l;

  GST_LOG_OBJECT (pad, "pad removed, chain:%p", chain);

  /* In fact, we don't have to do anything here, the active group will be
   * removed when the group's multiqueue is drained */
  CHAIN_MUTEX_LOCK (chain);
  for (l = chain->pending_pads; l; l = l->next) {
    GstPendingPad *ppad = l->data;
    GstPad *opad = ppad->pad;

    if (pad == opad) {
      gst_pending_pad_free (ppad);
      chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
      break;
    }
  }
  CHAIN_MUTEX_UNLOCK (chain);
}

static void
no_more_pads_cb (GstElement * element, GstParseChain * chain)
{
  GstParseGroup *group = NULL;

  GST_LOG_OBJECT (element, "got no more pads");

  CHAIN_MUTEX_LOCK (chain);
  if (!chain->elements
      || ((GstParseElement *) chain->elements->data)->element != element) {
    GST_LOG_OBJECT (chain->parsebin, "no-more-pads from old chain element '%s'",
        GST_OBJECT_NAME (element));
    CHAIN_MUTEX_UNLOCK (chain);
    return;
  } else if (!chain->demuxer) {
    GST_LOG_OBJECT (chain->parsebin,
        "no-more-pads from a non-demuxer element '%s'",
        GST_OBJECT_NAME (element));
    CHAIN_MUTEX_UNLOCK (chain);
    return;
  }

  /* when we received no_more_pads, we can complete the pads of the chain */
  if (!chain->next_groups && chain->active_group) {
    group = chain->active_group;
  } else if (chain->next_groups) {
    GList *iter;
    for (iter = chain->next_groups; iter; iter = g_list_next (iter)) {
      group = iter->data;
      if (!group->no_more_pads)
        break;
    }
  }
  if (!group) {
    GST_ERROR_OBJECT (chain->parsebin, "can't find group for element");
    CHAIN_MUTEX_UNLOCK (chain);
    return;
  }

  GST_DEBUG_OBJECT (element, "Setting group %p to complete", group);

  group->no_more_pads = TRUE;
  CHAIN_MUTEX_UNLOCK (chain);

  EXPOSE_LOCK (chain->parsebin);
  if (chain->parsebin->parse_chain) {
    if (gst_parse_chain_is_complete (chain->parsebin->parse_chain)) {
      gst_parse_bin_expose (chain->parsebin);
    }
  }
  EXPOSE_UNLOCK (chain->parsebin);
}

static void
caps_notify_cb (GstPad * pad, GParamSpec * unused, GstParseChain * chain)
{
  GstElement *element;
  GList *l;

  GST_LOG_OBJECT (pad, "Notified caps for pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  /* Disconnect this; if we still need it, we'll reconnect to this in
   * analyze_new_pad */
  element = GST_ELEMENT_CAST (gst_pad_get_parent (pad));

  CHAIN_MUTEX_LOCK (chain);
  for (l = chain->pending_pads; l; l = l->next) {
    GstPendingPad *ppad = l->data;
    if (ppad->pad == pad) {
      gst_pending_pad_free (ppad);
      chain->pending_pads = g_list_delete_link (chain->pending_pads, l);
      break;
    }
  }
  CHAIN_MUTEX_UNLOCK (chain);

  pad_added_cb (element, pad, chain);

  gst_object_unref (element);
}

/* Decide whether an element is a demuxer based on the
 * klass and number/type of src pad templates it has */
static gboolean
is_demuxer_element (GstElement * srcelement)
{
  GstElementFactory *srcfactory;
  GstElementClass *elemclass;
  GList *walk;
  const gchar *klass;
  gint potential_src_pads = 0;

  srcfactory = gst_element_get_factory (srcelement);
  klass =
      gst_element_factory_get_metadata (srcfactory, GST_ELEMENT_METADATA_KLASS);

  /* Can't be a demuxer unless it has Demux in the klass name */
  if (!strstr (klass, "Demux"))
    return FALSE;

  /* Walk the src pad templates and count how many the element
   * might produce */
  elemclass = GST_ELEMENT_GET_CLASS (srcelement);

  walk = gst_element_class_get_pad_template_list (elemclass);
  while (walk != NULL) {
    GstPadTemplate *templ;

    templ = (GstPadTemplate *) walk->data;
    if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
      switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
        case GST_PAD_ALWAYS:
        case GST_PAD_SOMETIMES:
          if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
            potential_src_pads += 2;    /* Might make multiple pads */
          else
            potential_src_pads += 1;
          break;
        case GST_PAD_REQUEST:
          potential_src_pads += 2;
          break;
      }
    }
    walk = g_list_next (walk);
  }

  if (potential_src_pads < 2)
    return FALSE;

  return TRUE;
}

/* gst_parse_chain_get_current_group:
 *
 * Returns the current group of this chain, to which
 * new chains should be attached or NULL if the last
 * group didn't have no-more-pads.
 *
 * Not MT-safe: Call with parent chain lock!
 */
static GstParseGroup *
gst_parse_chain_get_current_group (GstParseChain * chain)
{
  GstParseGroup *group;

  /* Now we know that we can really return something useful */
  if (!chain->active_group) {
    chain->active_group = group = gst_parse_group_new (chain->parsebin, chain);
  } else if (!chain->active_group->no_more_pads) {
    group = chain->active_group;
  } else {
    GList *iter;
    group = NULL;
    for (iter = chain->next_groups; iter; iter = g_list_next (iter)) {
      GstParseGroup *next_group = iter->data;

      if (!next_group->no_more_pads) {
        group = next_group;
        break;
      }
    }
  }
  if (!group) {
    group = gst_parse_group_new (chain->parsebin, chain);
    chain->next_groups = g_list_append (chain->next_groups, group);
  }

  return group;
}

static void gst_parse_group_free_internal (GstParseGroup * group,
    gboolean hide);

static void
gst_parse_chain_free_internal (GstParseChain * chain, gboolean hide)
{
  GList *l, *set_to_null = NULL;

  CHAIN_MUTEX_LOCK (chain);

  GST_DEBUG_OBJECT (chain->parsebin, "%s chain %p",
      (hide ? "Hiding" : "Freeing"), chain);

  if (chain->active_group) {
    gst_parse_group_free_internal (chain->active_group, hide);
    if (!hide)
      chain->active_group = NULL;
  }

  for (l = chain->next_groups; l; l = l->next) {
    gst_parse_group_free_internal ((GstParseGroup *) l->data, hide);
    if (!hide)
      l->data = NULL;
  }
  if (!hide) {
    g_list_free (chain->next_groups);
    chain->next_groups = NULL;
  }

  if (!hide) {
    for (l = chain->old_groups; l; l = l->next) {
      GstParseGroup *group = l->data;

      gst_parse_group_free (group);
    }
    g_list_free (chain->old_groups);
    chain->old_groups = NULL;
  }

  gst_object_replace ((GstObject **) & chain->current_pad, NULL);

  for (l = chain->pending_pads; l; l = l->next) {
    GstPendingPad *ppad = l->data;
    gst_pending_pad_free (ppad);
    l->data = NULL;
  }
  g_list_free (chain->pending_pads);
  chain->pending_pads = NULL;

  for (l = chain->elements; l; l = l->next) {
    GstParseElement *pelem = l->data;
    GstElement *element = pelem->element;

    if (pelem->pad_added_id)
      g_signal_handler_disconnect (element, pelem->pad_added_id);
    pelem->pad_added_id = 0;
    if (pelem->pad_removed_id)
      g_signal_handler_disconnect (element, pelem->pad_removed_id);
    pelem->pad_removed_id = 0;
    if (pelem->no_more_pads_id)
      g_signal_handler_disconnect (element, pelem->no_more_pads_id);
    pelem->no_more_pads_id = 0;

    if (pelem->capsfilter) {
      if (GST_OBJECT_PARENT (pelem->capsfilter) ==
          GST_OBJECT_CAST (chain->parsebin))
        gst_bin_remove (GST_BIN_CAST (chain->parsebin), pelem->capsfilter);
      if (!hide) {
        set_to_null =
            g_list_append (set_to_null, gst_object_ref (pelem->capsfilter));
      }
    }

    if (GST_OBJECT_PARENT (element) == GST_OBJECT_CAST (chain->parsebin))
      gst_bin_remove (GST_BIN_CAST (chain->parsebin), element);
    if (!hide) {
      set_to_null = g_list_append (set_to_null, gst_object_ref (element));
    }

    SUBTITLE_LOCK (chain->parsebin);
    /* remove possible subtitle element */
    chain->parsebin->subtitles =
        g_list_remove (chain->parsebin->subtitles, element);
    SUBTITLE_UNLOCK (chain->parsebin);

    if (!hide) {
      if (pelem->capsfilter) {
        gst_object_unref (pelem->capsfilter);
        pelem->capsfilter = NULL;
      }

      gst_object_unref (element);
      l->data = NULL;

      g_slice_free (GstParseElement, pelem);
    }
  }
  if (!hide) {
    g_list_free (chain->elements);
    chain->elements = NULL;
  }

  if (chain->endpad) {
    if (chain->endpad->exposed) {
      GstPad *endpad = GST_PAD_CAST (chain->endpad);
      GST_DEBUG_OBJECT (chain->parsebin, "Removing pad %s:%s",
          GST_DEBUG_PAD_NAME (endpad));
      gst_pad_push_event (endpad, gst_event_new_eos ());
      gst_element_remove_pad (GST_ELEMENT_CAST (chain->parsebin), endpad);
    }

    parse_pad_set_target (chain->endpad, NULL);
    chain->endpad->exposed = FALSE;
    if (!hide) {
      gst_object_unref (chain->endpad);
      chain->endpad = NULL;
    }
  }

  if (!hide && chain->current_pad) {
    gst_object_unref (chain->current_pad);
    chain->current_pad = NULL;
  }

  if (chain->pad) {
    gst_object_unref (chain->pad);
    chain->pad = NULL;
  }
  if (chain->start_caps) {
    gst_caps_unref (chain->start_caps);
    chain->start_caps = NULL;
  }

  if (chain->endcaps) {
    gst_caps_unref (chain->endcaps);
    chain->endcaps = NULL;
  }
  g_free (chain->deadend_details);
  chain->deadend_details = NULL;

  GST_DEBUG_OBJECT (chain->parsebin, "%s chain %p", (hide ? "Hidden" : "Freed"),
      chain);
  CHAIN_MUTEX_UNLOCK (chain);

  while (set_to_null) {
    GstElement *element = set_to_null->data;
    set_to_null = g_list_delete_link (set_to_null, set_to_null);
    gst_element_set_state (element, GST_STATE_NULL);
    gst_object_unref (element);
  }

  if (!hide) {
    g_mutex_clear (&chain->lock);
    g_slice_free (GstParseChain, chain);
  }
}

/* gst_parse_chain_free:
 *
 * Completely frees and removes the chain and all
 * child groups from ParseBin.
 *
 * MT-safe, don't hold the chain lock or any child chain's lock
 * when calling this!
 */
static void
gst_parse_chain_free (GstParseChain * chain)
{
  gst_parse_chain_free_internal (chain, FALSE);
}

/* gst_parse_chain_new:
 *
 * Creates a new parse chain and initializes it.
 *
 * It's up to the caller to add it to the list of child chains of
 * a group!
 */
static GstParseChain *
gst_parse_chain_new (GstParseBin * parsebin, GstParseGroup * parent,
    GstPad * pad, GstCaps * start_caps)
{
  GstParseChain *chain = g_slice_new0 (GstParseChain);

  GST_DEBUG_OBJECT (parsebin, "Creating new chain %p with parent group %p",
      chain, parent);

  chain->parsebin = parsebin;
  chain->parent = parent;
  g_mutex_init (&chain->lock);
  chain->pad = gst_object_ref (pad);
  if (start_caps)
    chain->start_caps = gst_caps_ref (start_caps);

  return chain;
}

/****
 * GstParseGroup functions
 ****/

static void
gst_parse_group_free_internal (GstParseGroup * group, gboolean hide)
{
  GList *l;

  GST_DEBUG_OBJECT (group->parsebin, "%s group %p",
      (hide ? "Hiding" : "Freeing"), group);
  for (l = group->children; l; l = l->next) {
    GstParseChain *chain = (GstParseChain *) l->data;

    gst_parse_chain_free_internal (chain, hide);
    if (!hide)
      l->data = NULL;
  }
  if (!hide) {
    g_list_free (group->children);
    group->children = NULL;
  }

  GST_DEBUG_OBJECT (group->parsebin, "%s group %p", (hide ? "Hid" : "Freed"),
      group);
  if (!hide)
    g_slice_free (GstParseGroup, group);
}

/* gst_parse_group_free:
 *
 * Completely frees and removes the parse group and all
 * it's children.
 *
 * Never call this from any streaming thread!
 *
 * Not MT-safe, call with parent's chain lock!
 */
static void
gst_parse_group_free (GstParseGroup * group)
{
  gst_parse_group_free_internal (group, FALSE);
}

/* gst_parse_group_hide:
 *
 * Hide the parse group only, this means that
 * all child endpads are removed from ParseBin
 * and all signals are unconnected.
 *
 * No element is set to NULL state and completely
 * unrefed here.
 *
 * Can be called from streaming threads.
 *
 * Not MT-safe, call with parent's chain lock!
 */
static void
gst_parse_group_hide (GstParseGroup * group)
{
  gst_parse_group_free_internal (group, TRUE);
}

/* gst_parse_chain_free_hidden_groups:
 *
 * Frees any parse groups that were hidden previously.
 * This allows keeping memory use from ballooning when
 * switching chains repeatedly.
 *
 * A new throwaway thread will be created to free the
 * groups, so any delay does not block the setup of a
 * new group.
 *
 * Not MT-safe, call with parent's chain lock!
 */
static void
gst_parse_chain_free_hidden_groups (GList * old_groups)
{
  GList *l;

  for (l = old_groups; l; l = l->next) {
    GstParseGroup *group = l->data;

    gst_parse_group_free (group);
  }
  g_list_free (old_groups);
}

static void
gst_parse_chain_start_free_hidden_groups_thread (GstParseChain * chain)
{
  GThread *thread;
  GError *error = NULL;
  GList *old_groups;

  old_groups = chain->old_groups;
  if (!old_groups)
    return;

  chain->old_groups = NULL;
  thread = g_thread_try_new ("free-hidden-groups",
      (GThreadFunc) gst_parse_chain_free_hidden_groups, old_groups, &error);
  if (!thread || error) {
    GST_ERROR ("Failed to start free-hidden-groups thread: %s",
        error ? error->message : "unknown reason");
    g_clear_error (&error);
    chain->old_groups = old_groups;
    return;
  }
  GST_DEBUG_OBJECT (chain->parsebin, "Started free-hidden-groups thread");
  /* We do not need to wait for it or get any results from it */
  g_thread_unref (thread);
}

/* gst_parse_group_new:
 * @parsebin: Parent ParseBin
 * @parent: Parent chain or %NULL
 *
 * Creates a new GstParseGroup. It is up to the caller to add it to the list
 * of groups.
 */
static GstParseGroup *
gst_parse_group_new (GstParseBin * parsebin, GstParseChain * parent)
{
  GstParseGroup *group = g_slice_new0 (GstParseGroup);

  GST_DEBUG_OBJECT (parsebin, "Creating new group %p with parent chain %p",
      group, parent);

  group->parsebin = parsebin;
  group->parent = parent;

  return group;
}

/* gst_parse_group_is_complete:
 *
 * Checks if the group is complete, this means that
 * a) no-more-pads happened
 * b) all child chains are complete
 *
 * Not MT-safe, always call with ParseBin expose lock
 */
static gboolean
gst_parse_group_is_complete (GstParseGroup * group)
{
  GList *l;
  gboolean complete = TRUE;

  if (!group->no_more_pads) {
    complete = FALSE;
    goto out;
  }

  for (l = group->children; l; l = l->next) {
    GstParseChain *chain = l->data;

    /* Any blocked chain requires we complete this group
     * since everything is synchronous, we can't proceed otherwise */
    if (chain->endpad && chain->endpad->blocked)
      goto out;

    if (!gst_parse_chain_is_complete (chain)) {
      complete = FALSE;
      goto out;
    }
  }

out:
  GST_DEBUG_OBJECT (group->parsebin, "Group %p is complete: %d", group,
      complete);
  return complete;
}

/* gst_parse_chain_is_complete:
 *
 * Returns TRUE if the chain is complete, this means either
 * a) This chain is a dead end, i.e. we have no suitable plugins
 * b) This chain ends in an endpad and this is blocked or exposed
 * c) The chain has gotten far enough to have plugged 1 parser at least.
 *
 * Not MT-safe, always call with ParseBin expose lock
 */
static gboolean
gst_parse_chain_is_complete (GstParseChain * chain)
{
  gboolean complete = FALSE;

  CHAIN_MUTEX_LOCK (chain);
  if (chain->parsebin->shutdown)
    goto out;

  if (chain->deadend) {
    complete = TRUE;
    goto out;
  }

  if (chain->endpad && (chain->endpad->blocked || chain->endpad->exposed)) {
    complete = TRUE;
    goto out;
  }

  if (chain->demuxer) {
    if (chain->active_group
        && gst_parse_group_is_complete (chain->active_group)) {
      complete = TRUE;
      goto out;
    }
  }

  if (chain->parsed) {
    complete = TRUE;
    goto out;
  }

out:
  CHAIN_MUTEX_UNLOCK (chain);
  GST_DEBUG_OBJECT (chain->parsebin, "Chain %p is complete: %d", chain,
      complete);
  return complete;
}

static void
chain_remove_old_groups (GstParseChain * chain)
{
  GList *tmp;

  /* First go in child */
  if (chain->active_group) {
    for (tmp = chain->active_group->children; tmp; tmp = tmp->next) {
      GstParseChain *child = (GstParseChain *) tmp->data;
      chain_remove_old_groups (child);
    }
  }

  if (chain->old_groups) {
    gst_parse_group_hide (chain->old_groups->data);
    gst_parse_chain_start_free_hidden_groups_thread (chain);
  }
}

static gboolean
drain_and_switch_chains (GstParseChain * chain, GstParsePad * drainpad,
    gboolean * last_group, gboolean * drained, gboolean * switched);
/* drain_and_switch_chains/groups:
 *
 * CALL WITH CHAIN LOCK (or group parent) TAKEN !
 *
 * Goes down the chains/groups until it finds the chain
 * to which the drainpad belongs.
 *
 * It marks that pad/chain as drained and then will figure
 * out which group to switch to or not.
 *
 * last_chain will be set to TRUE if the group to which the
 * pad belongs is the last one.
 *
 * drained will be set to TRUE if the chain/group is drained.
 *
 * Returns: TRUE if the chain contained the target pad */
static gboolean
drain_and_switch_group (GstParseGroup * group, GstParsePad * drainpad,
    gboolean * last_group, gboolean * drained, gboolean * switched)
{
  gboolean handled = FALSE;
  GList *tmp;

  GST_DEBUG ("Checking group %p (target pad %s:%s)",
      group, GST_DEBUG_PAD_NAME (drainpad));

  /* Definitely can't be in drained groups */
  if (G_UNLIKELY (group->drained)) {
    goto beach;
  }

  /* Figure out if all our chains are drained with the
   * new information */
  group->drained = TRUE;
  for (tmp = group->children; tmp; tmp = tmp->next) {
    GstParseChain *chain = (GstParseChain *) tmp->data;
    gboolean subdrained = FALSE;

    handled |=
        drain_and_switch_chains (chain, drainpad, last_group, &subdrained,
        switched);
    if (!subdrained)
      group->drained = FALSE;
  }

beach:
  GST_DEBUG ("group %p (last_group:%d, drained:%d, switched:%d, handled:%d)",
      group, *last_group, group->drained, *switched, handled);
  *drained = group->drained;
  return handled;
}

static gboolean
drain_and_switch_chains (GstParseChain * chain, GstParsePad * drainpad,
    gboolean * last_group, gboolean * drained, gboolean * switched)
{
  gboolean handled = FALSE;
  GstParseBin *parsebin = chain->parsebin;

  GST_DEBUG ("Checking chain %p %s:%s (target pad %s:%s)",
      chain, GST_DEBUG_PAD_NAME (chain->pad), GST_DEBUG_PAD_NAME (drainpad));

  CHAIN_MUTEX_LOCK (chain);

  /* Definitely can't be in drained chains */
  if (G_UNLIKELY (chain->drained)) {
    goto beach;
  }

  if (chain->endpad) {
    /* Check if we're reached the target endchain */
    if (drainpad != NULL && chain == drainpad->chain) {
      GST_DEBUG ("Found the target chain");
      drainpad->drained = TRUE;
      handled = TRUE;
    }

    chain->drained = chain->endpad->drained;
    goto beach;
  }

  /* We known there are groups to switch to */
  if (chain->next_groups)
    *last_group = FALSE;

  /* Check the active group */
  if (chain->active_group) {
    gboolean subdrained = FALSE;
    handled = drain_and_switch_group (chain->active_group, drainpad,
        last_group, &subdrained, switched);

    /* The group is drained, see if we can switch to another */
    if ((handled || drainpad == NULL) && subdrained && !*switched) {
      if (chain->next_groups) {
        /* Switch to next group, the actual removal of the current group will
         * be done when the next one is activated */
        GST_DEBUG_OBJECT (parsebin, "Moving current group %p to old groups",
            chain->active_group);
        chain->old_groups =
            g_list_prepend (chain->old_groups, chain->active_group);
        GST_DEBUG_OBJECT (parsebin, "Switching to next group %p",
            chain->next_groups->data);
        chain->active_group = chain->next_groups->data;
        chain->next_groups =
            g_list_delete_link (chain->next_groups, chain->next_groups);
        *switched = TRUE;
        chain->drained = FALSE;
      } else {
        GST_DEBUG ("Group %p was the last in chain %p", chain->active_group,
            chain);
        chain->drained = TRUE;
        /* We're drained ! */
      }
    } else {
      if (subdrained && !chain->next_groups)
        *drained = TRUE;
    }
  }

beach:
  CHAIN_MUTEX_UNLOCK (chain);

  GST_DEBUG ("Chain %p (handled:%d, last_group:%d, drained:%d, switched:%d)",
      chain, handled, *last_group, chain->drained, *switched);

  *drained = chain->drained;

  if (*drained)
    g_signal_emit (parsebin, gst_parse_bin_signals[SIGNAL_DRAINED], 0, NULL);

  return handled;
}

/* check if the group is drained, meaning all pads have seen an EOS
 * event.  */
static gboolean
gst_parse_pad_handle_eos (GstParsePad * pad)
{
  gboolean last_group = TRUE;
  gboolean switched = FALSE;
  gboolean drained = FALSE;
  GstParseChain *chain = pad->chain;
  GstParseBin *parsebin = chain->parsebin;

  GST_LOG_OBJECT (parsebin, "pad %p", pad);
  EXPOSE_LOCK (parsebin);
  if (parsebin->parse_chain) {
    drain_and_switch_chains (parsebin->parse_chain, pad, &last_group, &drained,
        &switched);

    if (switched) {
      /* If we resulted in a group switch, expose what's needed */
      if (gst_parse_chain_is_complete (parsebin->parse_chain))
        gst_parse_bin_expose (parsebin);
    }
  }
  EXPOSE_UNLOCK (parsebin);

  return last_group;
}

/* gst_parse_group_is_drained:
 *
 * Check is this group is drained and cache this result.
 * The group is drained if all child chains are drained.
 *
 * Not MT-safe, call with group->parent's lock */
static gboolean
gst_parse_group_is_drained (GstParseGroup * group)
{
  GList *l;
  gboolean drained = TRUE;

  if (group->drained) {
    drained = TRUE;
    goto out;
  }

  for (l = group->children; l; l = l->next) {
    GstParseChain *chain = l->data;

    CHAIN_MUTEX_LOCK (chain);
    if (!gst_parse_chain_is_drained (chain))
      drained = FALSE;
    CHAIN_MUTEX_UNLOCK (chain);
    if (!drained)
      goto out;
  }
  group->drained = drained;

out:
  GST_DEBUG_OBJECT (group->parsebin, "Group %p is drained: %d", group, drained);
  return drained;
}

/* gst_parse_chain_is_drained:
 *
 * Check is the chain is drained, which means that
 * either
 *
 * a) it's endpad is drained
 * b) there are no pending pads, the active group is drained
 *    and there are no next groups
 *
 * Not MT-safe, call with chain lock
 */
static gboolean
gst_parse_chain_is_drained (GstParseChain * chain)
{
  gboolean drained = FALSE;

  if (chain->endpad) {
    drained = chain->endpad->drained;
    goto out;
  }

  if (chain->pending_pads) {
    drained = FALSE;
    goto out;
  }

  if (chain->active_group && gst_parse_group_is_drained (chain->active_group)
      && !chain->next_groups) {
    drained = TRUE;
    goto out;
  }

out:
  GST_DEBUG_OBJECT (chain->parsebin, "Chain %p is drained: %d", chain, drained);
  return drained;
}

/* sort_end_pads:
 * GCompareFunc to use with lists of GstPad.
 * Sorts pads by mime type.
 * First video (raw, then non-raw), then audio (raw, then non-raw),
 * then others.
 *
 * Return: negative if a<b, 0 if a==b, positive if a>b
 */
static gint
sort_end_pads (GstParsePad * da, GstParsePad * db)
{
  gint va, vb;
  GstCaps *capsa, *capsb;
  GstStructure *sa, *sb;
  const gchar *namea, *nameb;
  gchar *ida, *idb;
  gint ret;

  capsa = get_pad_caps (GST_PAD_CAST (da));
  capsb = get_pad_caps (GST_PAD_CAST (db));

  sa = gst_caps_get_structure ((const GstCaps *) capsa, 0);
  sb = gst_caps_get_structure ((const GstCaps *) capsb, 0);

  namea = gst_structure_get_name (sa);
  nameb = gst_structure_get_name (sb);

  if (g_strrstr (namea, "video/x-raw"))
    va = 0;
  else if (g_strrstr (namea, "video/"))
    va = 1;
  else if (g_strrstr (namea, "image/"))
    va = 2;
  else if (g_strrstr (namea, "audio/x-raw"))
    va = 3;
  else if (g_strrstr (namea, "audio/"))
    va = 4;
  else
    va = 5;

  if (g_strrstr (nameb, "video/x-raw"))
    vb = 0;
  else if (g_strrstr (nameb, "video/"))
    vb = 1;
  else if (g_strrstr (nameb, "image/"))
    vb = 2;
  else if (g_strrstr (nameb, "audio/x-raw"))
    vb = 3;
  else if (g_strrstr (nameb, "audio/"))
    vb = 4;
  else
    vb = 5;

  gst_caps_unref (capsa);
  gst_caps_unref (capsb);

  if (va != vb)
    return va - vb;

  /* if otherwise the same, sort by stream-id */
  ida = gst_pad_get_stream_id (GST_PAD_CAST (da));
  idb = gst_pad_get_stream_id (GST_PAD_CAST (db));
  ret = (ida) ? ((idb) ? strcmp (ida, idb) : -1) : 1;
  g_free (ida);
  g_free (idb);

  return ret;
}

static gboolean
debug_sticky_event (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  GST_DEBUG_OBJECT (pad, "sticky event %s (%p)", GST_EVENT_TYPE_NAME (*event),
      *event);
  return TRUE;
}

/* Must only be called if the toplevel chain is complete and blocked! */
/* Not MT-safe, call with ParseBin expose lock! */
static gboolean
gst_parse_bin_expose (GstParseBin * parsebin)
{
  GList *tmp, *endpads;
  gboolean missing_plugin;
  GString *missing_plugin_details;
  gboolean already_exposed;
  gboolean last_group;
  gboolean uncollected_streams;
  GstStreamCollection *fallback_collection = NULL;

retry:
  endpads = NULL;
  missing_plugin = FALSE;
  already_exposed = TRUE;
  last_group = TRUE;

  missing_plugin_details = g_string_new ("");

  GST_DEBUG_OBJECT (parsebin, "Exposing currently active chains/groups");

  /* Don't expose if we're currently shutting down */
  DYN_LOCK (parsebin);
  if (G_UNLIKELY (parsebin->shutdown)) {
    GST_WARNING_OBJECT (parsebin,
        "Currently, shutting down, aborting exposing");
    DYN_UNLOCK (parsebin);
    return FALSE;
  }
  DYN_UNLOCK (parsebin);

  /* Get the pads that we're going to expose and mark things as exposed */
  uncollected_streams = FALSE;
  if (!gst_parse_chain_expose (parsebin->parse_chain, &endpads, &missing_plugin,
          missing_plugin_details, &last_group, &uncollected_streams)) {
    g_list_free_full (endpads, (GDestroyNotify) gst_object_unref);
    g_string_free (missing_plugin_details, TRUE);
    GST_ERROR_OBJECT (parsebin, "Broken chain/group tree");
    g_return_val_if_reached (FALSE);
    return FALSE;
  }
  if (endpads == NULL) {
    if (missing_plugin) {
      if (missing_plugin_details->len > 0) {
        gchar *details = g_string_free (missing_plugin_details, FALSE);
        GST_ELEMENT_ERROR (parsebin, CORE, MISSING_PLUGIN, (NULL),
            ("no suitable plugins found:\n%s", details));
        g_free (details);
      } else {
        g_string_free (missing_plugin_details, TRUE);
        GST_ELEMENT_ERROR (parsebin, CORE, MISSING_PLUGIN, (NULL),
            ("no suitable plugins found"));
      }
    } else {
      /* in this case, the stream ended without buffers,
       * just post a warning */
      g_string_free (missing_plugin_details, TRUE);

      GST_WARNING_OBJECT (parsebin, "All streams finished without buffers. "
          "Last group: %d", last_group);
      if (last_group) {
        GST_ELEMENT_ERROR (parsebin, STREAM, FAILED, (NULL),
            ("all streams without buffers"));
      } else {
        gboolean switched = FALSE;
        gboolean drained = FALSE;

        drain_and_switch_chains (parsebin->parse_chain, NULL, &last_group,
            &drained, &switched);
        GST_ELEMENT_WARNING (parsebin, STREAM, FAILED, (NULL),
            ("all streams without buffers"));
        if (switched) {
          if (gst_parse_chain_is_complete (parsebin->parse_chain))
            goto retry;
          else
            return FALSE;
        }
      }
    }

    do_async_done (parsebin);
    return FALSE;
  }

  if (uncollected_streams) {
    /* FIXME: Collect and use a stream id from the top chain as
     * upstream ID? */
    fallback_collection = gst_stream_collection_new (NULL);

    build_fallback_collection (parsebin->parse_chain, fallback_collection);

    gst_element_post_message (GST_ELEMENT (parsebin),
        gst_message_new_stream_collection (GST_OBJECT (parsebin),
            fallback_collection));
  }

  g_string_free (missing_plugin_details, TRUE);

  /* Check if this was called when everything was exposed already,
   * and see if we need to post a new fallback collection */
  for (tmp = endpads; tmp && already_exposed; tmp = tmp->next) {
    GstParsePad *parsepad = tmp->data;

    already_exposed &= parsepad->exposed;
  }
  if (already_exposed) {
    GST_DEBUG_OBJECT (parsebin, "Everything was exposed already!");
    if (fallback_collection)
      gst_object_unref (fallback_collection);
    g_list_free_full (endpads, (GDestroyNotify) gst_object_unref);
    return TRUE;
  }

  /* Set all already exposed pads to blocked */
  for (tmp = endpads; tmp; tmp = tmp->next) {
    GstParsePad *parsepad = tmp->data;

    if (parsepad->exposed) {
      GST_DEBUG_OBJECT (parsepad, "blocking exposed pad");
      gst_parse_pad_set_blocked (parsepad, TRUE);
    }
  }

  /* re-order pads : video, then audio, then others */
  endpads = g_list_sort (endpads, (GCompareFunc) sort_end_pads);

  /* Expose pads */
  for (tmp = endpads; tmp; tmp = tmp->next) {
    GstParsePad *parsepad = (GstParsePad *) tmp->data;
    gchar *padname;

    //if (!parsepad->blocked)
    //continue;

    /* 1. rewrite name */
    padname = g_strdup_printf ("src_%u", parsebin->nbpads);
    parsebin->nbpads++;
    GST_DEBUG_OBJECT (parsebin, "About to expose parsepad %s as %s",
        GST_OBJECT_NAME (parsepad), padname);
    gst_object_set_name (GST_OBJECT (parsepad), padname);
    g_free (padname);

    gst_pad_sticky_events_foreach (GST_PAD_CAST (parsepad), debug_sticky_event,
        parsepad);

    /* 2. activate and add */
    if (!parsepad->exposed) {
      parsepad->exposed = TRUE;
      if (!gst_element_add_pad (GST_ELEMENT (parsebin),
              GST_PAD_CAST (parsepad))) {
        /* not really fatal, we can try to add the other pads */
        g_warning ("error adding pad to ParseBin");
        parsepad->exposed = FALSE;
        continue;
      }
#if 0
      /* HACK: Send an empty gap event to push sticky events */
      gst_pad_push_event (GST_PAD (parsepad),
          gst_event_new_gap (0, GST_CLOCK_TIME_NONE));
#endif
    }

    GST_INFO_OBJECT (parsepad, "added new parsed pad");
  }

  /* Unblock internal pads. The application should have connected stuff now
   * so that streaming can continue. */
  for (tmp = endpads; tmp; tmp = tmp->next) {
    GstParsePad *parsepad = (GstParsePad *) tmp->data;

    if (parsepad->exposed) {
      GST_DEBUG_OBJECT (parsepad, "unblocking");
      gst_parse_pad_unblock (parsepad);
      GST_DEBUG_OBJECT (parsepad, "unblocked");
    }

    /* Send stream-collection events for any pads that don't have them,
     * and post a stream-collection onto the bus */
    if (parsepad->active_collection == NULL && fallback_collection) {
      gst_pad_push_event (GST_PAD (parsepad),
          gst_event_new_stream_collection (fallback_collection));
    }
    gst_object_unref (parsepad);
  }
  g_list_free (endpads);

  if (fallback_collection)
    gst_object_unref (fallback_collection);

  /* Remove old groups */
  chain_remove_old_groups (parsebin->parse_chain);

  do_async_done (parsebin);
  GST_DEBUG_OBJECT (parsebin, "Exposed everything");
  return TRUE;
}

/* gst_parse_chain_expose:
 *
 * Check if the chain can be exposed and add all endpads
 * to the endpads list.
 *
 * Not MT-safe, call with ParseBin expose lock! *
 */
static gboolean
gst_parse_chain_expose (GstParseChain * chain, GList ** endpads,
    gboolean * missing_plugin, GString * missing_plugin_details,
    gboolean * last_group, gboolean * uncollected_streams)
{
  GstParseGroup *group;
  GList *l;
  gboolean ret = FALSE;

  if (chain->deadend) {
    if (chain->endcaps) {
      if (chain->deadend_details) {
        g_string_append (missing_plugin_details, chain->deadend_details);
        g_string_append_c (missing_plugin_details, '\n');
      } else {
        gchar *desc = gst_pb_utils_get_codec_description (chain->endcaps);
        gchar *caps_str = gst_caps_to_string (chain->endcaps);
        g_string_append_printf (missing_plugin_details,
            "Missing parser: %s (%s)\n", desc, caps_str);
        g_free (caps_str);
        g_free (desc);
      }
      *missing_plugin = TRUE;
    }
    return TRUE;
  }

  if (chain->endpad == NULL && chain->parsed && chain->pending_pads) {
    /* The chain has a pending pad from a parser, let's just
     * expose that now as the endpad */
    GList *cur = chain->pending_pads;
    GstPendingPad *ppad = (GstPendingPad *) (cur->data);
    GstPad *endpad = gst_object_ref (ppad->pad);
    GstElement *elem =
        GST_ELEMENT (gst_object_get_parent (GST_OBJECT (endpad)));

    chain->pending_pads = g_list_remove (chain->pending_pads, ppad);

    gst_pending_pad_free (ppad);

    GST_DEBUG_OBJECT (chain->parsebin,
        "Exposing pad %" GST_PTR_FORMAT " with incomplete caps "
        "because it's parsed", endpad);

    expose_pad (chain->parsebin, elem, chain->current_pad, endpad, NULL, chain);
    gst_object_unref (endpad);
    gst_object_unref (elem);
  }

  if (chain->endpad) {
    GstParsePad *p = chain->endpad;

    if (p->active_stream && p->active_collection == NULL
        && !p->in_a_fallback_collection)
      *uncollected_streams = TRUE;

    *endpads = g_list_prepend (*endpads, gst_object_ref (p));
    return TRUE;
  }

  if (chain->next_groups)
    *last_group = FALSE;

  group = chain->active_group;
  if (!group) {
    GstParsePad *p = chain->current_pad;

    if (p->active_stream && p->active_collection == NULL
        && !p->in_a_fallback_collection)
      *uncollected_streams = TRUE;

    return FALSE;
  }

  for (l = group->children; l; l = l->next) {
    GstParseChain *childchain = l->data;

    ret |= gst_parse_chain_expose (childchain, endpads, missing_plugin,
        missing_plugin_details, last_group, uncollected_streams);
  }

  return ret;
}

static void
build_fallback_collection (GstParseChain * chain,
    GstStreamCollection * collection)
{
  GstParseGroup *group = chain->active_group;
  GList *l;

  /* If it's an end pad, or a not-finished chain that's
   * not a group, put it in the collection */
  if (chain->endpad || (chain->current_pad && group == NULL)) {
    GstParsePad *p = chain->current_pad;

    if (p->active_stream != NULL && p->active_collection == NULL) {
      GST_DEBUG_OBJECT (p, "Adding stream to fallback collection");
      gst_stream_collection_add_stream (collection,
          gst_object_ref (p->active_stream));
      p->in_a_fallback_collection = TRUE;
    }
    return;
  }

  if (!group)
    return;

  /* we used g_list_prepend when adding children, so iterate from last
   * to first to maintain the original order they were added in */
  for (l = g_list_last (group->children); l != NULL; l = l->prev) {
    GstParseChain *childchain = l->data;

    build_fallback_collection (childchain, collection);
  }
}

/*************************
 * GstParsePad functions
 *************************/

static void gst_parse_pad_dispose (GObject * object);

static void
gst_parse_pad_class_init (GstParsePadClass * klass)
{
  GObjectClass *gobject_klass;

  gobject_klass = (GObjectClass *) klass;

  gobject_klass->dispose = gst_parse_pad_dispose;
}

static void
gst_parse_pad_init (GstParsePad * pad)
{
  pad->chain = NULL;
  pad->blocked = FALSE;
  pad->exposed = FALSE;
  pad->drained = FALSE;
  gst_object_ref_sink (pad);
}

static void
gst_parse_pad_dispose (GObject * object)
{
  GstParsePad *parsepad = (GstParsePad *) (object);
  parse_pad_set_target (parsepad, NULL);

  gst_object_replace ((GstObject **) & parsepad->active_collection, NULL);
  gst_object_replace ((GstObject **) & parsepad->active_stream, NULL);

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

static GstPadProbeReturn
source_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstParsePad *parsepad = user_data;
  GstParseChain *chain;
  GstParseBin *parsebin;
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM) {
    GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);

    GST_LOG_OBJECT (pad, "Seeing event '%s'", GST_EVENT_TYPE_NAME (event));

    if (!GST_EVENT_IS_SERIALIZED (event)) {
      /* do not block on sticky or out of band events otherwise the allocation query
         from demuxer might block the loop thread */
      GST_LOG_OBJECT (pad, "Letting OOB event through");
      return GST_PAD_PROBE_PASS;
    }

    if (GST_EVENT_IS_STICKY (event) && GST_EVENT_TYPE (event) != GST_EVENT_EOS) {
      GstPad *peer;

      /* manually push sticky events to ghost pad to avoid exposing pads
       * that don't have the sticky events. Handle EOS separately as we
       * want to block the pad on it if we didn't get any buffers before
       * EOS and expose the pad then. */
      peer = gst_pad_get_peer (pad);
      gst_pad_send_event (peer, event);
      gst_object_unref (peer);
      GST_LOG_OBJECT (pad, "Manually pushed sticky event through");
      ret = GST_PAD_PROBE_HANDLED;
      goto done;
    }
  } else if (GST_PAD_PROBE_INFO_TYPE (info) &
      GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM) {
    GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);

    if (!GST_QUERY_IS_SERIALIZED (query)) {
      /* do not block on non-serialized queries */
      GST_LOG_OBJECT (pad, "Letting non-serialized query through");
      return GST_PAD_PROBE_PASS;
    }
    if (!gst_pad_has_current_caps (pad)) {
      /* do not block on allocation queries before we have caps,
       * this would deadlock because we are doing no autoplugging
       * without caps.
       * TODO: Try to do autoplugging based on the query caps
       */
      GST_LOG_OBJECT (pad, "Letting serialized query before caps through");
      return GST_PAD_PROBE_PASS;
    }
  }
  chain = parsepad->chain;
  parsebin = chain->parsebin;

  GST_LOG_OBJECT (parsepad, "blocked: parsepad->chain:%p", chain);

  parsepad->blocked = TRUE;

  EXPOSE_LOCK (parsebin);
  if (parsebin->parse_chain) {
    if (!gst_parse_bin_expose (parsebin))
      GST_WARNING_OBJECT (parsebin, "Couldn't expose group");
  }
  EXPOSE_UNLOCK (parsebin);

done:
  return ret;
}

/* FIXME: We can probably do some cleverer things, and maybe move this into
 * pbutils. Ideas:
 *    if there are tags look if it's got an AUDIO_CODEC VIDEO_CODEC CONTAINER_FORMAT tag
 *    Look at the factory klass designation of parsers in the chain
 *    Consider demuxer pad names as well, sometimes they give the type away
 */
static GstStreamType
guess_stream_type_from_caps (GstCaps * caps)
{
  GstStructure *s;
  const gchar *name;

  if (gst_caps_get_size (caps) < 1)
    return GST_STREAM_TYPE_UNKNOWN;

  s = gst_caps_get_structure (caps, 0);
  name = gst_structure_get_name (s);

  if (g_str_has_prefix (name, "video/") || g_str_has_prefix (name, "image/"))
    return GST_STREAM_TYPE_VIDEO;
  if (g_str_has_prefix (name, "audio/"))
    return GST_STREAM_TYPE_AUDIO;
  if (g_str_has_prefix (name, "text/") ||
      g_str_has_prefix (name, "subpicture/"))
    return GST_STREAM_TYPE_TEXT;

  return GST_STREAM_TYPE_UNKNOWN;
}

static void
gst_parse_pad_update_caps (GstParsePad * parsepad, GstCaps * caps)
{
  if (caps && parsepad->active_stream) {
    GST_DEBUG_OBJECT (parsepad, "Storing caps %" GST_PTR_FORMAT
        " on stream %" GST_PTR_FORMAT, caps, parsepad->active_stream);

    if (gst_caps_is_fixed (caps))
      gst_stream_set_caps (parsepad->active_stream, caps);
    /* intuit a type */
    if (gst_stream_get_stream_type (parsepad->active_stream) ==
        GST_STREAM_TYPE_UNKNOWN) {
      GstStreamType new_type = guess_stream_type_from_caps (caps);
      if (new_type != GST_STREAM_TYPE_UNKNOWN)
        gst_stream_set_stream_type (parsepad->active_stream, new_type);
    }
  }
}

static void
gst_parse_pad_update_tags (GstParsePad * parsepad, GstTagList * tags)
{
  if (tags && gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM
      && parsepad->active_stream) {
    GST_DEBUG_OBJECT (parsepad,
        "Storing new tags %" GST_PTR_FORMAT " on stream %" GST_PTR_FORMAT, tags,
        parsepad->active_stream);
    gst_stream_set_tags (parsepad->active_stream, tags);
  }
}

static GstEvent *
gst_parse_pad_stream_start_event (GstParsePad * parsepad, GstEvent * event)
{
  GstStream *stream = NULL;
  const gchar *stream_id = NULL;
  gboolean repeat_event = FALSE;

  gst_event_parse_stream_start (event, &stream_id);

  if (parsepad->active_stream != NULL &&
      g_str_equal (parsepad->active_stream->stream_id, stream_id))
    repeat_event = TRUE;
  else {
    /* A new stream requires a new collection event, or else
     * we'll place it in a fallback collection later */
    gst_object_replace ((GstObject **) & parsepad->active_collection, NULL);
    parsepad->in_a_fallback_collection = FALSE;
  }

  gst_event_parse_stream (event, &stream);
  if (stream == NULL) {
    GstCaps *caps = gst_pad_get_current_caps (GST_PAD_CAST (parsepad));
    if (caps == NULL) {
      /* Try and get caps from the parsepad peer */
      GstPad *peer = gst_ghost_pad_get_target (GST_GHOST_PAD (parsepad));
      caps = gst_pad_get_current_caps (peer);
      gst_object_unref (peer);
    }
    if (caps == NULL && parsepad->chain && parsepad->chain->start_caps) {
      /* Still no caps, use the chain start caps */
      caps = gst_caps_ref (parsepad->chain->start_caps);
    }

    GST_DEBUG_OBJECT (parsepad,
        "Saw stream_start with no GstStream. Adding one. Caps %"
        GST_PTR_FORMAT, caps);

    if (repeat_event) {
      stream = gst_object_ref (parsepad->active_stream);
    } else {
      stream =
          gst_stream_new (stream_id, NULL, GST_STREAM_TYPE_UNKNOWN,
          GST_STREAM_FLAG_NONE);
      gst_object_replace ((GstObject **) & parsepad->active_stream,
          (GstObject *) stream);
    }
    if (caps) {
      gst_parse_pad_update_caps (parsepad, caps);
      gst_caps_unref (caps);
    }

    event = gst_event_make_writable (event);
    gst_event_set_stream (event, stream);
  }
  gst_object_unref (stream);
  GST_LOG_OBJECT (parsepad, "Saw stream %s (GstStream %p)",
      stream->stream_id, stream);

  return event;
}

static void
gst_parse_pad_update_stream_collection (GstParsePad * parsepad,
    GstStreamCollection * collection)
{
  GST_LOG_OBJECT (parsepad, "Got new stream collection %p", collection);
  gst_object_replace ((GstObject **) & parsepad->active_collection,
      (GstObject *) collection);
  parsepad->in_a_fallback_collection = FALSE;
}

static GstPadProbeReturn
gst_parse_pad_event (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstObject *parent = gst_pad_get_parent (pad);
  GstParsePad *parsepad = GST_PARSE_PAD (parent);
  gboolean forwardit = TRUE;

  GST_LOG_OBJECT (pad, "%s parsepad:%p", GST_EVENT_TYPE_NAME (event), parsepad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:{
      GstCaps *caps = NULL;
      gst_event_parse_caps (event, &caps);
      gst_parse_pad_update_caps (parsepad, caps);
      break;
    }
    case GST_EVENT_TAG:{
      GstTagList *tags;
      gst_event_parse_tag (event, &tags);
      gst_parse_pad_update_tags (parsepad, tags);
      break;
    }
    case GST_EVENT_STREAM_START:{
      GST_PAD_PROBE_INFO_DATA (info) =
          gst_parse_pad_stream_start_event (parsepad, event);
      break;
    }
    case GST_EVENT_STREAM_COLLECTION:{
      GstStreamCollection *collection = NULL;
      gst_event_parse_stream_collection (event, &collection);
      gst_parse_pad_update_stream_collection (parsepad, collection);
      break;
    }
    case GST_EVENT_EOS:{
      GST_DEBUG_OBJECT (pad, "we received EOS");

      /* Check if all pads are drained.
       * * If there is no next group, we will let the EOS go through.
       * * If there is a next group but the current group isn't completely
       *   drained, we will drop the EOS event.
       * * If there is a next group to expose and this was the last non-drained
       *   pad for that group, we will remove the ghostpad of the current group
       *   first, which unlinks the peer and so drops the EOS. */
      forwardit = gst_parse_pad_handle_eos (parsepad);
    }
    default:
      break;
  }
  gst_object_unref (parent);
  if (forwardit)
    return GST_PAD_PROBE_OK;
  else
    return GST_PAD_PROBE_DROP;
}

static void
gst_parse_pad_set_blocked (GstParsePad * parsepad, gboolean blocked)
{
  GstParseBin *parsebin = parsepad->parsebin;
  GstPad *opad;

  DYN_LOCK (parsebin);

  GST_DEBUG_OBJECT (parsepad, "blocking pad: %d", blocked);

  opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (parsepad));
  if (!opad)
    goto out;

  /* do not block if shutting down.
   * we do not consider/expect it blocked further below, but use other trick */
  if (!blocked || !parsebin->shutdown) {
    if (blocked) {
      if (parsepad->block_id == 0)
        parsepad->block_id =
            gst_pad_add_probe (opad,
            GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM |
            GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM, source_pad_blocked_cb,
            gst_object_ref (parsepad), (GDestroyNotify) gst_object_unref);
    } else {
      if (parsepad->block_id != 0) {
        gst_pad_remove_probe (opad, parsepad->block_id);
        parsepad->block_id = 0;
      }
      parsepad->blocked = FALSE;
    }
  }

  if (blocked) {
    if (parsebin->shutdown) {
      /* deactivate to force flushing state to prevent NOT_LINKED errors */
      gst_pad_set_active (GST_PAD_CAST (parsepad), FALSE);
      /* note that deactivating the target pad would have no effect here,
       * since elements are typically connected first (and pads exposed),
       * and only then brought to PAUSED state (so pads activated) */
    } else {
      gst_object_ref (parsepad);
      parsebin->blocked_pads =
          g_list_prepend (parsebin->blocked_pads, parsepad);
    }
  } else {
    GList *l;

    if ((l = g_list_find (parsebin->blocked_pads, parsepad))) {
      gst_object_unref (parsepad);
      parsebin->blocked_pads = g_list_delete_link (parsebin->blocked_pads, l);
    }
  }
  gst_object_unref (opad);
out:
  DYN_UNLOCK (parsebin);
}

static void
gst_parse_pad_activate (GstParsePad * parsepad, GstParseChain * chain)
{
  g_return_if_fail (chain != NULL);

  parsepad->chain = chain;
  gst_pad_set_active (GST_PAD_CAST (parsepad), TRUE);
  gst_parse_pad_set_blocked (parsepad, TRUE);
}

static void
gst_parse_pad_unblock (GstParsePad * parsepad)
{
  gst_parse_pad_set_blocked (parsepad, FALSE);
}

static gboolean
gst_parse_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstParsePad *parsepad = GST_PARSE_PAD (parent);
  gboolean ret = FALSE;

  CHAIN_MUTEX_LOCK (parsepad->chain);
  if (!parsepad->exposed && !parsepad->parsebin->shutdown
      && !parsepad->chain->deadend && parsepad->chain->elements) {
    GstParseElement *pelem = parsepad->chain->elements->data;

    ret = FALSE;
    GST_DEBUG_OBJECT (parsepad->parsebin,
        "calling autoplug-query for %s (element %s): %" GST_PTR_FORMAT,
        GST_PAD_NAME (parsepad), GST_ELEMENT_NAME (pelem->element), query);
    g_signal_emit (G_OBJECT (parsepad->parsebin),
        gst_parse_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, parsepad,
        pelem->element, query, &ret);

    if (ret)
      GST_DEBUG_OBJECT (parsepad->parsebin,
          "autoplug-query returned %d: %" GST_PTR_FORMAT, ret, query);
    else
      GST_DEBUG_OBJECT (parsepad->parsebin, "autoplug-query returned %d", ret);
  }
  CHAIN_MUTEX_UNLOCK (parsepad->chain);

  /* If exposed or nothing handled the query use the default handler */
  if (!ret)
    ret = gst_pad_query_default (pad, parent, query);

  return ret;
}

/*gst_parse_pad_new:
 *
 * Creates a new GstParsePad for the given pad.
 */
static GstParsePad *
gst_parse_pad_new (GstParseBin * parsebin, GstParseChain * chain)
{
  GstParsePad *parsepad;
  GstProxyPad *ppad;
  GstPadTemplate *pad_tmpl;

  GST_DEBUG_OBJECT (parsebin, "making new parsepad");
  pad_tmpl = gst_static_pad_template_get (&parse_bin_src_template);
  parsepad =
      g_object_new (GST_TYPE_PARSE_PAD, "direction", GST_PAD_SRC,
      "template", pad_tmpl, NULL);
  gst_ghost_pad_construct (GST_GHOST_PAD_CAST (parsepad));
  parsepad->chain = chain;
  parsepad->parsebin = parsebin;
  gst_object_unref (pad_tmpl);

  ppad = gst_proxy_pad_get_internal (GST_PROXY_PAD (parsepad));
  gst_pad_set_query_function (GST_PAD_CAST (ppad), gst_parse_pad_query);

  /* Add downstream event probe */
  GST_LOG_OBJECT (parsepad, "Adding event probe on internal pad %"
      GST_PTR_FORMAT, ppad);
  gst_pad_add_probe (GST_PAD_CAST (ppad),
      GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, gst_parse_pad_event, parsepad, NULL);
  gst_object_unref (ppad);

  return parsepad;
}

static void
gst_pending_pad_free (GstPendingPad * ppad)
{
  g_assert (ppad);
  g_assert (ppad->pad);

  if (ppad->event_probe_id != 0)
    gst_pad_remove_probe (ppad->pad, ppad->event_probe_id);
  if (ppad->notify_caps_id)
    g_signal_handler_disconnect (ppad->pad, ppad->notify_caps_id);
  gst_object_unref (ppad->pad);
  g_slice_free (GstPendingPad, ppad);
}

/*****
 * Element add/remove
 *****/

static void
do_async_start (GstParseBin * parsebin)
{
  GstMessage *message;

  parsebin->async_pending = TRUE;

  message = gst_message_new_async_start (GST_OBJECT_CAST (parsebin));
  parent_class->handle_message (GST_BIN_CAST (parsebin), message);
}

static void
do_async_done (GstParseBin * parsebin)
{
  GstMessage *message;

  if (parsebin->async_pending) {
    message =
        gst_message_new_async_done (GST_OBJECT_CAST (parsebin),
        GST_CLOCK_TIME_NONE);
    parent_class->handle_message (GST_BIN_CAST (parsebin), message);

    parsebin->async_pending = FALSE;
  }
}

/* call with dyn_lock held */
static void
unblock_pads (GstParseBin * parsebin)
{
  GList *tmp;

  GST_LOG_OBJECT (parsebin, "unblocking pads");

  for (tmp = parsebin->blocked_pads; tmp; tmp = tmp->next) {
    GstParsePad *parsepad = (GstParsePad *) tmp->data;
    GstPad *opad;

    opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (parsepad));
    if (!opad)
      continue;

    GST_DEBUG_OBJECT (parsepad, "unblocking");
    if (parsepad->block_id != 0) {
      gst_pad_remove_probe (opad, parsepad->block_id);
      parsepad->block_id = 0;
    }
    parsepad->blocked = FALSE;
    /* make flushing, prevent NOT_LINKED */
    gst_pad_set_active (GST_PAD_CAST (parsepad), FALSE);
    gst_object_unref (parsepad);
    gst_object_unref (opad);
    GST_DEBUG_OBJECT (parsepad, "unblocked");
  }

  /* clear, no more blocked pads */
  g_list_free (parsebin->blocked_pads);
  parsebin->blocked_pads = NULL;
}

static GstStateChangeReturn
gst_parse_bin_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstParseBin *parsebin = GST_PARSE_BIN (element);
  GstParseChain *chain_to_free = NULL;

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (parsebin->typefind == NULL)
        goto missing_typefind;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* Make sure we've cleared all existing chains */
      EXPOSE_LOCK (parsebin);
      if (parsebin->parse_chain) {
        gst_parse_chain_free (parsebin->parse_chain);
        parsebin->parse_chain = NULL;
      }
      EXPOSE_UNLOCK (parsebin);
      DYN_LOCK (parsebin);
      GST_LOG_OBJECT (parsebin, "clearing shutdown flag");
      parsebin->shutdown = FALSE;
      DYN_UNLOCK (parsebin);
      parsebin->have_type = FALSE;
      ret = GST_STATE_CHANGE_ASYNC;
      do_async_start (parsebin);


      /* connect a signal to find out when the typefind element found
       * a type */
      parsebin->have_type_id =
          g_signal_connect (parsebin->typefind, "have-type",
          G_CALLBACK (type_found), parsebin);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (parsebin->have_type_id)
        g_signal_handler_disconnect (parsebin->typefind,
            parsebin->have_type_id);
      parsebin->have_type_id = 0;
      DYN_LOCK (parsebin);
      GST_LOG_OBJECT (parsebin, "setting shutdown flag");
      parsebin->shutdown = TRUE;
      unblock_pads (parsebin);
      DYN_UNLOCK (parsebin);
    default:
      break;
  }

  {
    GstStateChangeReturn bret;

    bret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
    if (G_UNLIKELY (bret == GST_STATE_CHANGE_FAILURE))
      goto activate_failed;
    else if (G_UNLIKELY (bret == GST_STATE_CHANGE_NO_PREROLL)) {
      do_async_done (parsebin);
      ret = bret;
    }
  }
  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      do_async_done (parsebin);
      EXPOSE_LOCK (parsebin);
      if (parsebin->parse_chain) {
        chain_to_free = parsebin->parse_chain;
        gst_parse_chain_free_internal (parsebin->parse_chain, TRUE);
        parsebin->parse_chain = NULL;
      }
      EXPOSE_UNLOCK (parsebin);
      if (chain_to_free)
        gst_parse_chain_free (chain_to_free);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
    default:
      break;
  }

  return ret;

/* ERRORS */
missing_typefind:
  {
    gst_element_post_message (element,
        gst_missing_element_message_new (element, "typefind"));
    GST_ELEMENT_ERROR (parsebin, CORE, MISSING_PLUGIN, (NULL),
        ("no typefind!"));
    return GST_STATE_CHANGE_FAILURE;
  }
activate_failed:
  {
    GST_DEBUG_OBJECT (element,
        "element failed to change states -- activation problem?");
    do_async_done (parsebin);
    return GST_STATE_CHANGE_FAILURE;
  }
}

static void
gst_parse_bin_handle_message (GstBin * bin, GstMessage * msg)
{
  GstParseBin *parsebin = GST_PARSE_BIN (bin);
  gboolean drop = FALSE;

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR:{
      /* Don't pass errors when shutting down. Sometimes,
       * elements can generate spurious errors because we set the
       * output pads to flushing, and they can't detect that if they
       * send an event at exactly the wrong moment */
      DYN_LOCK (parsebin);
      drop = parsebin->shutdown;
      DYN_UNLOCK (parsebin);

      if (!drop) {
        GST_OBJECT_LOCK (parsebin);
        drop =
            (g_list_find (parsebin->filtered, GST_MESSAGE_SRC (msg)) != NULL);
        if (drop)
          parsebin->filtered_errors =
              g_list_prepend (parsebin->filtered_errors, gst_message_ref (msg));
        GST_OBJECT_UNLOCK (parsebin);
      }
      break;
    }
    default:
      break;
  }

  if (drop)
    gst_message_unref (msg);
  else
    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
}

gboolean
gst_parse_bin_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_parse_bin_debug, "parsebin", 0, "parser bin");

  return gst_element_register (plugin, "parsebin", GST_RANK_NONE,
      GST_TYPE_PARSE_BIN);
}
