/* 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
 * @title: 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;

  GMutex cleanup_lock;          /* Mutex used to protect the cleanup thread */
  GThread *cleanup_thread;      /* thread used to free chains asynchronously.
                                 * We store it to make sure we end up joining it
                                 * before stopping the element.
                                 * Protected by the object lock */
  GList *cleanup_groups;        /* List of groups to free  */
};

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);
static void unblock_pads (GstDecodeBin * dbin);

#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 */
  gulong pad_probe_id;          /* id for the demuxer_source_pad_probe probe */

  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.
   *
   * >   Invocation of signal handlers stops after the first signal handler
   * >   returns %FALSE. Signal handlers are invoked in the order they were
   * >   connected in.
   *
   * Returns: %TRUE if you wish 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 signal is emitted 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.
   *
   * >   Only the signal handler that is connected first will ever by invoked.
   * >   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
   * >   signal, they will never be invoked!
   *
   * Returns: a #GValueArray* with a list of factories to try. The factories are
   * by default tried in the returned order or based on the index returned by
   * "autoplug-select".
   */
  gst_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 emitted. The purpose of the signal is for
   * the application to perform additional sorting or filtering on the element
   * factory array.
   *
   * The callee should copy and modify @factories or return %NULL if the
   * order should not change.
   *
   * >   Invocation of signal handlers stops after one signal handler has
   * >   returned something else than %NULL. Signal handlers are invoked in
   * >   the order they were connected in.
   * >   Don't connect signal handlers with the #G_CONNECT_AFTER flag to this
   * >   signal, they will never be invoked!
   *
   * Returns: A new sorted array of #GstElementFactory objects.
   */
  gst_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.
   *
   * >   The signal handler will not be invoked if any of the previously
   * >   registered signal handlers (if any) return a value other than
   * >   GST_AUTOPLUG_SELECT_TRY. Which also means that if you return
   * >   GST_AUTOPLUG_SELECT_TRY from one signal handler, handlers that get
   * >   registered next (again, if any) can override that decision.
   *
   * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
   * operation. the default handler will always return
   * #GST_AUTOPLUG_SELECT_TRY.
   */
  gst_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);

  g_mutex_init (&decode_bin->cleanup_lock);
  decode_bin->cleanup_thread = NULL;

  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;

  unblock_pads (decode_bin);

  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_mutex_clear (&decode_bin->cleanup_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 */
    chain->pad_probe_id =
        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;
  GstDecodeBin *dbin = chain->dbin;

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

  /* If we already have a thread running, wait for it to finish */
  g_mutex_lock (&dbin->cleanup_lock);
  if (dbin->cleanup_thread) {
    g_thread_join (dbin->cleanup_thread);
    dbin->cleanup_thread = NULL;
  }

  chain->old_groups = NULL;

  if (dbin->shutdown) {
    /* If we're shutting down, add the groups to be cleaned up in the
     * state change handler (which *is* another thread). Also avoids
     * playing racy games with the state change handler */
    dbin->cleanup_groups = g_list_concat (dbin->cleanup_groups, old_groups);
    g_mutex_unlock (&dbin->cleanup_lock);
    return;
  }

  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;
    g_mutex_unlock (&dbin->cleanup_lock);
    return;
  }

  dbin->cleanup_thread = thread;
  g_mutex_unlock (&dbin->cleanup_lock);

  GST_DEBUG_OBJECT (chain->dbin, "Started free-hidden-groups 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);

  if (chain->pad_probe_id) {
    gst_pad_remove_probe (chain->pad, chain->pad_probe_id);
    chain->pad_probe_id = 0;
  }

  /* 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,
    GstElement * capsfilter, 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 || (capsfilter != NULL && parent == capsfilter)) {
            caps = gst_pad_get_current_caps (pad);
            *srcpad = gst_object_ref (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)) {
    GstPad *srcpad;

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

      srcpad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (chain->endpad));
      gst_structure_id_set (u, topology_element_srcpad, GST_TYPE_PAD,
          srcpad, NULL);

      gst_object_unref (srcpad);
    }

    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, *capsfilter, *elem_next;
    GstCaps *caps;
    GstPad *srcpad;

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

    caps = _gst_element_get_linked_caps (elem_next, elem, capsfilter, &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);
    /* Failures could be due to the fact that we are currently shutting down (recheck) */
    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);
    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);

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

  /* 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");
  }
  DYN_UNLOCK (dbin);

  /* 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)
{
  GST_LOG_OBJECT (dbin, "unblocking pads");

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

    dbin->blocked_pads = g_list_delete_link (dbin->blocked_pads, tmp);
    opad = gst_ghost_pad_get_target (GST_GHOST_PAD_CAST (dpad));
    if (opad) {

      GST_DEBUG_OBJECT (dpad, "unblocking");
      if (dpad->block_id != 0) {
        gst_pad_remove_probe (opad, dpad->block_id);
        dpad->block_id = 0;
      }
      gst_object_unref (opad);
    }

    dpad->blocked = FALSE;

    /* We release the dyn lock since we want to allow the streaming threads
     * to properly stop and not be blocked in our various probes */
    DYN_UNLOCK (dbin);
    /* make flushing, prevent NOT_LINKED */
    gst_pad_set_active (GST_PAD_CAST (dpad), FALSE);
    DYN_LOCK (dbin);

    GST_DEBUG_OBJECT (dpad, "unblocked");
    gst_object_unref (dpad);
  }
}

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:
    case GST_STATE_CHANGE_READY_TO_NULL:
      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);

      /* Make sure we don't have cleanup races where
       * we might be trying to deactivate pads (in the cleanup thread)
       * at the same time as the default element deactivation
       * (in PAUSED=>READY)  */
      g_mutex_lock (&dbin->cleanup_lock);
      if (dbin->cleanup_thread) {
        g_thread_join (dbin->cleanup_thread);
        dbin->cleanup_thread = NULL;
      }
      g_mutex_unlock (&dbin->cleanup_lock);
    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;
      /* Let's do a final check of leftover groups to free */
      g_mutex_lock (&dbin->cleanup_lock);
      if (dbin->cleanup_groups) {
        gst_decode_chain_free_hidden_groups (dbin->cleanup_groups);
        dbin->cleanup_groups = NULL;
      }
      g_mutex_unlock (&dbin->cleanup_lock);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      /* Let's do a final check of leftover groups to free */
      g_mutex_lock (&dbin->cleanup_lock);
      if (dbin->cleanup_groups) {
        gst_decode_chain_free_hidden_groups (dbin->cleanup_groups);
        dbin->cleanup_groups = NULL;
      }
      g_mutex_unlock (&dbin->cleanup_lock);
      break;
    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) {
    /* Don't pass errors when shutting down. Sometimes,
     * elements can generate spurious errors because we set the
     * output pads to flushing, and they can't detect that if they
     * send an event at exactly the wrong moment */
    DYN_LOCK (dbin);
    drop = dbin->shutdown;
    DYN_UNLOCK (dbin);

    if (!drop) {
      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);
  g_mutex_lock (&dbin->buffering_post_lock);
  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));
  }
  g_mutex_unlock (&dbin->buffering_post_lock);

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