/* 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>
 *
 * 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-decodebin
 *
 * #GstBin that auto-magically constructs a decoding pipeline using available
 * decoders and demuxers via auto-plugging.
 *
 * decodebin is considered stable now and replaces the old #decodebin element.
 * #uridecodebin uses decodebin internally and is often more convenient to
 * use, as it creates a suitable source element as well.
 */

/* Implementation notes:
 *
 * The following section describes how decodebin works internally.
 *
 * The first part of decodebin is its typefind element, which tries
 * to determine the media type of the input stream. If the type is found
 * autoplugging starts.
 *
 * decodebin internally organizes the elements it autoplugged into GstDecodeChains
 * and GstDecodeGroups. A decode chain is a single chain of decoding, this
 * means that if decodebin every autoplugs an element with two+ srcpads
 * (e.g. a demuxer) this will end the chain and everything following this
 * demuxer will be put into decode groups below the chain. Otherwise,
 * if an element has a single srcpad that outputs raw data the decode chain
 * is ended too and a GstDecodePad is stored and blocked.
 *
 * A decode group combines a number of chains that are created by a
 * demuxer element. All those chains are connected through a multiqueue to
 * the demuxer. A new group for the same demuxer is only created if the
 * demuxer has signaled no-more-pads, in which case all following pads
 * create a new chain in the new group.
 *
 * This continues until the top-level decode chain is complete. A decode
 * chain is complete if it either ends with a blocked endpad, if autoplugging
 * stopped because no suitable plugins could be found or if the active group
 * is complete. A decode group on the other hand is complete if all child
 * chains are complete.
 *
 * If this happens at some point, all endpads of all active groups are exposed.
 * For this decodebin adds the endpads, signals no-more-pads and then unblocks
 * them. Now playback starts.
 *
 * If one of the chains that end on a endpad receives EOS decodebin 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 "gstrawcaps.h"
#include "gstplaybackutils.h"

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

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

GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
#define GST_CAT_DEFAULT gst_decode_bin_debug

typedef struct _GstPendingPad GstPendingPad;
typedef struct _GstDecodeElement GstDecodeElement;
typedef struct _GstDecodeChain GstDecodeChain;
typedef struct _GstDecodeGroup GstDecodeGroup;
typedef struct _GstDecodePad GstDecodePad;
typedef GstGhostPadClass GstDecodePadClass;
typedef struct _GstDecodeBin GstDecodeBin;
typedef struct _GstDecodeBinClass GstDecodeBinClass;

#define GST_TYPE_DECODE_BIN             (gst_decode_bin_get_type())
#define GST_DECODE_BIN_CAST(obj)        ((GstDecodeBin*)(obj))
#define GST_DECODE_BIN(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_BIN,GstDecodeBin))
#define GST_DECODE_BIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECODE_BIN,GstDecodeBinClass))
#define GST_IS_DECODE_BIN(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECODE_BIN))
#define GST_IS_DECODE_BIN_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECODE_BIN))

/**
 *  GstDecodeBin:
 *
 *  The opaque #GstDecodeBin data structure
 */
struct _GstDecodeBin
{
  GstBin bin;                   /* we extend GstBin */

  /* properties */
  GstCaps *caps;                /* caps on which to stop decoding */
  gchar *encoding;              /* encoding of subtitles */
  gboolean use_buffering;       /* configure buffering on multiqueues */
  gint low_percent;
  gint high_percent;
  guint max_size_bytes;
  guint max_size_buffers;
  guint64 max_size_time;
  gboolean post_stream_topology;
  guint64 connection_speed;

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

  GMutex expose_lock;           /* Protects exposal and removal of groups */
  GstDecodeChain *decode_chain; /* Top level decode 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 */

  GList *buffering_status;      /* element currently buffering messages */
  GMutex buffering_lock;
  GMutex buffering_post_lock;
};

struct _GstDecodeBinClass
{
  GstBinClass parent_class;

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

  /* signal fired to know if we continue trying to decode 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
};

/* automatic sizes, while prerolling we buffer up to 2MB, we ignore time
 * and buffers in this case. */
#define AUTO_PREROLL_SIZE_BYTES                  2 * 1024 * 1024
#define AUTO_PREROLL_SIZE_BUFFERS                0
#define AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME      10 * GST_SECOND
#define AUTO_PREROLL_SEEKABLE_SIZE_TIME          0

/* when playing, keep a max of 2MB of data but try to keep the number of buffers
 * as low as possible (try to aim for 5 buffers) */
#define AUTO_PLAY_SIZE_BYTES        2 * 1024 * 1024
#define AUTO_PLAY_SIZE_BUFFERS      5
#define AUTO_PLAY_SIZE_TIME         0

#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_MAX_SIZE_BYTES    0
#define DEFAULT_MAX_SIZE_BUFFERS  0
#define DEFAULT_MAX_SIZE_TIME     0
#define DEFAULT_POST_STREAM_TOPOLOGY FALSE
#define DEFAULT_EXPOSE_ALL_STREAMS  TRUE
#define DEFAULT_CONNECTION_SPEED    0

/* Properties */
enum
{
  PROP_0,
  PROP_CAPS,
  PROP_SUBTITLE_ENCODING,
  PROP_SINK_CAPS,
  PROP_USE_BUFFERING,
  PROP_LOW_PERCENT,
  PROP_HIGH_PERCENT,
  PROP_MAX_SIZE_BYTES,
  PROP_MAX_SIZE_BUFFERS,
  PROP_MAX_SIZE_TIME,
  PROP_POST_STREAM_TOPOLOGY,
  PROP_EXPOSE_ALL_STREAMS,
  PROP_CONNECTION_SPEED
};

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

static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);

static void do_async_start (GstDecodeBin * dbin);
static void do_async_done (GstDecodeBin * dbin);

static void type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstDecodeBin * decode_bin);

static void decodebin_set_queue_size (GstDecodeBin * dbin,
    GstElement * multiqueue, gboolean preroll, gboolean seekable);
static void decodebin_set_queue_size_full (GstDecodeBin * dbin,
    GstElement * multiqueue, gboolean use_buffering, gboolean preroll,
    gboolean seekable);

static gboolean gst_decode_bin_autoplug_continue (GstElement * element,
    GstPad * pad, GstCaps * caps);
static GValueArray *gst_decode_bin_autoplug_factories (GstElement *
    element, GstPad * pad, GstCaps * caps);
static GValueArray *gst_decode_bin_autoplug_sort (GstElement * element,
    GstPad * pad, GstCaps * caps, GValueArray * factories);
static GstAutoplugSelectResult gst_decode_bin_autoplug_select (GstElement *
    element, GstPad * pad, GstCaps * caps, GstElementFactory * factory);
static gboolean gst_decode_bin_autoplug_query (GstElement * element,
    GstPad * pad, GstQuery * query);

static void gst_decode_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_decode_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps);
static GstCaps *gst_decode_bin_get_caps (GstDecodeBin * dbin);
static void caps_notify_cb (GstPad * pad, GParamSpec * unused,
    GstDecodeChain * chain);

static void flush_chain (GstDecodeChain * chain, gboolean flushing);
static void flush_group (GstDecodeGroup * group, gboolean flushing);
static GstPad *find_sink_pad (GstElement * element);
static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
    GstStateChange transition);
static void gst_decode_bin_handle_message (GstBin * bin, GstMessage * message);
static gboolean gst_decode_bin_remove_element (GstBin * bin,
    GstElement * element);

static gboolean check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad);

static GstCaps *get_pad_caps (GstPad * pad);

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

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

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

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

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

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

#define BUFFERING_LOCK(dbin) G_STMT_START {				\
    GST_LOG_OBJECT (dbin,						\
		    "buffering locking from thread %p",			\
		    g_thread_self ());					\
    g_mutex_lock (&GST_DECODE_BIN_CAST(dbin)->buffering_lock);		\
    GST_LOG_OBJECT (dbin,						\
		    "buffering lock from thread %p",			\
		    g_thread_self ());					\
} G_STMT_END

#define BUFFERING_UNLOCK(dbin) G_STMT_START {				\
    GST_LOG_OBJECT (dbin,						\
		    "buffering unlocking from thread %p",		\
		    g_thread_self ());					\
    g_mutex_unlock (&GST_DECODE_BIN_CAST(dbin)->buffering_lock);		\
} G_STMT_END

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

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

/* GstDecodeGroup
 *
 * Streams belonging to the same group/chain of a media file
 *
 * When changing something here lock the parent chain!
 */
struct _GstDecodeGroup
{
  GstDecodeBin *dbin;
  GstDecodeChain *parent;

  GstElement *multiqueue;       /* Used for linking all child chains */
  gulong overrunsig;            /* the overrun signal for multiqueue */

  gboolean overrun;             /* TRUE if the multiqueue signaled overrun. This
                                 * means that we should really expose the group */

  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 GstDecodeChains in this group */

  GList *reqpads;               /* List of RequestPads for multiqueue, there is
                                 * exactly one RequestPad per child chain */
};

struct _GstDecodeChain
{
  GstDecodeGroup *parent;
  GstDecodeBin *dbin;

  gint refs;                    /* Number of references to this object */

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

  GstPad *pad;                  /* srcpad that caused creation of this chain */

  gboolean drained;             /* TRUE if the all children are drained */
  gboolean demuxer;             /* TRUE if elements->data is a demuxer */
  gboolean adaptive_demuxer;    /* TRUE if elements->data is an adaptive streaming demuxer */
  gboolean seekable;            /* TRUE if this chain ends on a demuxer and is seekable */
  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! */

  GstDecodeGroup *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 */

  GstDecodePad *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 */
  GstDecodePad *endpad;         /* Pad of this chain that could be exposed */
  gboolean deadend;             /* This chain is incomplete and can't be completed,
                                   e.g. no suitable decoder 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 GstDecodeChain *gst_decode_chain_ref (GstDecodeChain * chain);
static void gst_decode_chain_unref (GstDecodeChain * chain);
static void gst_decode_chain_free (GstDecodeChain * chain);
static GstDecodeChain *gst_decode_chain_new (GstDecodeBin * dbin,
    GstDecodeGroup * group, GstPad * pad);
static void gst_decode_group_hide (GstDecodeGroup * group);
static void gst_decode_group_free (GstDecodeGroup * group);
static GstDecodeGroup *gst_decode_group_new (GstDecodeBin * dbin,
    GstDecodeChain * chain);
static gboolean gst_decode_chain_is_complete (GstDecodeChain * chain);
static gboolean gst_decode_chain_expose (GstDecodeChain * chain,
    GList ** endpads, gboolean * missing_plugin,
    GString * missing_plugin_details, gboolean * last_group);
static gboolean gst_decode_chain_is_drained (GstDecodeChain * chain);
static gboolean gst_decode_chain_reset_buffering (GstDecodeChain * chain);
static gboolean gst_decode_group_is_complete (GstDecodeGroup * group);
static GstPad *gst_decode_group_control_demuxer_pad (GstDecodeGroup * group,
    GstPad * pad);
static gboolean gst_decode_group_is_drained (GstDecodeGroup * group);
static gboolean gst_decode_group_reset_buffering (GstDecodeGroup * group);

static gboolean gst_decode_bin_expose (GstDecodeBin * dbin);
static void gst_decode_bin_reset_buffering (GstDecodeBin * dbin);

#define CHAIN_MUTEX_LOCK(chain) G_STMT_START {				\
    GST_LOG_OBJECT (chain->dbin,					\
		    "locking chain %p from thread %p",			\
		    chain, g_thread_self ());				\
    g_mutex_lock (&chain->lock);						\
    GST_LOG_OBJECT (chain->dbin,					\
		    "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->dbin,					\
		    "unlocking chain %p from thread %p",		\
		    chain, g_thread_self ());				\
    g_mutex_unlock (&chain->lock);					\
} G_STMT_END

/* GstDecodePad
 *
 * GstPad private used for source pads of chains
 */
struct _GstDecodePad
{
  GstGhostPad parent;
  GstDecodeBin *dbin;
  GstDecodeChain *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;
};

GType gst_decode_pad_get_type (void);
G_DEFINE_TYPE (GstDecodePad, gst_decode_pad, GST_TYPE_GHOST_PAD);
#define GST_TYPE_DECODE_PAD (gst_decode_pad_get_type ())
#define GST_DECODE_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_PAD,GstDecodePad))

static GstDecodePad *gst_decode_pad_new (GstDecodeBin * dbin,
    GstDecodeChain * chain);
static void gst_decode_pad_activate (GstDecodePad * dpad,
    GstDecodeChain * chain);
static void gst_decode_pad_unblock (GstDecodePad * dpad);
static void gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked);
static gboolean gst_decode_pad_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_decode_pad_is_exposable (GstDecodePad * endpad);

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_decode_bin_class_init (GstDecodeBinClass * klass);
static void gst_decode_bin_init (GstDecodeBin * decode_bin);
static void gst_decode_bin_dispose (GObject * object);
static void gst_decode_bin_finalize (GObject * object);

static GType
gst_decode_bin_get_type (void)
{
  static GType gst_decode_bin_type = 0;

  if (!gst_decode_bin_type) {
    static const GTypeInfo gst_decode_bin_info = {
      sizeof (GstDecodeBinClass),
      NULL,
      NULL,
      (GClassInitFunc) gst_decode_bin_class_init,
      NULL,
      NULL,
      sizeof (GstDecodeBin),
      0,
      (GInstanceInitFunc) gst_decode_bin_init,
      NULL
    };

    gst_decode_bin_type =
        g_type_register_static (GST_TYPE_BIN, "GstDecodeBin",
        &gst_decode_bin_info, 0);
  }

  return gst_decode_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_decode_bin_class_init (GstDecodeBinClass * 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_decode_bin_dispose;
  gobject_klass->finalize = gst_decode_bin_finalize;
  gobject_klass->set_property = gst_decode_bin_set_property;
  gobject_klass->get_property = gst_decode_bin_get_property;

  /**
   * GstDecodeBin::unknown-type:
   * @bin: The decodebin.
   * @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
   * decoding is added to the decodebin.
   */
  gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
      g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
      GST_TYPE_PAD, GST_TYPE_CAPS);

  /**
   * GstDecodeBin::autoplug-continue:
   * @bin: The decodebin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps found.
   *
   * This signal is emitted whenever decodebin finds a new stream. It is
   * emitted before looking for any elements that can handle that stream.
   *
   * <note>
   *   Invocation of signal handlers stops after the first signal handler
   *   returns #FALSE. Signal handlers are invoked in the order they were
   *   connected in.
   * </note>
   *
   * Returns: #TRUE if you wish decodebin 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_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
      g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_continue),
      _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
      G_TYPE_BOOLEAN, 2, GST_TYPE_PAD, GST_TYPE_CAPS);

  /**
   * GstDecodeBin::autoplug-factories:
   * @bin: The decodebin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps found.
   *
   * This function is emited when an array of possible factories for @caps on
   * @pad is needed. Decodebin 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.
   *
   * <note>
   *   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!
   * </note>
   *
   * 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_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES] =
      g_signal_new ("autoplug-factories", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass,
          autoplug_factories), _gst_array_accumulator, NULL,
      g_cclosure_marshal_generic, G_TYPE_VALUE_ARRAY, 2,
      GST_TYPE_PAD, GST_TYPE_CAPS);

  /**
   * GstDecodeBin::autoplug-sort:
   * @bin: The decodebin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps.
   * @factories: A #GValueArray of possible #GstElementFactory to use.
   *
   * Once decodebin 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.
   *
   * <note>
   *   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!
   * </note>
   *
   * Returns: A new sorted array of #GstElementFactory objects.
   */
  gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT] =
      g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, 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);

  /**
   * GstDecodeBin::autoplug-select:
   * @bin: The decodebin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps.
   * @factory: A #GstElementFactory to use.
   *
   * This signal is emitted once decodebin 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 decodebin 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.
   *
   * <note>
   *   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.
   * </note>
   *
   * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
   * operation. the default handler will always return
   * #GST_AUTOPLUG_SELECT_TRY.
   */
  gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
      g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, 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);

  /**
   * GstDecodeBin::autoplug-query:
   * @bin: The decodebin.
   * @pad: The #GstPad.
   * @child: The child element doing the query
   * @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_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY] =
      g_signal_new ("autoplug-query", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, 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);

  /**
   * GstDecodeBin::drained
   * @bin: The decodebin
   *
   * This signal is emitted once decodebin has finished decoding all the data.
   */
  gst_decode_bin_signals[SIGNAL_DRAINED] =
      g_signal_new ("drained", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, drained),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);

  g_object_class_install_property (gobject_klass, PROP_CAPS,
      g_param_spec_boxed ("caps", "Caps", "The caps on which to stop decoding.",
          GST_TYPE_CAPS, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

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

  /**
   * GstDecodeBin::use-buffering
   *
   * Activate buffering in decodebin. This will instruct the multiqueues behind
   * decoders to emit BUFFERING messages.
   */
  g_object_class_install_property (gobject_klass, PROP_USE_BUFFERING,
      g_param_spec_boolean ("use-buffering", "Use Buffering",
          "Emit GST_MESSAGE_BUFFERING based on low-/high-percent thresholds",
          DEFAULT_USE_BUFFERING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDecodeBin:low-percent
   *
   * Low threshold percent for buffering to start.
   */
  g_object_class_install_property (gobject_klass, PROP_LOW_PERCENT,
      g_param_spec_int ("low-percent", "Low percent",
          "Low threshold for buffering to start", 0, 100,
          DEFAULT_LOW_PERCENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstDecodeBin:high-percent
   *
   * High threshold percent for buffering to finish.
   */
  g_object_class_install_property (gobject_klass, PROP_HIGH_PERCENT,
      g_param_spec_int ("high-percent", "High percent",
          "High threshold for buffering to finish", 0, 100,
          DEFAULT_HIGH_PERCENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDecodeBin:max-size-bytes
   *
   * Max amount of bytes in the queue (0=automatic).
   */
  g_object_class_install_property (gobject_klass, PROP_MAX_SIZE_BYTES,
      g_param_spec_uint ("max-size-bytes", "Max. size (bytes)",
          "Max. amount of bytes in the queue (0=automatic)",
          0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstDecodeBin:max-size-buffers
   *
   * Max amount of buffers in the queue (0=automatic).
   */
  g_object_class_install_property (gobject_klass, PROP_MAX_SIZE_BUFFERS,
      g_param_spec_uint ("max-size-buffers", "Max. size (buffers)",
          "Max. number of buffers in the queue (0=automatic)",
          0, G_MAXUINT, DEFAULT_MAX_SIZE_BUFFERS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstDecodeBin:max-size-time
   *
   * Max amount of time in the queue (in ns, 0=automatic).
   */
  g_object_class_install_property (gobject_klass, PROP_MAX_SIZE_TIME,
      g_param_spec_uint64 ("max-size-time", "Max. size (ns)",
          "Max. amount of data in the queue (in ns, 0=automatic)",
          0, G_MAXUINT64,
          DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDecodeBin::post-stream-topology
   *
   * Post stream-topology messages on the bus every time the topology changes.
   */
  g_object_class_install_property (gobject_klass, PROP_POST_STREAM_TOPOLOGY,
      g_param_spec_boolean ("post-stream-topology", "Post Stream Topology",
          "Post stream-topology messages",
          DEFAULT_POST_STREAM_TOPOLOGY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstDecodeBin::expose-all-streams
   *
   * Expose streams of unknown type.
   *
   * If set to %FALSE, then only the streams that can be decoded to the final
   * caps (see 'caps' property) will have a pad exposed. Streams that do not
   * match those caps but could have been decoded will not have decoder 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));

  /**
   * GstDecodeBin2::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_decode_bin_autoplug_continue);
  klass->autoplug_factories =
      GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_factories);
  klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_sort);
  klass->autoplug_select = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_select);
  klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_query);

  gst_element_class_add_static_pad_template (gstelement_klass,
      &decoder_bin_sink_template);
  gst_element_class_add_static_pad_template (gstelement_klass,
      &decoder_bin_src_template);

  gst_element_class_set_static_metadata (gstelement_klass,
      "Decoder Bin", "Generic/Bin/Decoder",
      "Autoplug and decode to raw media",
      "Edward Hervey <edward.hervey@collabora.co.uk>, "
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  gstelement_klass->change_state =
      GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);

  gstbin_klass->handle_message =
      GST_DEBUG_FUNCPTR (gst_decode_bin_handle_message);

  gstbin_klass->remove_element =
      GST_DEBUG_FUNCPTR (gst_decode_bin_remove_element);

  g_type_class_ref (GST_TYPE_DECODE_PAD);
}

/* Must be called with factories lock! */
static void
gst_decode_bin_update_factories_list (GstDecodeBin * dbin)
{
  guint cookie;

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

static void
gst_decode_bin_init (GstDecodeBin * decode_bin)
{
  /* first filter out the interesting element factories */
  g_mutex_init (&decode_bin->factories_lock);

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

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

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

    /* get the pad template */
    pad_tmpl = gst_static_pad_template_get (&decoder_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 (decode_bin), gpad);

    gst_object_unref (pad_tmpl);
    gst_object_unref (pad);
  }

  g_mutex_init (&decode_bin->expose_lock);
  decode_bin->decode_chain = NULL;

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

  g_mutex_init (&decode_bin->subtitle_lock);
  g_mutex_init (&decode_bin->buffering_lock);
  g_mutex_init (&decode_bin->buffering_post_lock);

  decode_bin->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);
  decode_bin->caps = gst_static_caps_get (&default_raw_caps);
  decode_bin->use_buffering = DEFAULT_USE_BUFFERING;
  decode_bin->low_percent = DEFAULT_LOW_PERCENT;
  decode_bin->high_percent = DEFAULT_HIGH_PERCENT;

  decode_bin->max_size_bytes = DEFAULT_MAX_SIZE_BYTES;
  decode_bin->max_size_buffers = DEFAULT_MAX_SIZE_BUFFERS;
  decode_bin->max_size_time = DEFAULT_MAX_SIZE_TIME;

  decode_bin->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
  decode_bin->connection_speed = DEFAULT_CONNECTION_SPEED;
}

static void
gst_decode_bin_dispose (GObject * object)
{
  GstDecodeBin *decode_bin;

  decode_bin = GST_DECODE_BIN (object);

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

  if (decode_bin->decode_chain)
    gst_decode_chain_free (decode_bin->decode_chain);
  decode_bin->decode_chain = NULL;

  if (decode_bin->caps)
    gst_caps_unref (decode_bin->caps);
  decode_bin->caps = NULL;

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

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

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

static void
gst_decode_bin_finalize (GObject * object)
{
  GstDecodeBin *decode_bin;

  decode_bin = GST_DECODE_BIN (object);

  g_mutex_clear (&decode_bin->expose_lock);
  g_mutex_clear (&decode_bin->dyn_lock);
  g_mutex_clear (&decode_bin->subtitle_lock);
  g_mutex_clear (&decode_bin->buffering_lock);
  g_mutex_clear (&decode_bin->buffering_post_lock);
  g_mutex_clear (&decode_bin->factories_lock);

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

/* _set_caps
 * Changes the caps on which decodebin will stop decoding.
 * Will unref the previously set one. The refcount of the given caps will be
 * increased.
 * @caps can be NULL.
 *
 * MT-safe
 */
static void
gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps)
{
  GST_DEBUG_OBJECT (dbin, "Setting new caps: %" GST_PTR_FORMAT, caps);

  GST_OBJECT_LOCK (dbin);
  gst_caps_replace (&dbin->caps, caps);
  GST_OBJECT_UNLOCK (dbin);
}

/* _get_caps
 * Returns the currently configured caps on which decodebin will stop decoding.
 * The returned caps (if not NULL), will have its refcount incremented.
 *
 * MT-safe
 */
static GstCaps *
gst_decode_bin_get_caps (GstDecodeBin * dbin)
{
  GstCaps *caps;

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

  GST_OBJECT_LOCK (dbin);
  caps = dbin->caps;
  if (caps)
    gst_caps_ref (caps);
  GST_OBJECT_UNLOCK (dbin);

  return caps;
}

static void
gst_decode_bin_set_sink_caps (GstDecodeBin * dbin, GstCaps * caps)
{
  GST_DEBUG_OBJECT (dbin, "Setting new caps: %" GST_PTR_FORMAT, caps);

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

static GstCaps *
gst_decode_bin_get_sink_caps (GstDecodeBin * dbin)
{
  GstCaps *caps;

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

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

  return caps;
}

static void
gst_decode_bin_set_subs_encoding (GstDecodeBin * dbin, const gchar * encoding)
{
  GList *walk;

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

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

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

static gchar *
gst_decode_bin_get_subs_encoding (GstDecodeBin * dbin)
{
  gchar *encoding;

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

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

  return encoding;
}

static void
gst_decode_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDecodeBin *dbin;

  dbin = GST_DECODE_BIN (object);

  switch (prop_id) {
    case PROP_CAPS:
      gst_decode_bin_set_caps (dbin, g_value_get_boxed (value));
      break;
    case PROP_SUBTITLE_ENCODING:
      gst_decode_bin_set_subs_encoding (dbin, g_value_get_string (value));
      break;
    case PROP_SINK_CAPS:
      gst_decode_bin_set_sink_caps (dbin, g_value_get_boxed (value));
      break;
    case PROP_USE_BUFFERING:
      dbin->use_buffering = g_value_get_boolean (value);
      break;
    case PROP_LOW_PERCENT:
      dbin->low_percent = g_value_get_int (value);
      break;
    case PROP_HIGH_PERCENT:
      dbin->high_percent = g_value_get_int (value);
      break;
    case PROP_MAX_SIZE_BYTES:
      dbin->max_size_bytes = g_value_get_uint (value);
      break;
    case PROP_MAX_SIZE_BUFFERS:
      dbin->max_size_buffers = g_value_get_uint (value);
      break;
    case PROP_MAX_SIZE_TIME:
      dbin->max_size_time = g_value_get_uint64 (value);
      break;
    case PROP_POST_STREAM_TOPOLOGY:
      dbin->post_stream_topology = g_value_get_boolean (value);
      break;
    case PROP_EXPOSE_ALL_STREAMS:
      dbin->expose_allstreams = g_value_get_boolean (value);
      break;
    case PROP_CONNECTION_SPEED:
      GST_OBJECT_LOCK (dbin);
      dbin->connection_speed = g_value_get_uint64 (value) * 1000;
      GST_OBJECT_UNLOCK (dbin);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_decode_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstDecodeBin *dbin;

  dbin = GST_DECODE_BIN (object);
  switch (prop_id) {
    case PROP_CAPS:
      g_value_take_boxed (value, gst_decode_bin_get_caps (dbin));
      break;
    case PROP_SUBTITLE_ENCODING:
      g_value_take_string (value, gst_decode_bin_get_subs_encoding (dbin));
      break;
    case PROP_SINK_CAPS:
      g_value_take_boxed (value, gst_decode_bin_get_sink_caps (dbin));
      break;
    case PROP_USE_BUFFERING:
      g_value_set_boolean (value, dbin->use_buffering);
      break;
    case PROP_LOW_PERCENT:
      g_value_set_int (value, dbin->low_percent);
      break;
    case PROP_HIGH_PERCENT:
      g_value_set_int (value, dbin->high_percent);
      break;
    case PROP_MAX_SIZE_BYTES:
      g_value_set_uint (value, dbin->max_size_bytes);
      break;
    case PROP_MAX_SIZE_BUFFERS:
      g_value_set_uint (value, dbin->max_size_buffers);
      break;
    case PROP_MAX_SIZE_TIME:
      g_value_set_uint64 (value, dbin->max_size_time);
      break;
    case PROP_POST_STREAM_TOPOLOGY:
      g_value_set_boolean (value, dbin->post_stream_topology);
      break;
    case PROP_EXPOSE_ALL_STREAMS:
      g_value_set_boolean (value, dbin->expose_allstreams);
      break;
    case PROP_CONNECTION_SPEED:
      GST_OBJECT_LOCK (dbin);
      g_value_set_uint64 (value, dbin->connection_speed / 1000);
      GST_OBJECT_UNLOCK (dbin);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


/*****
 * Default autoplug signal handlers
 *****/
static gboolean
gst_decode_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_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
    GstCaps * caps)
{
  GList *list, *tmp;
  GValueArray *result;
  GstDecodeBin *dbin = GST_DECODE_BIN_CAST (element);

  GST_DEBUG_OBJECT (element, "finding factories");

  /* return all compatible factories for caps */
  g_mutex_lock (&dbin->factories_lock);
  gst_decode_bin_update_factories_list (dbin);
  list =
      gst_element_factory_list_filter (dbin->factories, caps, GST_PAD_SINK,
      gst_caps_is_fixed (caps));
  g_mutex_unlock (&dbin->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_decode_bin_autoplug_sort (GstElement * element, GstPad * pad,
    GstCaps * caps, GValueArray * factories)
{
  return NULL;
}

static GstAutoplugSelectResult
gst_decode_bin_autoplug_select (GstElement * element, GstPad * pad,
    GstCaps * caps, GstElementFactory * factory)
{
  GST_DEBUG_OBJECT (element, "default autoplug-select returns TRY");

  /* Try factory. */
  return GST_AUTOPLUG_SELECT_TRY;
}

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

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

static gboolean are_final_caps (GstDecodeBin * dbin, GstCaps * caps);
static gboolean is_demuxer_element (GstElement * srcelement);
static gboolean is_adaptive_demuxer_element (GstElement * srcelement);

static gboolean connect_pad (GstDecodeBin * dbin, GstElement * src,
    GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GValueArray * factories,
    GstDecodeChain * chain, gchar ** deadend_details);
static GList *connect_element (GstDecodeBin * dbin, GstDecodeElement * delem,
    GstDecodeChain * chain);
static void expose_pad (GstDecodeBin * dbin, GstElement * src,
    GstDecodePad * dpad, GstPad * pad, GstCaps * caps, GstDecodeChain * chain);

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

static GstDecodeGroup *gst_decode_chain_get_current_group (GstDecodeChain *
    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 ** event, gpointer user_data)
{
  GstPad *gpad = GST_PAD_CAST (user_data);

  GST_DEBUG_OBJECT (gpad, "store sticky event %" GST_PTR_FORMAT, *event);
  gst_pad_store_sticky_event (gpad, *event);

  return TRUE;
}

static void
decode_pad_set_target (GstDecodePad * dpad, GstPad * target)
{
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (dpad), target);
  if (target == NULL)
    gst_pad_sticky_events_foreach (GST_PAD_CAST (dpad), clear_sticky_events,
        NULL);
  else
    gst_pad_sticky_events_foreach (target, copy_sticky_events, dpad);
}

/* 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.
 */
/* returns whether to expose the pad */
static gboolean
analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
    GstCaps * caps, GstDecodeChain * chain, GstDecodeChain ** new_chain)
{
  gboolean apcontinue = TRUE;
  GValueArray *factories = NULL, *result = NULL;
  GstDecodePad *dpad;
  GstElementFactory *factory;
  const gchar *classification;
  gboolean is_parser_converter = FALSE;
  gboolean res;
  gchar *deadend_details = NULL;

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

  if (new_chain)
    *new_chain = chain;

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

  if (chain->endpad) {
    GST_ERROR_OBJECT (dbin, "New pad in a chain that is already complete");
    return FALSE;
  }

  if (chain->demuxer) {
    GstDecodeGroup *group;
    GstDecodeChain *oldchain = chain;
    GstDecodeElement *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_decode_chain_get_current_group (chain);
    if (group && !g_list_find (group->children, chain)) {
      g_assert (new_chain != NULL);
      *new_chain = chain = gst_decode_chain_new (dbin, group, pad);
      group->children = g_list_prepend (group->children, chain);
    }
    CHAIN_MUTEX_UNLOCK (oldchain);
    if (!group) {
      GST_WARNING_OBJECT (dbin, "No current group");
      return FALSE;
    }

    /* 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_decode_pad_new (dbin, chain);

  dpad = gst_object_ref (chain->current_pad);
  gst_pad_set_active (GST_PAD_CAST (dpad), TRUE);
  decode_pad_set_target (dpad, 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 (dbin),
        gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, dpad, caps,
        &apcontinue);
  else
    apcontinue = TRUE;

  /* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
  if ((!apcontinue) || are_final_caps (dbin, caps))
    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"));

  /* 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 (dbin, "No final caps set yet, delaying autoplugging");
      gst_object_unref (dpad);
      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 (dbin),
      gst_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, dpad, 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 decoder */
  if (factories->n_values == 0) {
    if (!dbin->expose_allstreams) {
      GstCaps *raw = gst_static_caps_get (&default_raw_caps);

      /* If the caps are raw, this just means we don't want to expose them */
      if (gst_caps_is_subset (caps, raw)) {
        g_value_array_free (factories);
        gst_caps_unref (raw);
        gst_object_unref (dpad);
        goto discarded_type;
      }
      gst_caps_unref (raw);
    }

    /* if not we have a unhandled type with no compatible factories */
    g_value_array_free (factories);
    gst_object_unref (dpad);
    goto unknown_type;
  }

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

  /* At this point we have a potential decoder, but we might not need it
   * if it doesn't match the output caps  */
  if (!dbin->expose_allstreams && gst_caps_is_fixed (caps)) {
    guint i;
    const GList *tmps;
    gboolean dontuse = FALSE;

    GST_DEBUG ("Checking if we can abort early");

    /* 1.f Do an early check to see if the candidates are potential decoders, but
     * due to the fact that they decode to a mediatype that is not final we don't
     * need them */

    for (i = 0; i < factories->n_values && !dontuse; i++) {
      GstElementFactory *factory =
          g_value_get_object (g_value_array_get_nth (factories, i));
      GstCaps *tcaps;

      /* We are only interested in skipping decoders */
      if (strstr (gst_element_factory_get_metadata (factory,
                  GST_ELEMENT_METADATA_KLASS), "Decoder")) {

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

        /* Check the source pad template caps to see if they match raw caps but don't match
         * our final caps*/
        for (tmps = gst_element_factory_get_static_pad_templates (factory);
            tmps && !dontuse; tmps = tmps->next) {
          GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
          if (st->direction != GST_PAD_SRC)
            continue;
          tcaps = gst_static_pad_template_get_caps (st);

          apcontinue = TRUE;

          /* Emit autoplug-continue to see if the caps are considered to be raw caps */
          g_signal_emit (G_OBJECT (dbin),
              gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, dpad, tcaps,
              &apcontinue);

          /* If autoplug-continue returns TRUE and the caps are not final, don't use them */
          if (apcontinue && !are_final_caps (dbin, tcaps))
            dontuse = TRUE;
          gst_caps_unref (tcaps);
        }
      }
    }

    if (dontuse) {
      gst_object_unref (dpad);
      g_value_array_free (factories);
      goto discarded_type;
    }
  }

  /* 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;
    GstElement *capsfilter;
    GstPad *p;
    GstDecodeElement *delem;

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

    if (chain->elements) {
      delem = (GstDecodeElement *) chain->elements->data;
      capsfilter = delem->capsfilter =
          gst_element_factory_make ("capsfilter", NULL);
    } else {
      delem = g_slice_new0 (GstDecodeElement);
      capsfilter = delem->element =
          gst_element_factory_make ("capsfilter", NULL);
      delem->capsfilter = NULL;
      chain->elements = g_list_prepend (chain->elements, delem);
    }

    g_object_set (G_OBJECT (capsfilter), "caps", filter_caps, NULL);
    gst_caps_unref (filter_caps);
    gst_element_set_state (capsfilter, GST_STATE_PAUSED);
    gst_bin_add (GST_BIN_CAST (dbin), gst_object_ref (capsfilter));

    decode_pad_set_target (dpad, NULL);
    p = gst_element_get_static_pad (capsfilter, "sink");
    gst_pad_link_full (pad, p, GST_PAD_LINK_CHECK_NOTHING);
    gst_object_unref (p);
    p = gst_element_get_static_pad (capsfilter, "src");
    decode_pad_set_target (dpad, p);
    pad = p;

    gst_caps_unref (caps);

    caps = gst_pad_get_current_caps (pad);
    if (!caps) {
      GST_DEBUG_OBJECT (dbin, "No final caps set yet, delaying autoplugging");
      gst_object_unref (dpad);
      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 (dbin, src, dpad, 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 (dpad);
  g_value_array_free (factories);

  if (!res)
    goto unknown_type;

  gst_caps_unref (caps);

  return FALSE;

expose_pad:
  {
    GST_LOG_OBJECT (dbin, "Pad is final and should expose the pad. "
        "autoplug-continue:%d", apcontinue);
    gst_object_unref (dpad);
    gst_caps_unref (caps);
    return TRUE;
  }

discarded_type:
  {
    GST_LOG_OBJECT (pad, "Known type, but discarded because not final caps");
    chain->deadend = TRUE;
    chain->endcaps = caps;
    gst_object_replace ((GstObject **) & chain->current_pad, NULL);

    /* Try to expose anything */
    EXPOSE_LOCK (dbin);
    if (dbin->decode_chain) {
      if (gst_decode_chain_is_complete (dbin->decode_chain)) {
        gst_decode_bin_expose (dbin);
      }
    }
    EXPOSE_UNLOCK (dbin);
    do_async_done (dbin);

    return FALSE;
  }

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 (dbin),
        gst_missing_decoder_message_new (GST_ELEMENT_CAST (dbin), caps));

    g_signal_emit (G_OBJECT (dbin),
        gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);

    /* Try to expose anything */
    EXPOSE_LOCK (dbin);
    if (dbin->decode_chain) {
      if (gst_decode_chain_is_complete (dbin->decode_chain)) {
        gst_decode_bin_expose (dbin);
      }
    }
    EXPOSE_UNLOCK (dbin);

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

    /* connect to caps notification */
    CHAIN_MUTEX_LOCK (chain);
    GST_LOG_OBJECT (dbin, "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 FALSE;
  }
}

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

static void
remove_error_filter (GstDecodeBin * dbin, GstElement * element,
    GstMessage ** error)
{
  GList *l;

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

  if (error)
    *error = NULL;

  l = dbin->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 = dbin->filtered_errors = g_list_delete_link (dbin->filtered_errors, l);
    } else {
      l = l->next;
    }
  }
  GST_OBJECT_UNLOCK (dbin);
}

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 (GstDecodeBin * dbin, 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;
}

static GstPadProbeReturn
demuxer_source_pad_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstDecodeGroup *group = (GstDecodeGroup *) user_data;
  GstDecodeChain *parent_chain = group->parent;

  GST_DEBUG_OBJECT (pad, "Saw event %s", GST_EVENT_TYPE_NAME (event));
  /* Check if we are the active group, if not we need to proxy the flush
   * events to the other groups (of which at least one is exposed, ensuring
   * flushing properly propagates downstream of decodebin */
  if (parent_chain->active_group == group)
    return GST_PAD_PROBE_OK;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
    case GST_EVENT_FLUSH_STOP:
    {
      GList *tmp;
      GST_DEBUG_OBJECT (pad, "Proxying flush events to inactive groups");
      /* Proxy to active group */
      for (tmp = parent_chain->active_group->reqpads; tmp; tmp = tmp->next) {
        GstPad *reqpad = (GstPad *) tmp->data;
        gst_pad_send_event (reqpad, gst_event_ref (event));
      }
      /* Proxy to other non-active groups (except ourself) */
      for (tmp = parent_chain->next_groups; tmp; tmp = tmp->next) {
        GList *tmp2;
        GstDecodeGroup *tmpgroup = (GstDecodeGroup *) tmp->data;
        if (tmpgroup != group) {
          for (tmp2 = tmpgroup->reqpads; tmp2; tmp2 = tmp2->next) {
            GstPad *reqpad = (GstPad *) tmp2->data;
            gst_pad_send_event (reqpad, gst_event_ref (event));
          }
        }
      }
      flush_chain (parent_chain,
          GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START);
    }
      break;
    default:
      break;
  }

  return GST_PAD_PROBE_OK;
}

typedef struct
{
  GstDecodeChain *chain;
  GstPad *pad;
} PadExposeData;

/* connect_pad:
 *
 * Try to connect the given pad to an element created from one of the factories,
 * and recursively.
 *
 * Note that dpad is ghosting pad, and so pad is linked; be sure to unset dpad's
 * target before trying to link pad.
 *
 * Returns TRUE if an element was properly created and linked
 */
static gboolean
connect_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
    GstPad * pad, GstCaps * caps, GValueArray * factories,
    GstDecodeChain * chain, gchar ** deadend_details)
{
  gboolean res = FALSE;
  GstPad *mqpad = NULL;
  gboolean is_demuxer = chain->parent && !chain->elements;      /* First pad after the demuxer */
  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 (dbin,
      "pad %s:%s , chain:%p, %d factories, caps %" GST_PTR_FORMAT,
      GST_DEBUG_PAD_NAME (pad), chain, factories->n_values, caps);

  /* 1. is element demuxer or parser */
  if (is_demuxer) {
    GST_LOG_OBJECT (src,
        "is a demuxer, connecting the pad through multiqueue '%s'",
        GST_OBJECT_NAME (chain->parent->multiqueue));

    /* Set a flush-start/-stop probe on the downstream events */
    gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_FLUSH,
        demuxer_source_pad_probe, chain->parent, NULL);

    decode_pad_set_target (dpad, NULL);
    if (!(mqpad = gst_decode_group_control_demuxer_pad (chain->parent, pad)))
      goto beach;
    src = chain->parent->multiqueue;
    /* Forward sticky events to mq src pad to allow factory initialization */
    gst_pad_sticky_events_foreach (pad, copy_sticky_events, mqpad);
    pad = mqpad;
    decode_pad_set_target (dpad, pad);
  }

  error_details = g_string_new ("");

  /* 2. Try to create an element and link to it */
  while (factories->n_values > 0) {
    GstAutoplugSelectResult ret;
    GstElementFactory *factory;
    GstDecodeElement *delem;
    GstElement *element;
    GstPad *sinkpad;
    GParamSpec *pspec;
    gboolean subtitle;
    GList *to_connect = NULL;
    GList *to_expose = NULL;
    gboolean is_parser = FALSE;
    gboolean is_decoder = FALSE;

    /* Set dpad target to pad again, it might've been unset
     * below but we came back here because something failed
     */
    decode_pad_set_target (dpad, 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 decoder would want.
     *
     * A subset check will fail here because the parser caps
     * will be generic and while the decoder 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 = strstr (gst_element_factory_get_metadata (factory,
            GST_ELEMENT_METADATA_KLASS), "Parser") != NULL;

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

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

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

      if (!skip && chain->parent && chain->parent->parent) {
        GstDecodeChain *parent_chain = chain->parent->parent;
        GstDecodeElement *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 (dbin,
            "Skipping factory '%s' because it was already used in this chain",
            gst_plugin_feature_get_name (GST_PLUGIN_FEATURE_CAST (factory)));
        continue;
      }

    }

    /* emit autoplug-select to see what we should do with it. */
    g_signal_emit (G_OBJECT (dbin),
        gst_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT],
        0, dpad, caps, factory, &ret);

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

    /* 2.0. Unlink pad */
    decode_pad_set_target (dpad, NULL);

    /* 2.1. Try to create an element */
    if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
      GST_WARNING_OBJECT (dbin, "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 (dbin, 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 (dbin), element))) {
      GST_WARNING_OBJECT (dbin, "Couldn't add %s to the bin",
          GST_ELEMENT_NAME (element));
      remove_error_filter (dbin, 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. */
    if (!(sinkpad = find_sink_pad (element))) {
      GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad",
          GST_ELEMENT_NAME (element));
      remove_error_filter (dbin, 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 (dbin), 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 (dbin, "Link failed on pad %s:%s",
          GST_DEBUG_PAD_NAME (sinkpad));
      remove_error_filter (dbin, 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 (dbin), element);
      continue;
    }

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

      GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY",
          GST_ELEMENT_NAME (element));
      remove_error_filter (dbin, 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 (dbin), 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 (dbin, "Element %s does not accept caps",
          GST_ELEMENT_NAME (element));

      remove_error_filter (dbin, 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 (dbin), element);
      continue;
    }

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

    CHAIN_MUTEX_LOCK (chain);
    delem = g_slice_new0 (GstDecodeElement);
    delem->element = gst_object_ref (element);
    delem->capsfilter = NULL;
    chain->elements = g_list_prepend (chain->elements, delem);
    chain->demuxer = is_demuxer_element (element);
    chain->adaptive_demuxer = is_adaptive_demuxer_element (element);

    is_decoder = strstr (gst_element_factory_get_metadata (factory,
            GST_ELEMENT_METADATA_KLASS), "Decoder") != NULL;

    /* For adaptive streaming demuxer we insert a multiqueue after
     * this demuxer.
     * Now for the case where we have a container stream inside these
     * buffers, another demuxer will be plugged and after this second
     * demuxer there will be a second multiqueue. This second multiqueue
     * will get smaller buffers and will be the one emitting buffering
     * messages.
     * If we don't have a container stream inside the fragment buffers,
     * we'll insert a multiqueue below right after the next element after
     * the adaptive streaming demuxer. This is going to be a parser or
     * decoder, and will output smaller buffers.
     */
    if (chain->parent && chain->parent->parent) {
      GstDecodeChain *parent_chain = chain->parent->parent;

      if (parent_chain->adaptive_demuxer && (is_parser || is_decoder))
        chain->demuxer = TRUE;
    }

    /* If we are configured to use buffering and there is no demuxer in the
     * chain, we still want a multiqueue, otherwise we will ignore the
     * use-buffering property. In that case, we will insert a multiqueue after
     * the parser or decoder - not elsewhere, otherwise we won't have
     * timestamps.
     */

    if (!chain->parent && (is_parser || is_decoder) && dbin->use_buffering) {
      chain->demuxer = TRUE;
      if (is_decoder) {
        GST_WARNING_OBJECT (dbin,
            "Buffering messages used for decoded and non-parsed data");
      }
    }

    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 = dbin->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 (dbin,
              "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 (dbin, "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 (dbin);
      GST_DEBUG_OBJECT (dbin,
          "setting subtitle-encoding=%s to element", dbin->encoding);
      g_object_set (G_OBJECT (element), "subtitle-encoding", dbin->encoding,
          NULL);
      SUBTITLE_UNLOCK (dbin);
      subtitle = TRUE;
    } else {
      subtitle = FALSE;
    }

    /* link this element further */
    to_connect = connect_element (dbin, delem, chain);

    while (to_connect) {
      GstPad *opad = to_connect->data;
      gboolean expose_pad = FALSE;
      GstDecodeChain *new_chain;
      GstCaps *ocaps;

      ocaps = get_pad_caps (opad);
      expose_pad =
          analyze_new_pad (dbin, delem->element, opad, ocaps, chain,
          &new_chain);

      if (ocaps)
        gst_caps_unref (ocaps);

      if (expose_pad) {
        PadExposeData *expose_data = g_new0 (PadExposeData, 1);
        expose_data->chain = new_chain;
        expose_data->pad = gst_object_ref (opad);
        to_expose = g_list_prepend (to_expose, expose_data);
      }

      gst_object_unref (opad);
      to_connect = g_list_delete_link (to_connect, to_connect);
    }
    /* any pads left in to_expose are to be exposed */

    /* 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 ||
        !send_sticky_events (dbin, pad)) {
      GstDecodeElement *dtmp = NULL;
      GstElement *tmp = NULL;
      GstMessage *error_msg;

      GST_PAD_STREAM_UNLOCK (sinkpad);

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

      while (to_expose) {
        PadExposeData *expose_data = to_expose->data;
        gst_object_unref (expose_data->pad);
        g_free (expose_data);
        to_expose = g_list_delete_link (to_expose, to_expose);
      }

      remove_error_filter (dbin, 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 (dbin), dtmp->capsfilter);
          gst_element_set_state (dtmp->capsfilter, GST_STATE_NULL);
          gst_object_unref (dtmp->capsfilter);
        }

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

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

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

      continue;
    } else {
      /* 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 (dbin, element, NULL);

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

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

    while (to_expose) {
      PadExposeData *expose_data = to_expose->data;
      GstCaps *ocaps;

      ocaps = get_pad_caps (expose_data->pad);
      expose_pad (dbin, delem->element, expose_data->chain->current_pad,
          expose_data->pad, ocaps, expose_data->chain);

      if (ocaps)
        gst_caps_unref (ocaps);

      gst_object_unref (expose_data->pad);
      g_free (expose_data);
      to_expose = g_list_delete_link (to_expose, to_expose);
    }

    res = TRUE;
    break;
  }

beach:
  if (mqpad)
    gst_object_unref (mqpad);

  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 (GstDecodeBin * dbin, GstDecodeElement * delem,
    GstDecodeChain * chain)
{
  GstElement *element = delem->element;
  GList *pads;
  gboolean dynamic = FALSE;
  GList *to_connect = NULL;

  GST_DEBUG_OBJECT (dbin, "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 (dbin, "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 (dbin, "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 (dbin,
              "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 (dbin, "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 (dbin,
              "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 (dbin, "ignoring request padtemplate %s", templ_name);
        break;
    }
  }

  /* 2. if there are more potential pads, connect to relevant signals */
  if (dynamic) {
    GST_LOG_OBJECT (dbin, "Adding signals to element %s in chain %p",
        GST_ELEMENT_NAME (element), chain);
    delem->pad_added_id = g_signal_connect (element, "pad-added",
        G_CALLBACK (pad_added_cb), chain);
    delem->pad_removed_id = g_signal_connect (element, "pad-removed",
        G_CALLBACK (pad_removed_cb), chain);
    delem->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 decoded pad.
 */
static void
expose_pad (GstDecodeBin * dbin, GstElement * src, GstDecodePad * dpad,
    GstPad * pad, GstCaps * caps, GstDecodeChain * chain)
{
  GstPad *mqpad = NULL;

  GST_DEBUG_OBJECT (dbin, "pad %s:%s, chain:%p",
      GST_DEBUG_PAD_NAME (pad), chain);

  /* If this is the first pad for this chain, there are no other elements
   * and the source element is not the multiqueue we must link through the
   * multiqueue.
   *
   * This is the case if a demuxer directly exposed a raw pad.
   */
  if (chain->parent && !chain->elements && src != chain->parent->multiqueue) {
    GST_LOG_OBJECT (src, "connecting the pad through multiqueue");

    decode_pad_set_target (dpad, NULL);
    if (!(mqpad = gst_decode_group_control_demuxer_pad (chain->parent, pad)))
      goto beach;
    pad = mqpad;
    decode_pad_set_target (dpad, pad);
  }

  gst_decode_pad_activate (dpad, chain);
  chain->endpad = gst_object_ref (dpad);
  chain->endcaps = gst_caps_ref (caps);

  EXPOSE_LOCK (dbin);
  if (dbin->decode_chain) {
    if (gst_decode_chain_is_complete (dbin->decode_chain)) {
      gst_decode_bin_expose (dbin);
    }
  }
  EXPOSE_UNLOCK (dbin);

  if (mqpad)
    gst_object_unref (mqpad);

beach:
  return;
}

/* check_upstream_seekable:
 *
 * Check if upstream is seekable.
 */
static gboolean
check_upstream_seekable (GstDecodeBin * dbin, GstPad * pad)
{
  GstQuery *query;
  gint64 start = -1, stop = -1;
  gboolean seekable = FALSE;

  query = gst_query_new_seeking (GST_FORMAT_BYTES);
  if (!gst_pad_peer_query (pad, query)) {
    GST_DEBUG_OBJECT (dbin, "seeking query failed");
    goto done;
  }

  gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);

  /* try harder to query upstream size if we didn't get it the first time */
  if (seekable && stop == -1) {
    GST_DEBUG_OBJECT (dbin, "doing duration query to fix up unset stop");
    gst_pad_peer_query_duration (pad, GST_FORMAT_BYTES, &stop);
  }

  /* if upstream doesn't know the size, it's likely that it's not seekable in
   * practice even if it technically may be seekable */
  if (seekable && (start != 0 || stop <= start)) {
    GST_DEBUG_OBJECT (dbin, "seekable but unknown start/stop -> disable");
    seekable = FALSE;
  } else {
    GST_DEBUG_OBJECT (dbin, "upstream seekable: %d", seekable);
  }

done:
  gst_query_unref (query);
  return seekable;
}

static void
type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstDecodeBin * decode_bin)
{
  GstPad *pad, *sink_pad;
  GstDecodeChain *chain;

  GST_DEBUG_OBJECT (decode_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 (decode_bin, STREAM, WRONG_TYPE,
        (_("This appears to be a text file")),
        ("decodebin cannot decode plain text files"));
    goto exit;
  }

  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. decode_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);
  /* FIXME: we can only deal with one type, we don't yet support dynamically changing
   * caps from the typefind element */
  if (decode_bin->have_type || decode_bin->decode_chain) {
  } else {
    decode_bin->have_type = TRUE;

    decode_bin->decode_chain = gst_decode_chain_new (decode_bin, NULL, pad);
    chain = gst_decode_chain_ref (decode_bin->decode_chain);

    if (analyze_new_pad (decode_bin, typefind, pad, caps,
            decode_bin->decode_chain, NULL))
      expose_pad (decode_bin, typefind, decode_bin->decode_chain->current_pad,
          pad, caps, decode_bin->decode_chain);

    gst_decode_chain_unref (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;
  GstDecodeChain *chain = ppad->chain;
  GstDecodeBin *dbin = chain->dbin;

  g_assert (ppad);
  g_assert (chain);
  g_assert (dbin);
  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 (dbin);
      if (dbin->decode_chain)
        if (gst_decode_chain_is_complete (dbin->decode_chain))
          gst_decode_bin_expose (dbin);
      EXPOSE_UNLOCK (dbin);
      break;
    default:
      break;
  }
  return GST_PAD_PROBE_OK;
}

static void
pad_added_cb (GstElement * element, GstPad * pad, GstDecodeChain * chain)
{
  GstCaps *caps;
  GstDecodeBin *dbin;
  GstDecodeChain *new_chain;

  dbin = chain->dbin;

  GST_DEBUG_OBJECT (pad, "pad added, chain:%p", chain);
  GST_PAD_STREAM_LOCK (pad);
  if (!gst_pad_is_active (pad)) {
    GST_PAD_STREAM_UNLOCK (pad);
    GST_DEBUG_OBJECT (pad, "Ignoring pad-added from a deactivated pad");
    return;
  }

  caps = get_pad_caps (pad);
  if (analyze_new_pad (dbin, element, pad, caps, chain, &new_chain))
    expose_pad (dbin, element, new_chain->current_pad, pad, caps, new_chain);
  if (caps)
    gst_caps_unref (caps);

  GST_PAD_STREAM_UNLOCK (pad);
}

static GstPadProbeReturn
sink_pad_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstDecodeGroup *group = (GstDecodeGroup *) user_data;
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstPad *peer = gst_pad_get_peer (pad);
  GstPadProbeReturn proberet = GST_PAD_PROBE_OK;

  GST_DEBUG_OBJECT (pad, "Got upstream event %s", GST_EVENT_TYPE_NAME (event));

  if (peer == NULL) {
    GST_DEBUG_OBJECT (pad, "We are unlinked !");
    if (group->parent && group->parent->next_groups) {
      GstDecodeGroup *last_group =
          g_list_last (group->parent->next_groups)->data;
      GST_DEBUG_OBJECT (pad, "We could send the event to another group (%p)",
          last_group);
      /* Grab another sinkpad for that last group through which we will forward this event */
      if (last_group->reqpads) {
        GstPad *sinkpad = (GstPad *) last_group->reqpads->data;
        GstPad *otherpeer = gst_pad_get_peer (sinkpad);
        if (otherpeer) {
          GST_DEBUG_OBJECT (otherpeer, "Attempting to forward event");
          if (gst_pad_send_event (otherpeer, gst_event_ref (event))) {
            gst_event_unref (event);
            proberet = GST_PAD_PROBE_HANDLED;
          }
          gst_object_unref (otherpeer);
        }
      } else {
        GST_DEBUG_OBJECT (pad, "No request pads, can't forward event");
      }
    }
  } else {
    gst_object_unref (peer);
  }

  return proberet;
}

static GstPadProbeReturn
sink_pad_query_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstDecodeGroup *group = (GstDecodeGroup *) user_data;
  GstPad *peer = gst_pad_get_peer (pad);
  GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info);
  GstPadProbeReturn proberet = GST_PAD_PROBE_OK;

  GST_DEBUG_OBJECT (pad, "Got upstream query %s", GST_QUERY_TYPE_NAME (query));

  if (peer == NULL) {
    GST_DEBUG_OBJECT (pad, "We are unlinked !");
    if (group->parent && group->parent->next_groups) {
      GstDecodeGroup *last_group =
          g_list_last (group->parent->next_groups)->data;
      GST_DEBUG_OBJECT (pad, "We could send the query to another group");
      /* Grab another sinkpad for that last group through which we will forward this event */
      if (last_group->reqpads) {
        GstPad *sinkpad = (GstPad *) last_group->reqpads->data;
        GstPad *otherpeer = gst_pad_get_peer (sinkpad);
        if (otherpeer) {
          GST_DEBUG_OBJECT (otherpeer, "Attempting to forward query");
          if (gst_pad_query (otherpeer, query)) {
            proberet = GST_PAD_PROBE_HANDLED;
          } else
            GST_DEBUG ("FAILURE");
          gst_object_unref (otherpeer);
        } else
          GST_DEBUG_OBJECT (sinkpad, "request pad not connected ??");
      } else
        GST_DEBUG_OBJECT (pad, "No request pads ???");
    }
  } else
    gst_object_unref (peer);

  return proberet;
}

static void
pad_removed_cb (GstElement * element, GstPad * pad, GstDecodeChain * 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, GstDecodeChain * chain)
{
  GstDecodeGroup *group = NULL;

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

  CHAIN_MUTEX_LOCK (chain);
  if (!chain->elements
      || ((GstDecodeElement *) chain->elements->data)->element != element) {
    GST_LOG_OBJECT (chain->dbin, "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->dbin, "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->dbin, "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;
  /* this group has prerolled enough to not need more pads,
   * we can probably set its buffering state to playing now */
  GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
      "'playing' buffering mode", group);
  decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE,
      (group->parent ? group->parent->seekable : TRUE));
  CHAIN_MUTEX_UNLOCK (chain);

  EXPOSE_LOCK (chain->dbin);
  if (chain->dbin->decode_chain) {
    if (gst_decode_chain_is_complete (chain->dbin->decode_chain)) {
      gst_decode_bin_expose (chain->dbin);
    }
  }
  EXPOSE_UNLOCK (chain->dbin);
}

static void
caps_notify_cb (GstPad * pad, GParamSpec * unused, GstDecodeChain * 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;
}

static gboolean
is_adaptive_demuxer_element (GstElement * srcelement)
{
  GstElementFactory *srcfactory;
  const gchar *klass;

  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") || !strstr (klass, "Adaptive"))
    return FALSE;

  return TRUE;
}

/* Returns TRUE if the caps are compatible with the caps specified in the 'caps'
 * property (which by default are the raw caps)
 *
 * The decodebin_lock should be taken !
 */
static gboolean
are_final_caps (GstDecodeBin * dbin, GstCaps * caps)
{
  gboolean res;

  GST_LOG_OBJECT (dbin, "Checking with caps %" GST_PTR_FORMAT, caps);

  /* lock for getting the caps */
  GST_OBJECT_LOCK (dbin);
  res = gst_caps_is_subset (caps, dbin->caps);
  GST_OBJECT_UNLOCK (dbin);

  GST_LOG_OBJECT (dbin, "Caps are %sfinal caps", res ? "" : "not ");

  return res;
}

/* gst_decode_bin_reset_buffering:
 *
 * Enables buffering on the last multiqueue of each group only,
 * disabling the rest
 *
 */
static void
gst_decode_bin_reset_buffering (GstDecodeBin * dbin)
{
  if (!dbin->use_buffering)
    return;

  GST_DEBUG_OBJECT (dbin, "Reseting multiqueues buffering");
  if (dbin->decode_chain) {
    CHAIN_MUTEX_LOCK (dbin->decode_chain);
    gst_decode_chain_reset_buffering (dbin->decode_chain);
    CHAIN_MUTEX_UNLOCK (dbin->decode_chain);
  }
}

/****
 * GstDecodeChain functions
 ****/

static gboolean
gst_decode_chain_reset_buffering (GstDecodeChain * chain)
{
  GstDecodeGroup *group;

  group = chain->active_group;
  GST_LOG_OBJECT (chain->dbin, "Resetting chain %p buffering, active group: %p",
      chain, group);
  if (group) {
    return gst_decode_group_reset_buffering (group);
  }
  return FALSE;
}

/* gst_decode_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 GstDecodeGroup *
gst_decode_chain_get_current_group (GstDecodeChain * chain)
{
  GstDecodeGroup *group;

  if (!chain->next_groups && chain->active_group
      && chain->active_group->overrun && !chain->active_group->no_more_pads) {
    GST_WARNING_OBJECT (chain->dbin,
        "Currently active group %p is exposed"
        " and wants to add a new pad without having signaled no-more-pads",
        chain->active_group);
    return NULL;
  }

  if (chain->next_groups && (group = chain->next_groups->data) && group->overrun
      && !group->no_more_pads) {
    GST_WARNING_OBJECT (chain->dbin,
        "Currently newest pending group %p "
        "had overflow but didn't signal no-more-pads", group);
    return NULL;
  }

  /* Now we know that we can really return something useful */
  if (!chain->active_group) {
    chain->active_group = group = gst_decode_group_new (chain->dbin, chain);
  } else if (!chain->active_group->overrun
      && !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)) {
      GstDecodeGroup *next_group = iter->data;

      if (!next_group->overrun && !next_group->no_more_pads) {
        group = next_group;
        break;
      }
    }
  }
  if (!group) {
    group = gst_decode_group_new (chain->dbin, chain);
    chain->next_groups = g_list_append (chain->next_groups, group);
  }

  return group;
}

static void gst_decode_group_free_internal (GstDecodeGroup * group,
    gboolean hide);

static void
gst_decode_chain_unref (GstDecodeChain * chain)
{
  if (g_atomic_int_dec_and_test (&chain->refs)) {
    g_mutex_clear (&chain->lock);
    g_slice_free (GstDecodeChain, chain);
  }
}

static GstDecodeChain *
gst_decode_chain_ref (GstDecodeChain * chain)
{
  g_atomic_int_inc (&chain->refs);
  return chain;
}

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

  CHAIN_MUTEX_LOCK (chain);

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

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

  for (l = chain->next_groups; l; l = l->next) {
    gst_decode_group_free_internal ((GstDecodeGroup *) 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) {
      GstDecodeGroup *group = l->data;

      gst_decode_group_free (group);
    }
    g_list_free (chain->old_groups);
    chain->old_groups = 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) {
    GstDecodeElement *delem = l->data;
    GstElement *element = delem->element;

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

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

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

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

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

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

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

  if (chain->endpad) {
    if (chain->endpad->exposed) {
      gst_element_remove_pad (GST_ELEMENT_CAST (chain->dbin),
          GST_PAD_CAST (chain->endpad));
    }

    decode_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->endcaps) {
    gst_caps_unref (chain->endcaps);
    chain->endcaps = NULL;
  }
  g_free (chain->deadend_details);
  chain->deadend_details = NULL;

  GST_DEBUG_OBJECT (chain->dbin, "%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)
    gst_decode_chain_unref (chain);
}

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

/* gst_decode_chain_new:
 *
 * Creates a new decode chain and initializes it.
 *
 * It's up to the caller to add it to the list of child chains of
 * a group!
 */
static GstDecodeChain *
gst_decode_chain_new (GstDecodeBin * dbin, GstDecodeGroup * parent,
    GstPad * pad)
{
  GstDecodeChain *chain = g_slice_new0 (GstDecodeChain);

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

  chain->dbin = dbin;
  chain->parent = parent;
  chain->refs = 1;
  g_mutex_init (&chain->lock);
  chain->pad = gst_object_ref (pad);

  return chain;
}

/****
 * GstDecodeGroup functions
 ****/

/* The overrun callback is used to expose groups that have not yet had their
 * no_more_pads called while the (large) multiqueue overflowed. When this
 * happens we must assume that the no_more_pads will not arrive anymore and we
 * must expose the pads that we have.
 */
static void
multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group)
{
  GstDecodeBin *dbin;

  dbin = group->dbin;

  GST_LOG_OBJECT (dbin, "multiqueue '%s' (%p) is full", GST_OBJECT_NAME (queue),
      queue);

  group->overrun = TRUE;
  /* this group has prerolled enough to not need more pads,
   * we can probably set its buffering state to playing now */
  GST_DEBUG_OBJECT (group->dbin, "Setting group %p multiqueue to "
      "'playing' buffering mode", group);
  decodebin_set_queue_size (group->dbin, group->multiqueue, FALSE,
      (group->parent ? group->parent->seekable : TRUE));

  /* FIXME: We should make sure that everything gets exposed now
   * even if child chains are not complete because the will never
   * be complete! Ignore any non-complete chains when exposing
   * and never expose them later
   */

  EXPOSE_LOCK (dbin);
  if (dbin->decode_chain) {
    if (gst_decode_chain_is_complete (dbin->decode_chain)) {
      if (!gst_decode_bin_expose (dbin))
        GST_WARNING_OBJECT (dbin, "Couldn't expose group");
    }
  }
  EXPOSE_UNLOCK (dbin);
}

static void
gst_decode_group_free_internal (GstDecodeGroup * group, gboolean hide)
{
  GList *l;

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

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

  if (!hide) {
    for (l = group->reqpads; l; l = l->next) {
      GstPad *pad = l->data;

      gst_element_release_request_pad (group->multiqueue, pad);
      gst_object_unref (pad);
      l->data = NULL;
    }
    g_list_free (group->reqpads);
    group->reqpads = NULL;
  }

  if (group->multiqueue) {
    if (group->overrunsig) {
      g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
      group->overrunsig = 0;
    }

    if (GST_OBJECT_PARENT (group->multiqueue) == GST_OBJECT_CAST (group->dbin))
      gst_bin_remove (GST_BIN_CAST (group->dbin), group->multiqueue);
    if (!hide) {
      gst_element_set_state (group->multiqueue, GST_STATE_NULL);
      gst_object_unref (group->multiqueue);
      group->multiqueue = NULL;
    }
  }

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

/* gst_decode_group_free:
 *
 * Completely frees and removes the decode 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_decode_group_free (GstDecodeGroup * group)
{
  gst_decode_group_free_internal (group, FALSE);
}

/* gst_decode_group_hide:
 *
 * Hide the decode group only, this means that
 * all child endpads are removed from decodebin
 * 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_decode_group_hide (GstDecodeGroup * group)
{
  gst_decode_group_free_internal (group, TRUE);
}

/* gst_decode_chain_free_hidden_groups:
 *
 * Frees any decode 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_decode_chain_free_hidden_groups (GList * old_groups)
{
  GList *l;

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

    gst_decode_group_free (group);
  }
  g_list_free (old_groups);
}

static void
gst_decode_chain_start_free_hidden_groups_thread (GstDecodeChain * 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_decode_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->dbin, "Started free-hidden-groups thread");
  /* We do not need to wait for it or get any results from it */
  g_thread_unref (thread);
}

static void
decodebin_set_queue_size (GstDecodeBin * dbin, GstElement * multiqueue,
    gboolean preroll, gboolean seekable)
{
  gboolean use_buffering;

  /* get the current config from the multiqueue */
  g_object_get (multiqueue, "use-buffering", &use_buffering, NULL);

  decodebin_set_queue_size_full (dbin, multiqueue, use_buffering, preroll,
      seekable);
}

/* configure queue sizes, this depends on the buffering method and if we are
 * playing or prerolling. */
static void
decodebin_set_queue_size_full (GstDecodeBin * dbin, GstElement * multiqueue,
    gboolean use_buffering, gboolean preroll, gboolean seekable)
{
  guint max_bytes, max_buffers;
  guint64 max_time;

  GST_DEBUG_OBJECT (multiqueue, "use buffering %d", use_buffering);

  if (preroll || use_buffering) {
    /* takes queue limits, initially we only queue up up to the max bytes limit,
     * with a default of 2MB. we use the same values for buffering mode. */
    if (preroll || (max_bytes = dbin->max_size_bytes) == 0)
      max_bytes = AUTO_PREROLL_SIZE_BYTES;
    if (preroll || (max_buffers = dbin->max_size_buffers) == 0)
      max_buffers = AUTO_PREROLL_SIZE_BUFFERS;
    if (preroll || (max_time = dbin->max_size_time) == 0) {
      if (dbin->use_buffering && !preroll)
        max_time = 5 * GST_SECOND;
      else
        max_time = seekable ? AUTO_PREROLL_SEEKABLE_SIZE_TIME :
            AUTO_PREROLL_NOT_SEEKABLE_SIZE_TIME;
    }
  } else {
    /* update runtime limits. At runtime, we try to keep the amount of buffers
     * in the queues as low as possible (but at least 5 buffers). */
    if (dbin->use_buffering)
      max_bytes = 0;
    else if ((max_bytes = dbin->max_size_bytes) == 0)
      max_bytes = AUTO_PLAY_SIZE_BYTES;
    if ((max_buffers = dbin->max_size_buffers) == 0)
      max_buffers = AUTO_PLAY_SIZE_BUFFERS;
    /* this is a multiqueue with disabled buffering, don't limit max_time */
    if (dbin->use_buffering)
      max_time = 0;
    else if ((max_time = dbin->max_size_time) == 0)
      max_time = AUTO_PLAY_SIZE_TIME;
  }

  GST_DEBUG_OBJECT (multiqueue, "setting limits %u bytes, %u buffers, "
      "%" G_GUINT64_FORMAT " time", max_bytes, max_buffers, max_time);
  g_object_set (multiqueue,
      "max-size-bytes", max_bytes, "max-size-time", max_time,
      "max-size-buffers", max_buffers, NULL);
}

/* gst_decode_group_new:
 * @dbin: Parent decodebin
 * @parent: Parent chain or %NULL
 *
 * Creates a new GstDecodeGroup. It is up to the caller to add it to the list
 * of groups.
 */
static GstDecodeGroup *
gst_decode_group_new (GstDecodeBin * dbin, GstDecodeChain * parent)
{
  GstDecodeGroup *group = g_slice_new0 (GstDecodeGroup);
  GstElement *mq;
  gboolean seekable;

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

  group->dbin = dbin;
  group->parent = parent;

  mq = group->multiqueue = gst_element_factory_make ("multiqueue", NULL);
  if (G_UNLIKELY (!group->multiqueue))
    goto missing_multiqueue;

  /* configure queue sizes for preroll */
  seekable = FALSE;
  if (parent && parent->demuxer) {
    GstElement *element =
        ((GstDecodeElement *) parent->elements->data)->element;
    GstPad *pad = gst_element_get_static_pad (element, "sink");
    if (pad) {
      seekable = parent->seekable = check_upstream_seekable (dbin, pad);
      gst_object_unref (pad);
    }
  }
  decodebin_set_queue_size_full (dbin, mq, FALSE, TRUE, seekable);

  group->overrunsig = g_signal_connect (mq, "overrun",
      G_CALLBACK (multi_queue_overrun_cb), group);

  gst_element_set_state (mq, GST_STATE_PAUSED);
  gst_bin_add (GST_BIN (dbin), gst_object_ref (mq));

  return group;

  /* ERRORS */
missing_multiqueue:
  {
    gst_element_post_message (GST_ELEMENT_CAST (dbin),
        gst_missing_element_message_new (GST_ELEMENT_CAST (dbin),
            "multiqueue"));
    GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL), ("no multiqueue!"));
    g_slice_free (GstDecodeGroup, group);
    return NULL;
  }
}

/* gst_decode_group_control_demuxer_pad
 *
 * Adds a new demuxer srcpad to the given group.
 *
 * Returns the srcpad of the multiqueue corresponding the given pad.
 * Returns NULL if there was an error.
 */
static GstPad *
gst_decode_group_control_demuxer_pad (GstDecodeGroup * group, GstPad * pad)
{
  GstDecodeBin *dbin;
  GstPad *srcpad, *sinkpad;
  GstIterator *it = NULL;
  GValue item = { 0, };

  dbin = group->dbin;

  GST_LOG_OBJECT (dbin, "group:%p pad %s:%s", group, GST_DEBUG_PAD_NAME (pad));

  srcpad = NULL;

  if (G_UNLIKELY (!group->multiqueue))
    return NULL;

  if (!(sinkpad = gst_element_get_request_pad (group->multiqueue, "sink_%u"))) {
    GST_ERROR_OBJECT (dbin, "Couldn't get sinkpad from multiqueue");
    return NULL;
  }

  if ((gst_pad_link_full (pad, sinkpad,
              GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)) {
    GST_ERROR_OBJECT (dbin, "Couldn't link demuxer and multiqueue");
    goto error;
  }

  it = gst_pad_iterate_internal_links (sinkpad);

  if (!it || (gst_iterator_next (it, &item)) != GST_ITERATOR_OK
      || ((srcpad = g_value_dup_object (&item)) == NULL)) {
    GST_ERROR_OBJECT (dbin,
        "Couldn't get srcpad from multiqueue for sinkpad %" GST_PTR_FORMAT,
        sinkpad);
    goto error;
  }
  gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_UPSTREAM,
      sink_pad_event_probe, group, NULL);
  gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_QUERY_UPSTREAM,
      sink_pad_query_probe, group, NULL);

  CHAIN_MUTEX_LOCK (group->parent);
  group->reqpads = g_list_prepend (group->reqpads, gst_object_ref (sinkpad));
  CHAIN_MUTEX_UNLOCK (group->parent);

beach:
  if (G_IS_VALUE (&item))
    g_value_unset (&item);
  if (it)
    gst_iterator_free (it);
  gst_object_unref (sinkpad);
  return srcpad;

error:
  gst_element_release_request_pad (group->multiqueue, sinkpad);
  goto beach;
}

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

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

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

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

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

/* gst_decode_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
 *
 * Not MT-safe, always call with decodebin expose lock
 */
static gboolean
gst_decode_chain_is_complete (GstDecodeChain * chain)
{
  gboolean complete = FALSE;

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

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

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

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

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

/* Flushing group/chains */
static void
flush_group (GstDecodeGroup * group, gboolean flushing)
{
  GList *tmp;

  GST_DEBUG ("group %p flushing:%d", group, flushing);

  if (group->drained == flushing)
    return;
  for (tmp = group->children; tmp; tmp = tmp->next) {
    GstDecodeChain *chain = (GstDecodeChain *) tmp->data;
    flush_chain (chain, flushing);
  }
  GST_DEBUG ("Setting group %p to drained:%d", group, flushing);
  group->drained = flushing;
}

static void
flush_chain (GstDecodeChain * chain, gboolean flushing)
{
  GList *tmp;
  GstDecodeBin *dbin = chain->dbin;

  GST_DEBUG_OBJECT (dbin, "chain %p (pad %s:%s) flushing:%d", chain,
      GST_DEBUG_PAD_NAME (chain->pad), flushing);
  if (chain->drained == flushing)
    return;
  /* if unflushing, check if we should switch to last group */
  if (flushing == FALSE && chain->next_groups) {
    GstDecodeGroup *target_group =
        (GstDecodeGroup *) g_list_last (chain->next_groups)->data;
    gst_decode_chain_start_free_hidden_groups_thread (chain);
    /* Hide active group (we're sure it's not that one we'll be using) */
    GST_DEBUG_OBJECT (dbin, "Switching from active group %p to group %p",
        chain->active_group, target_group);
    gst_decode_group_hide (chain->active_group);
    chain->old_groups = g_list_prepend (chain->old_groups, chain->active_group);
    chain->active_group = target_group;
    /* Hide all groups but the target_group */
    for (tmp = chain->next_groups; tmp; tmp = tmp->next) {
      GstDecodeGroup *group = (GstDecodeGroup *) tmp->data;
      if (group != target_group) {
        gst_decode_group_hide (group);
        chain->old_groups = g_list_prepend (chain->old_groups, group);
      }
    }
    /* Clear next groups */
    g_list_free (chain->next_groups);
    chain->next_groups = NULL;
  }
  /* Mark all groups as flushing */
  if (chain->active_group)
    flush_group (chain->active_group, flushing);
  for (tmp = chain->next_groups; tmp; tmp = tmp->next) {
    GstDecodeGroup *group = (GstDecodeGroup *) tmp->data;
    flush_group (group, flushing);
  }
  GST_DEBUG ("Setting chain %p to drained:%d", chain, flushing);
  chain->drained = flushing;
}

static gboolean
drain_and_switch_chains (GstDecodeChain * chain, GstDecodePad * 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 (GstDecodeGroup * group, GstDecodePad * 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) {
    GstDecodeChain *chain = (GstDecodeChain *) 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 (GstDecodeChain * chain, GstDecodePad * drainpad,
    gboolean * last_group, gboolean * drained, gboolean * switched)
{
  gboolean handled = FALSE;
  GstDecodeBin *dbin = chain->dbin;

  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 */
        GST_DEBUG_OBJECT (dbin, "Hiding current group %p", chain->active_group);
        gst_decode_group_hide (chain->active_group);
        chain->old_groups =
            g_list_prepend (chain->old_groups, chain->active_group);
        GST_DEBUG_OBJECT (dbin, "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);
        gst_decode_chain_start_free_hidden_groups_thread (chain);
        *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 (dbin, gst_decode_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_decode_pad_handle_eos (GstDecodePad * pad)
{
  gboolean last_group = TRUE;
  gboolean switched = FALSE;
  gboolean drained = FALSE;
  GstDecodeChain *chain = pad->chain;
  GstDecodeBin *dbin = chain->dbin;
  GstEvent *tmp;

  GST_LOG_OBJECT (dbin, "pad %p", pad);

  /* Send a stream-group-done event in case downstream needs
   * to unblock before we can drain */
  tmp = gst_pad_get_sticky_event (GST_PAD (pad), GST_EVENT_STREAM_START, 0);
  if (tmp) {
    guint group_id;
    if (gst_event_parse_group_id (tmp, &group_id)) {
      GstPad *peer = gst_pad_get_peer (GST_PAD (pad));

      if (peer) {
        GST_DEBUG_OBJECT (dbin,
            "Sending stream-group-done for group %u to pad %"
            GST_PTR_FORMAT, group_id, pad);
        gst_pad_send_event (peer, gst_event_new_stream_group_done (group_id));
        gst_object_unref (peer);
      }
    } else {
      GST_DEBUG_OBJECT (dbin,
          "No group ID to send stream-group-done on pad %" GST_PTR_FORMAT, pad);
    }
    gst_event_unref (tmp);
  }

  EXPOSE_LOCK (dbin);
  if (dbin->decode_chain) {
    drain_and_switch_chains (dbin->decode_chain, pad, &last_group, &drained,
        &switched);

    if (switched) {
      /* If we resulted in a group switch, expose what's needed */
      if (gst_decode_chain_is_complete (dbin->decode_chain))
        gst_decode_bin_expose (dbin);
    }
  }
  EXPOSE_UNLOCK (dbin);

  return last_group;
}

/* gst_decode_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_decode_group_is_drained (GstDecodeGroup * group)
{
  GList *l;
  gboolean drained = TRUE;

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

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

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

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

/* gst_decode_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_decode_chain_is_drained (GstDecodeChain * 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_decode_group_is_drained (chain->active_group)
      && !chain->next_groups) {
    drained = TRUE;
    goto out;
  }

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

static gboolean
gst_decode_group_reset_buffering (GstDecodeGroup * group)
{
  GList *l;
  gboolean ret = TRUE;

  GST_DEBUG_OBJECT (group->dbin, "Group reset buffering %p %s", group,
      GST_ELEMENT_NAME (group->multiqueue));
  for (l = group->children; l; l = l->next) {
    GstDecodeChain *chain = l->data;

    CHAIN_MUTEX_LOCK (chain);
    if (!gst_decode_chain_reset_buffering (chain)) {
      ret = FALSE;
    }
    CHAIN_MUTEX_UNLOCK (chain);
  }

  decodebin_set_queue_size_full (group->dbin, group->multiqueue, !ret,
      FALSE, (group->parent ? group->parent->seekable : TRUE));

  if (ret) {
    /* all chains are buffering already, no need to do it here */
    g_object_set (group->multiqueue, "use-buffering", FALSE, NULL);
  } else {
    g_object_set (group->multiqueue, "use-buffering", TRUE,
        "low-percent", group->dbin->low_percent,
        "high-percent", group->dbin->high_percent, NULL);
  }

  GST_DEBUG_OBJECT (group->dbin, "Setting %s buffering to %d",
      GST_ELEMENT_NAME (group->multiqueue), !ret);
  return TRUE;
}


/* 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 (GstDecodePad * da, GstDecodePad * 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, "audio/x-raw"))
    va = 2;
  else if (g_strrstr (namea, "audio/"))
    va = 3;
  else
    va = 4;

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

  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 GstCaps *
_gst_element_get_linked_caps (GstElement * src, GstElement * sink,
    GstPad ** srcpad)
{
  GstIterator *it;
  GstElement *parent;
  GstPad *pad, *peer;
  gboolean done = FALSE;
  GstCaps *caps = NULL;
  GValue item = { 0, };

  it = gst_element_iterate_src_pads (src);
  while (!done) {
    switch (gst_iterator_next (it, &item)) {
      case GST_ITERATOR_OK:
        pad = g_value_get_object (&item);
        peer = gst_pad_get_peer (pad);
        if (peer) {
          parent = gst_pad_get_parent_element (peer);
          if (parent == sink) {
            caps = gst_pad_get_current_caps (pad);
            if (srcpad) {
              gst_object_ref (pad);
              *srcpad = pad;
            }
            done = TRUE;
          }

          if (parent)
            gst_object_unref (parent);
          gst_object_unref (peer);
        }
        g_value_reset (&item);
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (it);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }
  g_value_unset (&item);
  gst_iterator_free (it);

  return caps;
}

static GQuark topology_structure_name = 0;
static GQuark topology_caps = 0;
static GQuark topology_next = 0;
static GQuark topology_pad = 0;
static GQuark topology_element_srcpad = 0;

/* FIXME: Invent gst_structure_take_structure() to prevent all the
 * structure copying for nothing
 */
static GstStructure *
gst_decode_chain_get_topology (GstDecodeChain * chain)
{
  GstStructure *s, *u;
  GList *l;
  GstCaps *caps;

  if (G_UNLIKELY ((chain->endpad || chain->deadend)
          && (chain->endcaps == NULL))) {
    GST_WARNING ("End chain without valid caps !");
    return NULL;
  }

  u = gst_structure_new_id_empty (topology_structure_name);

  /* Now at the last element */
  if ((chain->elements || !chain->active_group) &&
      (chain->endpad || chain->deadend)) {
    s = gst_structure_new_id_empty (topology_structure_name);
    gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, chain->endcaps,
        NULL);

    if (chain->endpad) {
      gst_structure_id_set (u, topology_pad, GST_TYPE_PAD, chain->endpad, NULL);
      gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD,
          chain->endpad, NULL);
    }
    gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL);
    gst_structure_free (u);
    u = s;
  } else if (chain->active_group) {
    GValue list = { 0, };
    GValue item = { 0, };

    g_value_init (&list, GST_TYPE_LIST);
    g_value_init (&item, GST_TYPE_STRUCTURE);
    for (l = chain->active_group->children; l; l = l->next) {
      s = gst_decode_chain_get_topology (l->data);
      if (s) {
        gst_value_set_structure (&item, s);
        gst_value_list_append_value (&list, &item);
        g_value_reset (&item);
        gst_structure_free (s);
      }
    }
    gst_structure_id_set_value (u, topology_next, &list);
    g_value_unset (&list);
    g_value_unset (&item);
  }

  /* Get caps between all elements in this chain */
  l = (chain->elements && chain->elements->next) ? chain->elements : NULL;
  for (; l && l->next; l = l->next) {
    GstDecodeElement *delem, *delem_next;
    GstElement *elem, *elem_next;
    GstCaps *caps;
    GstPad *srcpad;

    delem = l->data;
    elem = delem->element;
    delem_next = l->next->data;
    elem_next = delem_next->element;
    srcpad = NULL;

    caps = _gst_element_get_linked_caps (elem_next, elem, &srcpad);

    if (caps) {
      s = gst_structure_new_id_empty (topology_structure_name);
      gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL);
      gst_caps_unref (caps);

      gst_structure_id_set (s, topology_next, GST_TYPE_STRUCTURE, u, NULL);
      gst_structure_free (u);
      u = s;
    }

    if (srcpad) {
      gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD, srcpad,
          NULL);
      gst_object_unref (srcpad);
    }
  }

  /* Caps that resulted in this chain */
  caps = get_pad_caps (chain->pad);
  if (G_UNLIKELY (!caps)) {
    GST_WARNING_OBJECT (chain->pad, "Couldn't get the caps of decode chain");
    return u;
  }
  gst_structure_id_set (u, topology_caps, GST_TYPE_CAPS, caps, NULL);
  gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD, chain->pad,
      NULL);
  gst_caps_unref (caps);

  return u;
}

static void
gst_decode_bin_post_topology_message (GstDecodeBin * dbin)
{
  GstStructure *s;
  GstMessage *msg;

  s = gst_decode_chain_get_topology (dbin->decode_chain);

  if (G_UNLIKELY (s == NULL))
    return;
  msg = gst_message_new_element (GST_OBJECT (dbin), s);
  gst_element_post_message (GST_ELEMENT (dbin), msg);
}

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 decodebin expose lock! */
static gboolean
gst_decode_bin_expose (GstDecodeBin * dbin)
{
  GList *tmp, *endpads;
  gboolean missing_plugin;
  GString *missing_plugin_details;
  gboolean already_exposed;
  gboolean last_group;

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

  missing_plugin_details = g_string_new ("");

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

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

  /* Get the pads that we're going to expose and mark things as exposed */
  if (!gst_decode_chain_expose (dbin->decode_chain, &endpads, &missing_plugin,
          missing_plugin_details, &last_group)) {
    g_list_foreach (endpads, (GFunc) gst_object_unref, NULL);
    g_list_free (endpads);
    g_string_free (missing_plugin_details, TRUE);
    GST_ERROR_OBJECT (dbin, "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 (dbin, 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 (dbin, 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 (dbin, "All streams finished without buffers. "
          "Last group: %d", last_group);
      if (last_group) {
        GST_ELEMENT_ERROR (dbin, STREAM, FAILED, (NULL),
            ("all streams without buffers"));
      } else {
        gboolean switched = FALSE;
        gboolean drained = FALSE;

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

    do_async_done (dbin);
    return FALSE;
  }

  g_string_free (missing_plugin_details, TRUE);

  /* Check if this was called when everything was exposed already */
  for (tmp = endpads; tmp && already_exposed; tmp = tmp->next) {
    GstDecodePad *dpad = tmp->data;

    already_exposed &= dpad->exposed;
    if (!already_exposed)
      break;
  }
  if (already_exposed) {
    GST_DEBUG_OBJECT (dbin, "Everything was exposed already!");
    g_list_foreach (endpads, (GFunc) gst_object_unref, NULL);
    g_list_free (endpads);
    return TRUE;
  }

  /* going to expose something, reset buffering */
  gst_decode_bin_reset_buffering (dbin);

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

    if (dpad->exposed) {
      GST_DEBUG_OBJECT (dpad, "blocking exposed pad");
      gst_decode_pad_set_blocked (dpad, 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) {
    GstDecodePad *dpad = (GstDecodePad *) tmp->data;
    gchar *padname;

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

    gst_pad_sticky_events_foreach (GST_PAD_CAST (dpad), debug_sticky_event,
        dpad);

    /* 2. activate and add */
    if (!dpad->exposed) {
      dpad->exposed = TRUE;
      if (!gst_element_add_pad (GST_ELEMENT (dbin), GST_PAD_CAST (dpad))) {
        /* not really fatal, we can try to add the other pads */
        g_warning ("error adding pad to decodebin");
        dpad->exposed = FALSE;
        continue;
      }
    }

    /* 3. emit signal */
    GST_INFO_OBJECT (dpad, "added new decoded pad");
  }

  /* 4. Signal no-more-pads. This allows the application to hook stuff to the
   * exposed pads */
  GST_LOG_OBJECT (dbin, "signaling no-more-pads");
  gst_element_no_more_pads (GST_ELEMENT (dbin));

  /* 5. Send a custom element message with the stream topology */
  if (dbin->post_stream_topology)
    gst_decode_bin_post_topology_message (dbin);

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

    GST_DEBUG_OBJECT (dpad, "unblocking");
    gst_decode_pad_unblock (dpad);
    GST_DEBUG_OBJECT (dpad, "unblocked");
    gst_object_unref (dpad);
  }
  g_list_free (endpads);

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

/* gst_decode_chain_expose:
 *
 * Check if the chain can be exposed and add all endpads
 * to the endpads list.
 *
 * Also update the active group's multiqueue to the
 * runtime limits.
 *
 * Not MT-safe, call with decodebin expose lock! *
 */
static gboolean
gst_decode_chain_expose (GstDecodeChain * chain, GList ** endpads,
    gboolean * missing_plugin, GString * missing_plugin_details,
    gboolean * last_group)
{
  GstDecodeGroup *group;
  GList *l;
  GstDecodeBin *dbin;

  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 decoder: %s (%s)\n", desc, caps_str);
        g_free (caps_str);
        g_free (desc);
      }
      *missing_plugin = TRUE;
    }
    return TRUE;
  }

  if (chain->endpad) {
    if (!gst_decode_pad_is_exposable (chain->endpad) && !chain->endpad->exposed)
      return FALSE;
    *endpads = g_list_prepend (*endpads, gst_object_ref (chain->endpad));
    return TRUE;
  }

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

  group = chain->active_group;
  if (!group)
    return FALSE;
  if (!group->no_more_pads && !group->overrun)
    return FALSE;

  dbin = group->dbin;

  /* we can now disconnect any overrun signal, which is used to expose the
   * group. */
  if (group->overrunsig) {
    GST_LOG_OBJECT (dbin, "Disconnecting overrun");
    g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
    group->overrunsig = 0;
  }

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

    if (!gst_decode_chain_expose (childchain, endpads, missing_plugin,
            missing_plugin_details, last_group))
      return FALSE;
  }

  return TRUE;
}

/*************************
 * GstDecodePad functions
 *************************/

static void
gst_decode_pad_class_init (GstDecodePadClass * klass)
{
}

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

static GstPadProbeReturn
source_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstDecodePad *dpad = user_data;
  GstDecodeChain *chain;
  GstDecodeBin *dbin;
  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) {
      /* 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. */
      gst_pad_push_event (GST_PAD_CAST (dpad), gst_event_ref (event));

      /* let the sticky events pass */
      ret = GST_PAD_PROBE_PASS;

      /* we only want to try to expose on CAPS events */
      if (GST_EVENT_TYPE (event) != GST_EVENT_CAPS) {
        GST_LOG_OBJECT (pad, "Letting sticky non-CAPS event through");
        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 = dpad->chain;
  dbin = chain->dbin;

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

  dpad->blocked = TRUE;

  EXPOSE_LOCK (dbin);
  if (dbin->decode_chain) {
    if (gst_decode_chain_is_complete (dbin->decode_chain)) {
      if (!gst_decode_bin_expose (dbin))
        GST_WARNING_OBJECT (dbin, "Couldn't expose group");
    }
  }
  EXPOSE_UNLOCK (dbin);

done:
  return ret;
}

static GstPadProbeReturn
source_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstDecodePad *dpad = user_data;
  gboolean res = TRUE;

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

  if (GST_EVENT_TYPE (event) == 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. */
    res = gst_decode_pad_handle_eos (dpad);
  }
  if (res)
    return GST_PAD_PROBE_OK;
  else
    return GST_PAD_PROBE_DROP;
}

static void
gst_decode_pad_set_blocked (GstDecodePad * dpad, gboolean blocked)
{
  GstDecodeBin *dbin = dpad->dbin;
  GstPad *opad;

  DYN_LOCK (dbin);

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

  opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (dpad));
  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 || !dbin->shutdown) {
    if (blocked) {
      if (dpad->block_id == 0)
        dpad->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 (dpad), (GDestroyNotify) gst_object_unref);
    } else {
      if (dpad->block_id != 0) {
        gst_pad_remove_probe (opad, dpad->block_id);
        dpad->block_id = 0;
      }
      dpad->blocked = FALSE;
    }
  }

  if (blocked) {
    if (dbin->shutdown) {
      /* deactivate to force flushing state to prevent NOT_LINKED errors */
      gst_pad_set_active (GST_PAD_CAST (dpad), 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 (dpad);
      dbin->blocked_pads = g_list_prepend (dbin->blocked_pads, dpad);
    }
  } else {
    GList *l;

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

static void
gst_decode_pad_add_drained_check (GstDecodePad * dpad)
{
  gst_pad_add_probe (GST_PAD_CAST (dpad), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      source_pad_event_probe, dpad, NULL);
}

static void
gst_decode_pad_activate (GstDecodePad * dpad, GstDecodeChain * chain)
{
  g_return_if_fail (chain != NULL);

  dpad->chain = chain;
  gst_pad_set_active (GST_PAD_CAST (dpad), TRUE);
  gst_decode_pad_set_blocked (dpad, TRUE);
  gst_decode_pad_add_drained_check (dpad);
}

static void
gst_decode_pad_unblock (GstDecodePad * dpad)
{
  gst_decode_pad_set_blocked (dpad, FALSE);
}

static gboolean
gst_decode_pad_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstDecodeBin *dbin = GST_DECODE_BIN (parent);

  if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK && dbin && dbin->decode_chain) {
    GstElement *demuxer = NULL;

    /* For adaptive demuxers we send the seek event directly to the demuxer.
     * See https://bugzilla.gnome.org/show_bug.cgi?id=606382
     */
    CHAIN_MUTEX_LOCK (dbin->decode_chain);
    if (dbin->decode_chain->adaptive_demuxer) {
      GstDecodeElement *delem = dbin->decode_chain->elements->data;
      demuxer = gst_object_ref (delem->element);
    }
    CHAIN_MUTEX_UNLOCK (dbin->decode_chain);

    if (demuxer) {
      gboolean ret;

      GST_DEBUG_OBJECT (dbin,
          "Sending SEEK event directly to adaptive streaming demuxer %s",
          GST_OBJECT_NAME (demuxer));
      ret = gst_element_send_event (demuxer, event);
      gst_object_unref (demuxer);
      return ret;
    }
  }

  return gst_pad_event_default (pad, parent, event);
}

static gboolean
gst_decode_pad_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstDecodePad *dpad = GST_DECODE_PAD (parent);
  gboolean ret = FALSE;

  CHAIN_MUTEX_LOCK (dpad->chain);
  if (!dpad->exposed && !dpad->dbin->shutdown && !dpad->chain->deadend
      && dpad->chain->elements) {
    GstDecodeElement *delem = dpad->chain->elements->data;

    ret = FALSE;
    GST_DEBUG_OBJECT (dpad->dbin,
        "calling autoplug-query for %s (element %s): %" GST_PTR_FORMAT,
        GST_PAD_NAME (dpad), GST_ELEMENT_NAME (delem->element), query);
    g_signal_emit (G_OBJECT (dpad->dbin),
        gst_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, dpad, delem->element,
        query, &ret);

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

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

  return ret;
}

static gboolean
gst_decode_pad_is_exposable (GstDecodePad * endpad)
{
  if (endpad->blocked || endpad->exposed)
    return TRUE;

  return gst_pad_has_current_caps (GST_PAD_CAST (endpad));
}

/*gst_decode_pad_new:
 *
 * Creates a new GstDecodePad for the given pad.
 */
static GstDecodePad *
gst_decode_pad_new (GstDecodeBin * dbin, GstDecodeChain * chain)
{
  GstDecodePad *dpad;
  GstProxyPad *ppad;
  GstPadTemplate *pad_tmpl;

  GST_DEBUG_OBJECT (dbin, "making new decodepad");
  pad_tmpl = gst_static_pad_template_get (&decoder_bin_src_template);
  dpad =
      g_object_new (GST_TYPE_DECODE_PAD, "direction", GST_PAD_SRC,
      "template", pad_tmpl, NULL);
  gst_ghost_pad_construct (GST_GHOST_PAD_CAST (dpad));
  dpad->chain = chain;
  dpad->dbin = dbin;
  gst_object_unref (pad_tmpl);

  ppad = gst_proxy_pad_get_internal (GST_PROXY_PAD (dpad));
  gst_pad_set_query_function (GST_PAD_CAST (ppad), gst_decode_pad_query);
  gst_pad_set_event_function (GST_PAD_CAST (dpad), gst_decode_pad_event);
  gst_object_unref (ppad);

  return dpad;
}

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 (GstDecodeBin * dbin)
{
  GstMessage *message;

  dbin->async_pending = TRUE;

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

static void
do_async_done (GstDecodeBin * dbin)
{
  GstMessage *message;

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

    dbin->async_pending = FALSE;
  }
}

/*****
 * convenience functions
 *****/

/* find_sink_pad
 *
 * Returns the first sink pad of the given element, or NULL if it doesn't have
 * any.
 */

static GstPad *
find_sink_pad (GstElement * element)
{
  GstIterator *it;
  GstPad *pad = NULL;
  GValue item = { 0, };

  it = gst_element_iterate_sink_pads (element);

  if ((gst_iterator_next (it, &item)) == GST_ITERATOR_OK)
    pad = g_value_dup_object (&item);
  g_value_unset (&item);
  gst_iterator_free (it);

  return pad;
}

/* call with dyn_lock held */
static void
unblock_pads (GstDecodeBin * dbin)
{
  GList *tmp;

  GST_LOG_OBJECT (dbin, "unblocking pads");

  for (tmp = dbin->blocked_pads; tmp; tmp = tmp->next) {
    GstDecodePad *dpad = (GstDecodePad *) tmp->data;
    GstPad *opad;

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

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

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

static void
gst_decode_chain_stop (GstDecodeBin * dbin, GstDecodeChain * chain,
    GQueue * elements)
{
  GQueue *internal_elements, internal_elements_ = G_QUEUE_INIT;
  GList *l;

  CHAIN_MUTEX_LOCK (chain);
  if (elements) {
    internal_elements = elements;
  } else {
    internal_elements = &internal_elements_;
  }

  for (l = chain->next_groups; l; l = l->next) {
    GstDecodeGroup *group = l->data;
    GList *m;

    for (m = group->children; m; m = m->next) {
      GstDecodeChain *chain2 = m->data;
      gst_decode_chain_stop (dbin, chain2, internal_elements);
    }
    if (group->multiqueue)
      g_queue_push_head (internal_elements, gst_object_ref (group->multiqueue));
  }

  if (chain->active_group) {
    for (l = chain->active_group->children; l; l = l->next) {
      GstDecodeChain *chain2 = l->data;
      gst_decode_chain_stop (dbin, chain2, internal_elements);
    }
    if (chain->active_group->multiqueue)
      g_queue_push_head (internal_elements,
          gst_object_ref (chain->active_group->multiqueue));
  }

  for (l = chain->old_groups; l; l = l->next) {
    GstDecodeGroup *group = l->data;
    GList *m;

    for (m = group->children; m; m = m->next) {
      GstDecodeChain *chain2 = m->data;
      gst_decode_chain_stop (dbin, chain2, internal_elements);
    }
    if (group->multiqueue)
      g_queue_push_head (internal_elements, gst_object_ref (group->multiqueue));
  }

  for (l = chain->elements; l; l = l->next) {
    GstDecodeElement *delem = l->data;

    if (delem->capsfilter)
      g_queue_push_head (internal_elements, gst_object_ref (delem->capsfilter));
    g_queue_push_head (internal_elements, gst_object_ref (delem->element));
  }

  CHAIN_MUTEX_UNLOCK (chain);

  if (!elements) {
    GstElement *element;

    EXPOSE_UNLOCK (dbin);
    /* Shut down from bottom to top */
    while ((element = g_queue_pop_tail (internal_elements))) {
      /* The bin must never ever change the state of this element anymore */
      gst_element_set_locked_state (element, TRUE);
      gst_element_set_state (element, GST_STATE_NULL);
      gst_object_unref (element);
    }
    g_queue_clear (internal_elements);
    EXPOSE_LOCK (dbin);
  }
}

static GstStateChangeReturn
gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
  GstDecodeBin *dbin = GST_DECODE_BIN (element);
  GstDecodeChain *chain_to_free = NULL;

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


      /* connect a signal to find out when the typefind element found
       * a type */
      dbin->have_type_id =
          g_signal_connect (dbin->typefind, "have-type",
          G_CALLBACK (type_found), dbin);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      if (dbin->have_type_id)
        g_signal_handler_disconnect (dbin->typefind, dbin->have_type_id);
      dbin->have_type_id = 0;
      DYN_LOCK (dbin);
      GST_LOG_OBJECT (dbin, "setting shutdown flag");
      dbin->shutdown = TRUE;
      unblock_pads (dbin);
      DYN_UNLOCK (dbin);
    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 (dbin);
      ret = bret;
    }
  }
  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      do_async_done (dbin);
      EXPOSE_LOCK (dbin);
      if (dbin->decode_chain) {
        gst_decode_chain_stop (dbin, dbin->decode_chain, NULL);
        chain_to_free = dbin->decode_chain;
        gst_decode_chain_free_internal (dbin->decode_chain, TRUE);
        dbin->decode_chain = NULL;
      }
      EXPOSE_UNLOCK (dbin);
      if (chain_to_free)
        gst_decode_chain_free (chain_to_free);
      g_list_free_full (dbin->buffering_status,
          (GDestroyNotify) gst_message_unref);
      dbin->buffering_status = NULL;
      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 (dbin, 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 (dbin);
    return GST_STATE_CHANGE_FAILURE;
  }
}

static void
gst_decode_bin_handle_message (GstBin * bin, GstMessage * msg)
{
  GstDecodeBin *dbin = GST_DECODE_BIN (bin);
  gboolean drop = FALSE;

  if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
    GST_OBJECT_LOCK (dbin);
    drop = (g_list_find (dbin->filtered, GST_MESSAGE_SRC (msg)) != NULL);
    if (drop)
      dbin->filtered_errors =
          g_list_prepend (dbin->filtered_errors, gst_message_ref (msg));
    GST_OBJECT_UNLOCK (dbin);
  } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_BUFFERING) {
    gint perc, msg_perc;
    gint smaller_perc = 100;
    GstMessage *smaller = NULL;
    GList *found = NULL;
    GList *iter;

    /* buffering messages must be aggregated as there might be multiple
     * multiqueue in the pipeline and their independent buffering messages
     * will confuse the application
     *
     * decodebin keeps a list of messages received from elements that are
     * buffering.
     * Rules are:
     * 1) Always post the smaller buffering %
     * 2) If an element posts a 100% buffering message, remove it from the list
     * 3) When there are no more messages on the list, post 100% message
     * 4) When an element posts a new buffering message, update the one
     *    on the list to this new value
     */

    BUFFERING_LOCK (dbin);
    gst_message_parse_buffering (msg, &msg_perc);

    GST_DEBUG_OBJECT (dbin, "Got buffering msg %" GST_PTR_FORMAT, msg);

    g_mutex_lock (&dbin->buffering_post_lock);

    /*
     * Single loop for 2 things:
     * 1) Look for a message with the same source
     *   1.1) If the received message is 100%, remove it from the list
     * 2) Find the minimum buffering from the list
     */
    for (iter = dbin->buffering_status; iter;) {
      GstMessage *bufstats = iter->data;
      if (GST_MESSAGE_SRC (bufstats) == GST_MESSAGE_SRC (msg)) {
        found = iter;
        if (msg_perc < 100) {
          GST_DEBUG_OBJECT (dbin, "Replacing old buffering msg %"
              GST_PTR_FORMAT, iter->data);
          gst_message_unref (iter->data);
          bufstats = iter->data = gst_message_ref (msg);
        } else {
          GList *current = iter;

          /* remove the element here and avoid confusing the loop */
          iter = g_list_next (iter);

          GST_DEBUG_OBJECT (dbin, "Deleting old buffering msg %"
              GST_PTR_FORMAT, current->data);

          gst_message_unref (current->data);
          dbin->buffering_status =
              g_list_delete_link (dbin->buffering_status, current);

          continue;
        }
      }

      gst_message_parse_buffering (bufstats, &perc);
      if (perc < smaller_perc) {
        smaller_perc = perc;
        smaller = bufstats;
      }
      iter = g_list_next (iter);
    }

    if (found == NULL && msg_perc < 100) {
      if (msg_perc < smaller_perc) {
        smaller_perc = msg_perc;
        smaller = msg;
      }
      GST_DEBUG_OBJECT (dbin, "Storing buffering msg %" GST_PTR_FORMAT, msg);
      dbin->buffering_status =
          g_list_prepend (dbin->buffering_status, gst_message_ref (msg));
    }

    /* now compute the buffering message that should be posted */
    if (smaller_perc == 100) {
      g_assert (dbin->buffering_status == NULL);
      /* we are posting the original received msg */
    } else {
      gst_message_replace (&msg, smaller);
    }
    BUFFERING_UNLOCK (dbin);

    GST_DEBUG_OBJECT (dbin, "Forwarding buffering msg %" GST_PTR_FORMAT, msg);
    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);

    g_mutex_unlock (&dbin->buffering_post_lock);
    return;
  }

  if (drop) {
    gst_message_unref (msg);
  } else {
    GST_DEBUG_OBJECT (dbin, "Forwarding msg %" GST_PTR_FORMAT, msg);
    GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
  }
}

static gboolean
gst_decode_bin_remove_element (GstBin * bin, GstElement * element)
{
  GstDecodeBin *dbin = GST_DECODE_BIN (bin);
  gboolean removed = FALSE, post = FALSE;
  GList *iter;

  BUFFERING_LOCK (bin);
  for (iter = dbin->buffering_status; iter; iter = iter->next) {
    GstMessage *bufstats = iter->data;

    if (GST_MESSAGE_SRC (bufstats) == GST_OBJECT_CAST (element) ||
        gst_object_has_as_ancestor (GST_MESSAGE_SRC (bufstats),
            GST_OBJECT_CAST (element))) {
      gst_message_unref (bufstats);
      dbin->buffering_status =
          g_list_delete_link (dbin->buffering_status, iter);
      removed = TRUE;
      break;
    }
  }

  if (removed && dbin->buffering_status == NULL)
    post = TRUE;
  BUFFERING_UNLOCK (bin);

  if (post) {
    gst_element_post_message (GST_ELEMENT_CAST (bin),
        gst_message_new_buffering (GST_OBJECT_CAST (dbin), 100));
  }

  return GST_BIN_CLASS (parent_class)->remove_element (bin, element);
}

gboolean
gst_decode_bin_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_decode_bin_debug, "decodebin", 0, "decoder bin");

  /* Register some quarks here for the stream topology message */
  topology_structure_name = g_quark_from_static_string ("stream-topology");
  topology_caps = g_quark_from_static_string ("caps");
  topology_next = g_quark_from_static_string ("next");
  topology_pad = g_quark_from_static_string ("pad");
  topology_element_srcpad = g_quark_from_static_string ("element-srcpad");

  return gst_element_register (plugin, "decodebin", GST_RANK_NONE,
      GST_TYPE_DECODE_BIN);
}
