/* GStreamer
 * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-uridecodebin
 *
 * Decodes data from a URI into raw media. It selects a source element that can
 * handle the given #GstURIDecodeBin:uri scheme and connects it to a decodebin.
 */

/* 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 <string.h>

#include <gst/gst.h>
#include <gst/gst-i18n-plugin.h>
#include <gst/pbutils/missing-plugins.h>

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

/* From gstdecodebin2.c */
gint _decode_bin_compare_factories_func (gconstpointer p1, gconstpointer p2);

#define GST_TYPE_URI_DECODE_BIN \
  (gst_uri_decode_bin_get_type())
#define GST_URI_DECODE_BIN(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_URI_DECODE_BIN,GstURIDecodeBin))
#define GST_URI_DECODE_BIN_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_URI_DECODE_BIN,GstURIDecodeBinClass))
#define GST_IS_URI_DECODE_BIN(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_URI_DECODE_BIN))
#define GST_IS_URI_DECODE_BIN_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_URI_DECODE_BIN))
#define GST_URI_DECODE_BIN_CAST(obj) ((GstURIDecodeBin *) (obj))

typedef struct _GstURIDecodeBin GstURIDecodeBin;
typedef struct _GstURIDecodeBinClass GstURIDecodeBinClass;

#define GST_URI_DECODE_BIN_LOCK(dec) (g_mutex_lock(&((GstURIDecodeBin*)(dec))->lock))
#define GST_URI_DECODE_BIN_UNLOCK(dec) (g_mutex_unlock(&((GstURIDecodeBin*)(dec))->lock))

typedef struct _GstURIDecodeBinStream
{
  gulong probe_id;
  guint bitrate;
} GstURIDecodeBinStream;

/**
 * GstURIDecodeBin
 *
 * uridecodebin element struct
 */
struct _GstURIDecodeBin
{
  GstBin parent_instance;

  GMutex lock;                  /* lock for constructing */

  GMutex factories_lock;
  guint32 factories_cookie;
  GList *factories;             /* factories we can use for selecting elements */

  gchar *uri;
  guint64 connection_speed;
  GstCaps *caps;
  gchar *encoding;

  gboolean is_stream;
  gboolean is_adaptive;
  gboolean need_queue;
  guint64 buffer_duration;      /* When buffering, buffer duration (ns) */
  guint buffer_size;            /* When buffering, buffer size (bytes) */
  gboolean download;
  gboolean use_buffering;

  GstElement *source;
  GstElement *queue;
  GstElement *typefind;
  guint have_type_id;           /* have-type signal id from typefind */
  GSList *decodebins;
  GSList *pending_decodebins;
  GHashTable *streams;
  guint numpads;

  /* for dynamic sources */
  guint src_np_sig_id;          /* new-pad signal id */
  guint src_nmp_sig_id;         /* no-more-pads signal id */
  gint pending;
  GList *missing_plugin_errors;

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

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

  guint64 ring_buffer_max_size; /* 0 means disabled */
};

struct _GstURIDecodeBinClass
{
  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);

  /* emitted when all data is decoded */
  void (*drained) (GstElement * element);
};

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

static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);

GST_DEBUG_CATEGORY_STATIC (gst_uri_decode_bin_debug);
#define GST_CAT_DEFAULT gst_uri_decode_bin_debug

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

/* properties */
#define DEFAULT_PROP_URI            NULL
#define DEFAULT_PROP_SOURCE         NULL
#define DEFAULT_CONNECTION_SPEED    0
#define DEFAULT_CAPS                (gst_static_caps_get (&default_raw_caps))
#define DEFAULT_SUBTITLE_ENCODING   NULL
#define DEFAULT_BUFFER_DURATION     -1
#define DEFAULT_BUFFER_SIZE         -1
#define DEFAULT_DOWNLOAD            FALSE
#define DEFAULT_USE_BUFFERING       FALSE
#define DEFAULT_EXPOSE_ALL_STREAMS  TRUE
#define DEFAULT_RING_BUFFER_MAX_SIZE 0

enum
{
  PROP_0,
  PROP_URI,
  PROP_SOURCE,
  PROP_CONNECTION_SPEED,
  PROP_CAPS,
  PROP_SUBTITLE_ENCODING,
  PROP_BUFFER_SIZE,
  PROP_BUFFER_DURATION,
  PROP_DOWNLOAD,
  PROP_USE_BUFFERING,
  PROP_EXPOSE_ALL_STREAMS,
  PROP_RING_BUFFER_MAX_SIZE
};

static guint gst_uri_decode_bin_signals[LAST_SIGNAL] = { 0 };

GType gst_uri_decode_bin_get_type (void);
#define gst_uri_decode_bin_parent_class parent_class
G_DEFINE_TYPE (GstURIDecodeBin, gst_uri_decode_bin, GST_TYPE_BIN);

static void remove_decoders (GstURIDecodeBin * bin, gboolean force);
static void gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_uri_decode_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_uri_decode_bin_finalize (GObject * obj);

static void handle_message (GstBin * bin, GstMessage * msg);

static gboolean gst_uri_decode_bin_query (GstElement * element,
    GstQuery * query);
static GstStateChangeReturn gst_uri_decode_bin_change_state (GstElement *
    element, GstStateChange transition);

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

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 gboolean
gst_uri_decode_bin_autoplug_continue (GstElement * element, GstPad * pad,
    GstCaps * caps)
{
  /* by default we always continue */
  return TRUE;
}

/* Must be called with factories lock! */
static void
gst_uri_decode_bin_update_factories_list (GstURIDecodeBin * dec)
{
  guint32 cookie;

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

static GValueArray *
gst_uri_decode_bin_autoplug_factories (GstElement * element, GstPad * pad,
    GstCaps * caps)
{
  GList *list, *tmp;
  GValueArray *result;
  GstURIDecodeBin *dec = GST_URI_DECODE_BIN_CAST (element);

  GST_DEBUG_OBJECT (element, "finding factories");

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

static GstAutoplugSelectResult
gst_uri_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_uri_decode_bin_autoplug_query (GstElement * element, GstPad * pad,
    GstQuery * query)
{
  /* No query handled here */
  return FALSE;
}

static void
gst_uri_decode_bin_class_init (GstURIDecodeBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBinClass *gstbin_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstbin_class = GST_BIN_CLASS (klass);

  gobject_class->set_property = gst_uri_decode_bin_set_property;
  gobject_class->get_property = gst_uri_decode_bin_get_property;
  gobject_class->finalize = gst_uri_decode_bin_finalize;

  g_object_class_install_property (gobject_class, PROP_URI,
      g_param_spec_string ("uri", "URI", "URI to decode",
          DEFAULT_PROP_URI, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SOURCE,
      g_param_spec_object ("source", "Source", "Source object used",
          GST_TYPE_ELEMENT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, 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));

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

  g_object_class_install_property (gobject_class, 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_class, PROP_BUFFER_SIZE,
      g_param_spec_int ("buffer-size", "Buffer size (bytes)",
          "Buffer size when buffering streams (-1 default value)",
          -1, G_MAXINT, DEFAULT_BUFFER_SIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_BUFFER_DURATION,
      g_param_spec_int64 ("buffer-duration", "Buffer duration (ns)",
          "Buffer duration when buffering streams (-1 default value)",
          -1, G_MAXINT64, DEFAULT_BUFFER_DURATION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstURIDecodeBin::download:
   *
   * For certain media type, enable download buffering.
   */
  g_object_class_install_property (gobject_class, PROP_DOWNLOAD,
      g_param_spec_boolean ("download", "Download",
          "Attempt download buffering when buffering network streams",
          DEFAULT_DOWNLOAD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstURIDecodeBin::use-buffering:
   *
   * Emit BUFFERING messages based on low-/high-percent thresholds of the
   * demuxed or parsed data.
   * When download buffering is activated and used for the current media
   * type, this property does nothing. Otherwise perform buffering on the
   * demuxed or parsed media.
   *
   * Since: 0.10.26
   */
  g_object_class_install_property (gobject_class, PROP_USE_BUFFERING,
      g_param_spec_boolean ("use-buffering", "Use Buffering",
          "Perform buffering on demuxed/parsed media",
          DEFAULT_USE_BUFFERING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstURIDecodeBin::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. 
   *
   * Since: 0.10.30
   */
  g_object_class_install_property (gobject_class, 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));

  /**
   * GstURIDecodeBin::ring-buffer-max-size
   *
   * The maximum size of the ring buffer in kilobytes. If set to 0, the ring
   * buffer is disabled. Default is 0.
   *
   * Since: 0.10.31
   */
  g_object_class_install_property (gobject_class, PROP_RING_BUFFER_MAX_SIZE,
      g_param_spec_uint64 ("ring-buffer-max-size",
          "Max. ring buffer size (bytes)",
          "Max. amount of data in the ring buffer (bytes, 0 = ring buffer disabled)",
          0, G_MAXUINT, DEFAULT_RING_BUFFER_MAX_SIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstURIDecodeBin::unknown-type:
   * @bin: The uridecodebin.
   * @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 uridecodebin.
   */
  gst_uri_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
      g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass, unknown_type),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2,
      GST_TYPE_PAD, GST_TYPE_CAPS);

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

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

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

  /**
   * GstURIDecodeBin::autoplug-select:
   * @bin: The uridecodebin.
   * @pad: The #GstPad.
   * @caps: The #GstCaps.
   * @factory: A #GstElementFactory to use.
   *
   * This signal is emitted once uridecodebin has found all the possible
   * #GstElementFactory that can be used to handle the given @caps. For each of
   * those factories, this signal is emitted.
   *
   * The signal handler should return a #GST_TYPE_AUTOPLUG_SELECT_RESULT enum
   * value indicating what decodebin should do next.
   *
   * A value of #GST_AUTOPLUG_SELECT_TRY will try to autoplug an element from
   * @factory.
   *
   * A value of #GST_AUTOPLUG_SELECT_EXPOSE will expose @pad without plugging
   * any element to it.
   *
   * A value of #GST_AUTOPLUG_SELECT_SKIP will skip @factory and move to the
   * next factory.
   *
   * <note>
   *   The signal handler will not be invoked if any of the previously
   *   registered signal handlers (if any) return a value other than
   *   GST_AUTOPLUG_SELECT_TRY. Which also means that if you return
   *   GST_AUTOPLUG_SELECT_TRY from one signal handler, handlers that get
   *   registered next (again, if any) can override that decision.
   * </note>
   *
   * Returns: a #GST_TYPE_AUTOPLUG_SELECT_RESULT that indicates the required
   * operation. The default handler will always return
   * #GST_AUTOPLUG_SELECT_TRY.
   */
  gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT] =
      g_signal_new ("autoplug-select", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass,
          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.
   * @child: The child element doing the query
   * @pad: The #GstPad.
   * @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_uri_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY] =
      g_signal_new ("autoplug-query", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstURIDecodeBinClass, 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);

  /**
   * GstURIDecodeBin::drained:
   *
   * This signal is emitted when the data for the current uri is played.
   */
  gst_uri_decode_bin_signals[SIGNAL_DRAINED] =
      g_signal_new ("drained", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstURIDecodeBinClass, drained), NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 0, G_TYPE_NONE);

  /**
   * GstURIDecodeBin::source-setup:
   * @bin: the uridecodebin.
   * @source: source element
   *
   * This signal is emitted after the source element has been created, so
   * it can be configured by setting additional properties (e.g. set a
   * proxy server for an http source, or set the device and read speed for
   * an audio cd source). This is functionally equivalent to connecting to
   * the notify::source signal, but more convenient.
   *
   * Since: 0.10.33
   */
  gst_uri_decode_bin_signals[SIGNAL_SOURCE_SETUP] =
      g_signal_new ("source-setup", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL,
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&srctemplate));
  gst_element_class_set_static_metadata (gstelement_class,
      "URI Decoder", "Generic/Bin/Decoder",
      "Autoplug and decode an URI to raw media",
      "Wim Taymans <wim.taymans@gmail.com>");

  gstelement_class->query = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_query);
  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_uri_decode_bin_change_state);

  gstbin_class->handle_message = GST_DEBUG_FUNCPTR (handle_message);

  klass->autoplug_continue =
      GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_continue);
  klass->autoplug_factories =
      GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_factories);
  klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_sort);
  klass->autoplug_select =
      GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_select);
  klass->autoplug_query = GST_DEBUG_FUNCPTR (gst_uri_decode_bin_autoplug_query);
}

static void
gst_uri_decode_bin_init (GstURIDecodeBin * dec)
{
  /* first filter out the interesting element factories */
  g_mutex_init (&dec->factories_lock);

  g_mutex_init (&dec->lock);

  dec->uri = g_strdup (DEFAULT_PROP_URI);
  dec->connection_speed = DEFAULT_CONNECTION_SPEED;
  dec->caps = DEFAULT_CAPS;
  dec->encoding = g_strdup (DEFAULT_SUBTITLE_ENCODING);

  dec->buffer_duration = DEFAULT_BUFFER_DURATION;
  dec->buffer_size = DEFAULT_BUFFER_SIZE;
  dec->download = DEFAULT_DOWNLOAD;
  dec->use_buffering = DEFAULT_USE_BUFFERING;
  dec->expose_allstreams = DEFAULT_EXPOSE_ALL_STREAMS;
  dec->ring_buffer_max_size = DEFAULT_RING_BUFFER_MAX_SIZE;

  GST_OBJECT_FLAG_SET (dec, GST_ELEMENT_FLAG_SOURCE);
}

static void
gst_uri_decode_bin_finalize (GObject * obj)
{
  GstURIDecodeBin *dec = GST_URI_DECODE_BIN (obj);

  remove_decoders (dec, TRUE);
  g_mutex_clear (&dec->lock);
  g_mutex_clear (&dec->factories_lock);
  g_free (dec->uri);
  g_free (dec->encoding);
  if (dec->factories)
    gst_plugin_feature_list_free (dec->factories);
  if (dec->caps)
    gst_caps_unref (dec->caps);

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

static void
gst_uri_decode_bin_set_encoding (GstURIDecodeBin * dec, const gchar * encoding)
{
  GSList *walk;

  GST_URI_DECODE_BIN_LOCK (dec);

  /* set property first */
  GST_OBJECT_LOCK (dec);
  g_free (dec->encoding);
  dec->encoding = g_strdup (encoding);
  GST_OBJECT_UNLOCK (dec);

  /* set the property on all decodebins now */
  for (walk = dec->decodebins; walk; walk = g_slist_next (walk)) {
    GObject *decodebin = G_OBJECT (walk->data);

    g_object_set (decodebin, "subtitle-encoding", encoding, NULL);
  }
  GST_URI_DECODE_BIN_UNLOCK (dec);
}

static void
gst_uri_decode_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstURIDecodeBin *dec = GST_URI_DECODE_BIN (object);

  switch (prop_id) {
    case PROP_URI:
      GST_OBJECT_LOCK (dec);
      g_free (dec->uri);
      dec->uri = g_value_dup_string (value);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_CONNECTION_SPEED:
      GST_OBJECT_LOCK (dec);
      dec->connection_speed = g_value_get_uint64 (value) * 1000;
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_CAPS:
      GST_OBJECT_LOCK (dec);
      if (dec->caps)
        gst_caps_unref (dec->caps);
      dec->caps = g_value_dup_boxed (value);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_SUBTITLE_ENCODING:
      gst_uri_decode_bin_set_encoding (dec, g_value_get_string (value));
      break;
    case PROP_BUFFER_SIZE:
      dec->buffer_size = g_value_get_int (value);
      break;
    case PROP_BUFFER_DURATION:
      dec->buffer_duration = g_value_get_int64 (value);
      break;
    case PROP_DOWNLOAD:
      dec->download = g_value_get_boolean (value);
      break;
    case PROP_USE_BUFFERING:
      dec->use_buffering = g_value_get_boolean (value);
      break;
    case PROP_EXPOSE_ALL_STREAMS:
      dec->expose_allstreams = g_value_get_boolean (value);
      break;
    case PROP_RING_BUFFER_MAX_SIZE:
      dec->ring_buffer_max_size = g_value_get_uint64 (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_uri_decode_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstURIDecodeBin *dec = GST_URI_DECODE_BIN (object);

  switch (prop_id) {
    case PROP_URI:
      GST_OBJECT_LOCK (dec);
      g_value_set_string (value, dec->uri);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_SOURCE:
      GST_OBJECT_LOCK (dec);
      g_value_set_object (value, dec->source);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_CONNECTION_SPEED:
      GST_OBJECT_LOCK (dec);
      g_value_set_uint64 (value, dec->connection_speed / 1000);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_CAPS:
      GST_OBJECT_LOCK (dec);
      g_value_set_boxed (value, dec->caps);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_SUBTITLE_ENCODING:
      GST_OBJECT_LOCK (dec);
      g_value_set_string (value, dec->encoding);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_BUFFER_SIZE:
      GST_OBJECT_LOCK (dec);
      g_value_set_int (value, dec->buffer_size);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_BUFFER_DURATION:
      GST_OBJECT_LOCK (dec);
      g_value_set_int64 (value, dec->buffer_duration);
      GST_OBJECT_UNLOCK (dec);
      break;
    case PROP_DOWNLOAD:
      g_value_set_boolean (value, dec->download);
      break;
    case PROP_USE_BUFFERING:
      g_value_set_boolean (value, dec->use_buffering);
      break;
    case PROP_EXPOSE_ALL_STREAMS:
      g_value_set_boolean (value, dec->expose_allstreams);
      break;
    case PROP_RING_BUFFER_MAX_SIZE:
      g_value_set_uint64 (value, dec->ring_buffer_max_size);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
do_async_start (GstURIDecodeBin * dbin)
{
  GstMessage *message;

  dbin->async_pending = TRUE;

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

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

  if (dbin->async_pending) {
    GST_DEBUG_OBJECT (dbin, "posting ASYNC_DONE");
    message =
        gst_message_new_async_done (GST_OBJECT_CAST (dbin),
        GST_CLOCK_TIME_NONE);
    GST_BIN_CLASS (parent_class)->handle_message (GST_BIN_CAST (dbin), message);

    dbin->async_pending = FALSE;
  }
}

#define DEFAULT_QUEUE_SIZE          (3 * GST_SECOND)
#define DEFAULT_QUEUE_MIN_THRESHOLD ((DEFAULT_QUEUE_SIZE * 30) / 100)
#define DEFAULT_QUEUE_THRESHOLD     ((DEFAULT_QUEUE_SIZE * 95) / 100)

static void
unknown_type_cb (GstElement * element, GstPad * pad, GstCaps * caps,
    GstURIDecodeBin * decoder)
{
  gchar *capsstr;

  capsstr = gst_caps_to_string (caps);
  GST_ELEMENT_WARNING (decoder, STREAM, CODEC_NOT_FOUND,
      (_("No decoder available for type \'%s\'."), capsstr), (NULL));
  g_free (capsstr);
}

/* add a streaminfo that indicates that the stream is handled by the
 * given element. This usually means that a stream without actual data is
 * produced but one that is sunken by an element. Examples of this are:
 * cdaudio, a hardware decoder/sink, dvd meta bins etc...
 */
static void
add_element_stream (GstElement * element, GstURIDecodeBin * decoder)
{
  g_warning ("add element stream");
}

/* when the decoder element signals that no more pads will be generated, we
 * can commit the current group.
 */
static void
no_more_pads_full (GstElement * element, gboolean subs,
    GstURIDecodeBin * decoder)
{
  gboolean final;

  /* setup phase */
  GST_DEBUG_OBJECT (element, "no more pads, %d pending", decoder->pending);

  GST_URI_DECODE_BIN_LOCK (decoder);
  final = (decoder->pending == 0);

  /* nothing pending, we can exit */
  if (final)
    goto done;

  /* the object has no pending no_more_pads */
  if (!g_object_get_data (G_OBJECT (element), "pending"))
    goto done;
  g_object_set_data (G_OBJECT (element), "pending", NULL);

  decoder->pending--;
  final = (decoder->pending == 0);

done:
  GST_URI_DECODE_BIN_UNLOCK (decoder);

  if (final) {
    /* If we got not a single stream yet, that means that all
     * decodebins had missing plugins for all of their streams!
     */
    if (!decoder->streams || g_hash_table_size (decoder->streams) == 0) {
      if (decoder->missing_plugin_errors) {
        GString *str = g_string_new ("");
        GList *l;

        for (l = decoder->missing_plugin_errors; l; l = l->next) {
          GstMessage *msg = l->data;
          gchar *debug;

          gst_message_parse_error (msg, NULL, &debug);
          g_string_append (str, debug);
          g_free (debug);
          gst_message_unref (msg);
        }
        g_list_free (decoder->missing_plugin_errors);
        decoder->missing_plugin_errors = NULL;

        GST_ELEMENT_ERROR (decoder, CORE, MISSING_PLUGIN, (NULL),
            ("no suitable plugins found:\n%s", str->str));
        g_string_free (str, TRUE);
      } else {
        GST_ELEMENT_ERROR (decoder, CORE, MISSING_PLUGIN, (NULL),
            ("no suitable plugins found"));
      }
    } else {
      gst_element_no_more_pads (GST_ELEMENT_CAST (decoder));
    }
    do_async_done (decoder);
  }

  return;
}

static void
no_more_pads (GstElement * element, GstURIDecodeBin * decoder)
{
  no_more_pads_full (element, FALSE, decoder);
}

static void
source_no_more_pads (GstElement * element, GstURIDecodeBin * bin)
{
  GST_DEBUG_OBJECT (bin, "No more pads in source element %s.",
      GST_ELEMENT_NAME (element));

  g_signal_handler_disconnect (element, bin->src_np_sig_id);
  bin->src_np_sig_id = 0;
  g_signal_handler_disconnect (element, bin->src_nmp_sig_id);
  bin->src_nmp_sig_id = 0;

  no_more_pads_full (element, FALSE, bin);
}

static void
configure_stream_buffering (GstURIDecodeBin * decoder)
{
  GstElement *queue = NULL;
  GHashTableIter iter;
  gpointer key, value;
  gint bitrate = 0;

  /* automatic configuration enabled ? */
  if (decoder->buffer_size != -1)
    return;

  GST_URI_DECODE_BIN_LOCK (decoder);
  if (decoder->queue)
    queue = gst_object_ref (decoder->queue);

  g_hash_table_iter_init (&iter, decoder->streams);
  while (g_hash_table_iter_next (&iter, &key, &value)) {
    GstURIDecodeBinStream *stream = value;

    if (stream->bitrate && bitrate >= 0)
      bitrate += stream->bitrate;
    else
      bitrate = -1;
  }
  GST_URI_DECODE_BIN_UNLOCK (decoder);

  GST_DEBUG_OBJECT (decoder, "overall bitrate %d", bitrate);
  if (!queue)
    return;

  if (bitrate > 0) {
    guint64 time;
    guint bytes;

    /* all streams have a bitrate;
     * configure queue size based on queue duration using combined bitrate */
    g_object_get (queue, "max-size-time", &time, NULL);
    GST_DEBUG_OBJECT (decoder, "queue buffering time %" GST_TIME_FORMAT,
        GST_TIME_ARGS (time));
    if (time > 0) {
      bytes = gst_util_uint64_scale (time, bitrate, 8 * GST_SECOND);
      GST_DEBUG_OBJECT (decoder, "corresponds to buffer size %d", bytes);
      g_object_set (queue, "max-size-bytes", bytes, NULL);
    }
  }

  gst_object_unref (queue);
}

static GstPadProbeReturn
decoded_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstURIDecodeBin *decoder = user_data;

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

  /* look for a bitrate tag */
  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:
    {
      GstTagList *list;
      guint bitrate = 0;
      GstURIDecodeBinStream *stream;

      gst_event_parse_tag (event, &list);
      if (!gst_tag_list_get_uint_index (list, GST_TAG_NOMINAL_BITRATE, 0,
              &bitrate)) {
        gst_tag_list_get_uint_index (list, GST_TAG_BITRATE, 0, &bitrate);
      }
      GST_DEBUG_OBJECT (pad, "found bitrate %u", bitrate);
      if (bitrate) {
        GST_URI_DECODE_BIN_LOCK (decoder);
        stream = g_hash_table_lookup (decoder->streams, pad);
        GST_URI_DECODE_BIN_UNLOCK (decoder);
        if (stream) {
          stream->bitrate = bitrate;
          /* no longer need this probe now */
          gst_pad_remove_probe (pad, stream->probe_id);
          /* configure buffer if possible */
          configure_stream_buffering (decoder);
        }
      }
      break;
    }
    default:
      break;
  }

  /* never drop */
  return GST_PAD_PROBE_OK;
}


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

/* Called by the signal handlers when a decodebin has found a new raw pad */
static void
new_decoded_pad_added_cb (GstElement * element, GstPad * pad,
    GstURIDecodeBin * decoder)
{
  GstPad *newpad;
  GstPadTemplate *pad_tmpl;
  gchar *padname;
  GstURIDecodeBinStream *stream;

  GST_DEBUG_OBJECT (element, "new decoded pad, name: <%s>", GST_PAD_NAME (pad));

  GST_URI_DECODE_BIN_LOCK (decoder);
  padname = g_strdup_printf ("src_%u", decoder->numpads);
  decoder->numpads++;
  GST_URI_DECODE_BIN_UNLOCK (decoder);

  pad_tmpl = gst_static_pad_template_get (&srctemplate);
  newpad = gst_ghost_pad_new_from_template (padname, pad, pad_tmpl);
  gst_object_unref (pad_tmpl);
  g_free (padname);

  /* store ref to the ghostpad so we can remove it */
  g_object_set_data (G_OBJECT (pad), "uridecodebin.ghostpad", newpad);

  /* add event probe to monitor tags */
  stream = g_slice_alloc0 (sizeof (GstURIDecodeBinStream));
  stream->probe_id =
      gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      decoded_pad_event_probe, decoder, NULL);
  GST_URI_DECODE_BIN_LOCK (decoder);
  g_hash_table_insert (decoder->streams, pad, stream);
  GST_URI_DECODE_BIN_UNLOCK (decoder);

  gst_pad_set_active (newpad, TRUE);
  gst_pad_sticky_events_foreach (pad, copy_sticky_events, newpad);
  gst_element_add_pad (GST_ELEMENT_CAST (decoder), newpad);
}

static GstPadProbeReturn
source_pad_event_probe (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);
  GstURIDecodeBin *decoder = user_data;

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

  if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
    GST_DEBUG_OBJECT (pad, "we received EOS");

    g_signal_emit (decoder,
        gst_uri_decode_bin_signals[SIGNAL_DRAINED], 0, NULL);
  }
  /* never drop events */
  return GST_PAD_PROBE_OK;
}

/* called when we found a raw pad on the source element. We need to set up a
 * padprobe to detect EOS before exposing the pad. */
static void
expose_decoded_pad (GstElement * element, GstPad * pad,
    GstURIDecodeBin * decoder)
{
  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      source_pad_event_probe, decoder, NULL);

  new_decoded_pad_added_cb (element, pad, decoder);
}

static void
pad_removed_cb (GstElement * element, GstPad * pad, GstURIDecodeBin * decoder)
{
  GstPad *ghost;

  GST_DEBUG_OBJECT (element, "pad removed name: <%s:%s>",
      GST_DEBUG_PAD_NAME (pad));

  /* we only care about srcpads */
  if (!GST_PAD_IS_SRC (pad))
    return;

  if (!(ghost = g_object_get_data (G_OBJECT (pad), "uridecodebin.ghostpad")))
    goto no_ghost;

  /* unghost the pad */
  gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ghost), NULL);

  /* deactivate and remove */
  gst_pad_set_active (pad, FALSE);
  gst_element_remove_pad (GST_ELEMENT_CAST (decoder), ghost);

  return;

  /* ERRORS */
no_ghost:
  {
    GST_WARNING_OBJECT (element, "no ghost pad found");
    return;
  }
}

/* helper function to lookup stuff in lists */
static gboolean
array_has_value (const gchar * values[], const gchar * value)
{
  gint i;

  for (i = 0; values[i]; i++) {
    if (g_str_has_prefix (value, values[i]))
      return TRUE;
  }
  return FALSE;
}

static gboolean
array_has_uri_value (const gchar * values[], const gchar * value)
{
  gint i;

  for (i = 0; values[i]; i++) {
    if (!g_ascii_strncasecmp (value, values[i], strlen (values[i])))
      return TRUE;
  }
  return FALSE;
}

/* list of URIs that we consider to be streams and that need buffering.
 * We have no mechanism yet to figure this out with a query. */
static const gchar *stream_uris[] = { "http://", "https://", "mms://",
  "mmsh://", "mmsu://", "mmst://", "fd://", "myth://", "ssh://",
  "ftp://", "sftp://",
  NULL
};

/* list of URIs that need a queue because they are pretty bursty */
static const gchar *queue_uris[] = { "cdda://", NULL };

/* blacklisted URIs, we know they will always fail. */
static const gchar *blacklisted_uris[] = { NULL };

/* media types that use adaptive streaming */
static const gchar *adaptive_media[] = {
  "application/x-hls", "application/x-smoothstreaming-manifest",
  "application/dash+xml", NULL
};

#define IS_STREAM_URI(uri)          (array_has_uri_value (stream_uris, uri))
#define IS_QUEUE_URI(uri)           (array_has_uri_value (queue_uris, uri))
#define IS_BLACKLISTED_URI(uri)     (array_has_uri_value (blacklisted_uris, uri))
#define IS_ADAPTIVE_MEDIA(media)    (array_has_value (adaptive_media, media))

/*
 * Generate and configure a source element.
 */
static GstElement *
gen_source_element (GstURIDecodeBin * decoder)
{
  GObjectClass *source_class;
  GstElement *source;
  GParamSpec *pspec;
  GstQuery *query;
  GstSchedulingFlags flags;
  GError *err = NULL;

  if (!decoder->uri)
    goto no_uri;

  GST_LOG_OBJECT (decoder, "finding source for %s", decoder->uri);

  if (!gst_uri_is_valid (decoder->uri))
    goto invalid_uri;

  if (IS_BLACKLISTED_URI (decoder->uri))
    goto uri_blacklisted;

  source =
      gst_element_make_from_uri (GST_URI_SRC, decoder->uri, "source", &err);
  if (!source)
    goto no_source;

  GST_LOG_OBJECT (decoder, "found source type %s", G_OBJECT_TYPE_NAME (source));

  query = gst_query_new_scheduling ();
  if (gst_element_query (source, query)) {
    gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);
    decoder->is_stream = flags & GST_SCHEDULING_FLAG_BANDWIDTH_LIMITED;
  } else
    decoder->is_stream = IS_STREAM_URI (decoder->uri);
  gst_query_unref (query);

  GST_LOG_OBJECT (decoder, "source is stream: %d", decoder->is_stream);

  decoder->need_queue = IS_QUEUE_URI (decoder->uri);
  GST_LOG_OBJECT (decoder, "source needs queue: %d", decoder->need_queue);

  source_class = G_OBJECT_GET_CLASS (source);

  pspec = g_object_class_find_property (source_class, "connection-speed");
  if (pspec != NULL) {
    guint64 speed = decoder->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 (decoder,
          "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) {
      g_object_set (source, "connection-speed", speed, NULL);

      GST_DEBUG_OBJECT (decoder,
          "setting connection-speed=%" G_GUINT64_FORMAT " to source element",
          speed);
    }
  }

  pspec = g_object_class_find_property (source_class, "subtitle-encoding");
  if (pspec != NULL && G_PARAM_SPEC_VALUE_TYPE (pspec) == G_TYPE_STRING) {
    GST_DEBUG_OBJECT (decoder,
        "setting subtitle-encoding=%s to source element", decoder->encoding);
    g_object_set (source, "subtitle-encoding", decoder->encoding, NULL);
  }
  return source;

  /* ERRORS */
no_uri:
  {
    GST_ELEMENT_ERROR (decoder, RESOURCE, NOT_FOUND,
        (_("No URI specified to play from.")), (NULL));
    return NULL;
  }
invalid_uri:
  {
    GST_ELEMENT_ERROR (decoder, RESOURCE, NOT_FOUND,
        (_("Invalid URI \"%s\"."), decoder->uri), (NULL));
    g_clear_error (&err);
    return NULL;
  }
uri_blacklisted:
  {
    GST_ELEMENT_ERROR (decoder, RESOURCE, FAILED,
        (_("This stream type cannot be played yet.")), (NULL));
    return NULL;
  }
no_source:
  {
    /* whoops, could not create the source element, dig a little deeper to
     * figure out what might be wrong. */
    if (err != NULL && err->code == GST_URI_ERROR_UNSUPPORTED_PROTOCOL) {
      gchar *prot;

      prot = gst_uri_get_protocol (decoder->uri);
      if (prot == NULL)
        goto invalid_uri;

      gst_element_post_message (GST_ELEMENT_CAST (decoder),
          gst_missing_uri_source_message_new (GST_ELEMENT (decoder), prot));

      GST_ELEMENT_ERROR (decoder, CORE, MISSING_PLUGIN,
          (_("No URI handler implemented for \"%s\"."), prot), (NULL));

      g_free (prot);
    } else {
      GST_ELEMENT_ERROR (decoder, RESOURCE, NOT_FOUND,
          ("%s", (err) ? err->message : "URI was not accepted by any element"),
          ("No element accepted URI '%s'", decoder->uri));
    }

    g_clear_error (&err);
    return NULL;
  }
}

/**
 * has_all_raw_caps:
 * @pad: a #GstPad
 * @all_raw: pointer to hold the result
 *
 * check if the caps of the pad are all raw. The caps are all raw if
 * all of its structures contain audio/x-raw or video/x-raw.
 *
 * Returns: %FALSE @pad has no caps. Else TRUE and @all_raw set t the result.
 */
static gboolean
has_all_raw_caps (GstPad * pad, GstCaps * rawcaps, gboolean * all_raw)
{
  GstCaps *caps, *intersection;
  gint capssize;
  gboolean res = FALSE;

  caps = gst_pad_query_caps (pad, NULL);
  if (caps == NULL)
    return FALSE;

  GST_DEBUG_OBJECT (pad, "have caps %" GST_PTR_FORMAT, caps);

  capssize = gst_caps_get_size (caps);
  /* no caps, skip and move to the next pad */
  if (capssize == 0 || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
    goto done;

  intersection = gst_caps_intersect (caps, rawcaps);
  *all_raw = !gst_caps_is_empty (intersection)
      && (gst_caps_get_size (intersection) == capssize);
  gst_caps_unref (intersection);

  res = TRUE;

done:
  gst_caps_unref (caps);
  return res;
}

static void
post_missing_plugin_error (GstElement * dec, const gchar * element_name)
{
  GstMessage *msg;

  msg = gst_missing_element_message_new (dec, element_name);
  gst_element_post_message (dec, msg);

  GST_ELEMENT_ERROR (dec, CORE, MISSING_PLUGIN,
      (_("Missing element '%s' - check your GStreamer installation."),
          element_name), (NULL));
  do_async_done (GST_URI_DECODE_BIN (dec));
}

/**
 * analyse_source:
 * @decoder: a #GstURIDecodeBin
 * @is_raw: are all pads raw data
 * @have_out: does the source have output
 * @is_dynamic: is this a dynamic source
 * @use_queue: put a queue before raw output pads
 *
 * Check the source of @decoder and collect information about it.
 *
 * @is_raw will be set to TRUE if the source only produces raw pads. When this
 * function returns, all of the raw pad of the source will be added
 * to @decoder.
 *
 * @have_out: will be set to TRUE if the source has output pads.
 *
 * @is_dynamic: TRUE if the element will create (more) pads dynamically later
 * on.
 *
 * Returns: FALSE if a fatal error occured while scanning.
 */
static gboolean
analyse_source (GstURIDecodeBin * decoder, gboolean * is_raw,
    gboolean * have_out, gboolean * is_dynamic, gboolean use_queue)
{
  GstIterator *pads_iter;
  gboolean done = FALSE;
  gboolean res = TRUE;
  GstCaps *rawcaps;
  GstPad *pad;
  GValue item = { 0, };

  *have_out = FALSE;
  *is_raw = FALSE;
  *is_dynamic = FALSE;

  g_object_get (decoder, "caps", &rawcaps, NULL);
  if (!rawcaps)
    rawcaps = DEFAULT_CAPS;

  pads_iter = gst_element_iterate_src_pads (decoder->source);
  while (!done) {
    switch (gst_iterator_next (pads_iter, &item)) {
      case GST_ITERATOR_ERROR:
        res = FALSE;
        /* FALLTROUGH */
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_RESYNC:
        /* reset results and resync */
        *have_out = FALSE;
        *is_raw = FALSE;
        *is_dynamic = FALSE;
        gst_iterator_resync (pads_iter);
        break;
      case GST_ITERATOR_OK:
        pad = g_value_dup_object (&item);
        /* we now officially have an ouput pad */
        *have_out = TRUE;

        /* if FALSE, this pad has no caps and we continue with the next pad. */
        if (!has_all_raw_caps (pad, rawcaps, is_raw)) {
          gst_object_unref (pad);
          g_value_reset (&item);
          break;
        }

        /* caps on source pad are all raw, we can add the pad */
        if (*is_raw) {
          GstElement *outelem;

          if (use_queue) {
            GstPad *sinkpad;

            /* insert a queue element right before the raw pad */
            outelem = gst_element_factory_make ("queue2", NULL);
            if (!outelem)
              goto no_queue2;

            gst_bin_add (GST_BIN_CAST (decoder), outelem);

            sinkpad = gst_element_get_static_pad (outelem, "sink");
            gst_pad_link (pad, sinkpad);
            gst_object_unref (sinkpad);

            /* save queue pointer so we can remove it later */
            decoder->queue = outelem;

            /* get the new raw srcpad */
            gst_object_unref (pad);
            pad = gst_element_get_static_pad (outelem, "src");
          } else {
            outelem = decoder->source;
          }
          expose_decoded_pad (outelem, pad, decoder);
        }
        gst_object_unref (pad);
        g_value_reset (&item);
        break;
    }
  }
  g_value_unset (&item);
  gst_iterator_free (pads_iter);
  gst_caps_unref (rawcaps);

  if (!*have_out) {
    GstElementClass *elemclass;
    GList *walk;

    /* element has no output pads, check for padtemplates that list SOMETIMES
     * pads. */
    elemclass = GST_ELEMENT_GET_CLASS (decoder->source);

    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) {
        if (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)
          *is_dynamic = TRUE;
        break;
      }
      walk = g_list_next (walk);
    }
  }

  return res;
no_queue2:
  {
    post_missing_plugin_error (GST_ELEMENT_CAST (decoder), "queue2");

    gst_object_unref (pad);
    g_value_unset (&item);
    gst_iterator_free (pads_iter);
    gst_caps_unref (rawcaps);

    return FALSE;
  }
}

/* Remove all decodebin from ourself
 * If force is FALSE, then the decodebin instances will be stored in
 * pending_decodebins for re-use later on.
 * If force is TRUE, then all decodebin instances will be unreferenced
 * and cleared, including the pending ones. */
static void
remove_decoders (GstURIDecodeBin * bin, gboolean force)
{
  GSList *walk;

  for (walk = bin->decodebins; walk; walk = g_slist_next (walk)) {
    GstElement *decoder = GST_ELEMENT_CAST (walk->data);

    GST_DEBUG_OBJECT (bin, "removing old decoder element");
    if (force) {
      gst_element_set_state (decoder, GST_STATE_NULL);
      gst_bin_remove (GST_BIN_CAST (bin), decoder);
    } else {
      GstCaps *caps;

      gst_element_set_state (decoder, GST_STATE_READY);
      /* add it to our list of pending decodebins */
      g_object_ref (decoder);
      gst_bin_remove (GST_BIN_CAST (bin), decoder);
      /* restore some properties we might have changed */
      g_object_set (decoder, "sink-caps", NULL, NULL);
      caps = DEFAULT_CAPS;
      g_object_set (decoder, "caps", caps, NULL);
      gst_caps_unref (caps);
      /* make it freshly floating again */
      g_object_force_floating (G_OBJECT (decoder));

      bin->pending_decodebins =
          g_slist_prepend (bin->pending_decodebins, decoder);
    }
  }
  g_slist_free (bin->decodebins);
  bin->decodebins = NULL;
  if (force) {
    GSList *tmp;

    for (tmp = bin->pending_decodebins; tmp; tmp = tmp->next) {
      gst_element_set_state ((GstElement *) tmp->data, GST_STATE_NULL);
      gst_object_unref ((GstElement *) tmp->data);
    }
    g_slist_free (bin->pending_decodebins);
    bin->pending_decodebins = NULL;

  }

  /* Don't loose the SOURCE flag */
  GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
}

static void
proxy_unknown_type_signal (GstElement * decodebin, GstPad * pad, GstCaps * caps,
    GstURIDecodeBin * dec)
{
  GST_DEBUG_OBJECT (dec, "unknown-type signaled");

  g_signal_emit (dec,
      gst_uri_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
}

static gboolean
proxy_autoplug_continue_signal (GstElement * decodebin, GstPad * pad,
    GstCaps * caps, GstURIDecodeBin * dec)
{
  gboolean result;

  g_signal_emit (dec,
      gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, pad, caps,
      &result);

  GST_DEBUG_OBJECT (dec, "autoplug-continue returned %d", result);

  return result;
}

static GValueArray *
proxy_autoplug_factories_signal (GstElement * decodebin, GstPad * pad,
    GstCaps * caps, GstURIDecodeBin * dec)
{
  GValueArray *result;

  g_signal_emit (dec,
      gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_FACTORIES], 0, pad, caps,
      &result);

  GST_DEBUG_OBJECT (dec, "autoplug-factories returned %p", result);

  return result;
}

static GValueArray *
proxy_autoplug_sort_signal (GstElement * decodebin, GstPad * pad,
    GstCaps * caps, GValueArray * factories, GstURIDecodeBin * dec)
{
  GValueArray *result;

  g_signal_emit (dec,
      gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SORT], 0, pad, caps,
      factories, &result);

  GST_DEBUG_OBJECT (dec, "autoplug-sort returned %p", result);

  return result;
}

static GstAutoplugSelectResult
proxy_autoplug_select_signal (GstElement * decodebin, GstPad * pad,
    GstCaps * caps, GstElementFactory * factory, GstURIDecodeBin * dec)
{
  GstAutoplugSelectResult result;

  g_signal_emit (dec,
      gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_SELECT], 0, pad, caps, factory,
      &result);

  GST_DEBUG_OBJECT (dec, "autoplug-select returned %d", result);

  return result;
}

static gboolean
proxy_autoplug_query_signal (GstElement * decodebin, GstPad * pad,
    GstElement * element, GstQuery * query, GstURIDecodeBin * dec)
{
  gboolean ret = FALSE;

  g_signal_emit (dec,
      gst_uri_decode_bin_signals[SIGNAL_AUTOPLUG_QUERY], 0, pad, element, query,
      &ret);

  GST_DEBUG_OBJECT (dec, "autoplug-query returned %d", ret);

  return ret;
}

static void
proxy_drained_signal (GstElement * decodebin, GstURIDecodeBin * dec)
{
  GST_DEBUG_OBJECT (dec, "drained signaled");

  g_signal_emit (dec, gst_uri_decode_bin_signals[SIGNAL_DRAINED], 0, NULL);
}

/* make a decodebin and connect to all the signals */
static GstElement *
make_decoder (GstURIDecodeBin * decoder)
{
  GstElement *decodebin;

  /* re-use pending decodebin */
  if (decoder->pending_decodebins) {
    GSList *first = decoder->pending_decodebins;
    GST_LOG_OBJECT (decoder, "re-using pending decodebin");
    decodebin = (GstElement *) first->data;
    decoder->pending_decodebins =
        g_slist_delete_link (decoder->pending_decodebins, first);
  } else {
    GST_LOG_OBJECT (decoder, "making new decodebin");

    /* now create the decoder element */
    decodebin = gst_element_factory_make ("decodebin", NULL);

    if (!decodebin)
      goto no_decodebin;

    /* sanity check */
    if (decodebin->numsinkpads == 0)
      goto no_typefind;

    /* connect signals to proxy */
    g_signal_connect (decodebin, "unknown-type",
        G_CALLBACK (proxy_unknown_type_signal), decoder);
    g_signal_connect (decodebin, "autoplug-continue",
        G_CALLBACK (proxy_autoplug_continue_signal), decoder);
    g_signal_connect (decodebin, "autoplug-factories",
        G_CALLBACK (proxy_autoplug_factories_signal), decoder);
    g_signal_connect (decodebin, "autoplug-sort",
        G_CALLBACK (proxy_autoplug_sort_signal), decoder);
    g_signal_connect (decodebin, "autoplug-select",
        G_CALLBACK (proxy_autoplug_select_signal), decoder);
    g_signal_connect (decodebin, "autoplug-query",
        G_CALLBACK (proxy_autoplug_query_signal), decoder);
    g_signal_connect (decodebin, "drained",
        G_CALLBACK (proxy_drained_signal), decoder);

    /* set up callbacks to create the links between decoded data
     * and video/audio/subtitle rendering/output. */
    g_signal_connect (decodebin,
        "pad-added", G_CALLBACK (new_decoded_pad_added_cb), decoder);
    g_signal_connect (decodebin,
        "pad-removed", G_CALLBACK (pad_removed_cb), decoder);
    g_signal_connect (decodebin, "no-more-pads",
        G_CALLBACK (no_more_pads), decoder);
    g_signal_connect (decodebin,
        "unknown-type", G_CALLBACK (unknown_type_cb), decoder);
  }

  /* configure caps if we have any */
  if (decoder->caps)
    g_object_set (decodebin, "caps", decoder->caps, NULL);

  /* Propagate expose-all-streams and connection-speed properties */
  g_object_set (decodebin, "expose-all-streams", decoder->expose_allstreams,
      "connection-speed", decoder->connection_speed / 1000, NULL);

  if (!decoder->is_stream || decoder->is_adaptive) {
    /* propagate the use-buffering property but only when we are not already
     * doing stream buffering with queue2. FIXME, we might want to do stream
     * buffering with the multiqueue buffering instead of queue2. */
    g_object_set (decodebin, "use-buffering", decoder->use_buffering
        || decoder->is_adaptive, NULL);

    if (decoder->use_buffering || decoder->is_adaptive) {
      guint max_bytes;
      guint64 max_time;

      /* configure sizes when buffering */
      if ((max_bytes = decoder->buffer_size) == -1)
        max_bytes = 2 * 1024 * 1024;
      if ((max_time = decoder->buffer_duration) == -1)
        max_time = 5 * GST_SECOND;

      g_object_set (decodebin, "max-size-bytes", max_bytes, "max-size-buffers",
          (guint) 0, "max-size-time", max_time, NULL);
    }
  }

  g_object_set_data (G_OBJECT (decodebin), "pending", GINT_TO_POINTER (1));
  g_object_set (decodebin, "subtitle-encoding", decoder->encoding, NULL);
  decoder->pending++;
  GST_LOG_OBJECT (decoder, "have %d pending dynamic objects", decoder->pending);

  gst_bin_add (GST_BIN_CAST (decoder), decodebin);

  decoder->decodebins = g_slist_prepend (decoder->decodebins, decodebin);

  return decodebin;

  /* ERRORS */
no_decodebin:
  {
    post_missing_plugin_error (GST_ELEMENT_CAST (decoder), "decodebin");
    GST_ELEMENT_ERROR (decoder, CORE, MISSING_PLUGIN, (NULL),
        ("No decodebin element, check your installation"));
    do_async_done (decoder);
    return NULL;
  }
no_typefind:
  {
    gst_object_unref (decodebin);
    GST_ELEMENT_ERROR (decoder, CORE, MISSING_PLUGIN, (NULL),
        ("No typefind element, decodebin is unusable, check your installation"));
    do_async_done (decoder);
    return NULL;
  }
}

/* signaled when we have a stream and we need to configure the download
 * buffering or regular buffering */
static void
type_found (GstElement * typefind, guint probability,
    GstCaps * caps, GstURIDecodeBin * decoder)
{
  GstElement *src_elem, *dec_elem, *queue = NULL;
  GstStructure *s;
  const gchar *media_type, *elem_name;
  gboolean do_download = FALSE;

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

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

  decoder->is_adaptive = IS_ADAPTIVE_MEDIA (media_type);

  /* only enable download buffering if the upstream duration is known */
  if (decoder->download) {
    gint64 dur;

    do_download = (gst_element_query_duration (typefind, GST_FORMAT_BYTES, &dur)
        && dur != -1);
  }

  dec_elem = make_decoder (decoder);
  if (!dec_elem)
    goto no_decodebin;

  if (decoder->is_adaptive) {
    src_elem = typefind;
  } else {
    if (do_download) {
      elem_name = "downloadbuffer";
    } else {
      elem_name = "queue2";
    }
    queue = gst_element_factory_make (elem_name, NULL);
    if (!queue)
      goto no_buffer_element;

    decoder->queue = queue;

    GST_DEBUG_OBJECT (decoder, "check media-type %s, %d", media_type,
        do_download);

    if (do_download) {
      gchar *temp_template, *filename;
      const gchar *tmp_dir, *prgname;

      tmp_dir = g_get_user_cache_dir ();
      prgname = g_get_prgname ();
      if (prgname == NULL)
        prgname = "GStreamer";

      filename = g_strdup_printf ("%s-XXXXXX", prgname);

      /* build our filename */
      temp_template = g_build_filename (tmp_dir, filename, NULL);

      GST_DEBUG_OBJECT (decoder, "enable download buffering in %s (%s, %s, %s)",
          temp_template, tmp_dir, prgname, filename);

      /* configure progressive download for selected media types */
      g_object_set (queue, "temp-template", temp_template, NULL);

      g_free (filename);
      g_free (temp_template);
    } else {
      g_object_set (queue, "use-buffering", TRUE, NULL);
      g_object_set (queue, "ring-buffer-max-size",
          decoder->ring_buffer_max_size, NULL);
      /* Disable max-size-buffers */
      g_object_set (queue, "max-size-buffers", 0, NULL);
    }

    /* If buffer size or duration are set, set them on the element */
    if (decoder->buffer_size != -1)
      g_object_set (queue, "max-size-bytes", decoder->buffer_size, NULL);
    if (decoder->buffer_duration != -1)
      g_object_set (queue, "max-size-time", decoder->buffer_duration, NULL);

    gst_bin_add (GST_BIN_CAST (decoder), queue);

    if (!gst_element_link_pads (typefind, "src", queue, "sink"))
      goto could_not_link;
    src_elem = queue;
  }

  /* to force caps on the decodebin element and avoid reparsing stuff by
   * typefind. It also avoids a deadlock in the way typefind activates pads in
   * the state change */
  g_object_set (dec_elem, "sink-caps", caps, NULL);

  if (!gst_element_link_pads (src_elem, "src", dec_elem, "sink"))
    goto could_not_link;

  /* PLAYING in one go might fail (see bug #632782) */
  gst_element_set_state (dec_elem, GST_STATE_PAUSED);
  gst_element_sync_state_with_parent (dec_elem);
  if (queue)
    gst_element_sync_state_with_parent (queue);

  return;

  /* ERRORS */
no_decodebin:
  {
    /* error was posted */
    return;
  }
could_not_link:
  {
    GST_ELEMENT_ERROR (decoder, CORE, NEGOTIATION,
        (NULL), ("Can't link typefind to decodebin element"));
    do_async_done (decoder);
    return;
  }
no_buffer_element:
  {
    post_missing_plugin_error (GST_ELEMENT_CAST (decoder), elem_name);
    return;
  }
}

/* setup a streaming source. This will first plug a typefind element to the
 * source. After we find the type, we decide to plug a queue2 and continue to
 * plug a decodebin starting from the found caps */
static gboolean
setup_streaming (GstURIDecodeBin * decoder)
{
  GstElement *typefind;

  /* now create the decoder element */
  typefind = gst_element_factory_make ("typefind", NULL);
  if (!typefind)
    goto no_typefind;

  gst_bin_add (GST_BIN_CAST (decoder), typefind);

  if (!gst_element_link_pads (decoder->source, NULL, typefind, "sink"))
    goto could_not_link;

  decoder->typefind = typefind;

  /* connect a signal to find out when the typefind element found
   * a type */
  decoder->have_type_id =
      g_signal_connect (decoder->typefind, "have-type",
      G_CALLBACK (type_found), decoder);

  return TRUE;

  /* ERRORS */
no_typefind:
  {
    post_missing_plugin_error (GST_ELEMENT_CAST (decoder), "typefind");
    GST_ELEMENT_ERROR (decoder, CORE, MISSING_PLUGIN, (NULL),
        ("No typefind element, check your installation"));
    do_async_done (decoder);
    return FALSE;
  }
could_not_link:
  {
    GST_ELEMENT_ERROR (decoder, CORE, NEGOTIATION,
        (NULL), ("Can't link source to typefind element"));
    gst_bin_remove (GST_BIN_CAST (decoder), typefind);
    /* Don't loose the SOURCE flag */
    GST_OBJECT_FLAG_SET (decoder, GST_ELEMENT_FLAG_SOURCE);
    do_async_done (decoder);
    return FALSE;
  }
}

static void
free_stream (gpointer value)
{
  g_slice_free (GstURIDecodeBinStream, value);
}

/* remove source and all related elements */
static void
remove_source (GstURIDecodeBin * bin)
{
  GstElement *source = bin->source;

  if (source) {
    GST_DEBUG_OBJECT (bin, "removing old src element");
    gst_element_set_state (source, GST_STATE_NULL);

    if (bin->src_np_sig_id) {
      g_signal_handler_disconnect (source, bin->src_np_sig_id);
      bin->src_np_sig_id = 0;
    }
    if (bin->src_nmp_sig_id) {
      g_signal_handler_disconnect (source, bin->src_nmp_sig_id);
      bin->src_nmp_sig_id = 0;
    }
    gst_bin_remove (GST_BIN_CAST (bin), source);
    bin->source = NULL;
  }
  if (bin->queue) {
    GST_DEBUG_OBJECT (bin, "removing old queue element");
    gst_element_set_state (bin->queue, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (bin), bin->queue);
    bin->queue = NULL;
  }
  if (bin->typefind) {
    GST_DEBUG_OBJECT (bin, "removing old typefind element");
    gst_element_set_state (bin->typefind, GST_STATE_NULL);
    gst_bin_remove (GST_BIN_CAST (bin), bin->typefind);
    bin->typefind = NULL;
  }
  if (bin->streams) {
    g_hash_table_destroy (bin->streams);
    bin->streams = NULL;
  }
  /* Don't loose the SOURCE flag */
  GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
}

/* is called when a dynamic source element created a new pad. */
static void
source_new_pad (GstElement * element, GstPad * pad, GstURIDecodeBin * bin)
{
  GstElement *decoder;
  gboolean is_raw;
  GstCaps *rawcaps;

  GST_URI_DECODE_BIN_LOCK (bin);
  GST_DEBUG_OBJECT (bin, "Found new pad %s.%s in source element %s",
      GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));

  g_object_get (bin, "caps", &rawcaps, NULL);
  if (!rawcaps)
    rawcaps = DEFAULT_CAPS;

  /* if this is a pad with all raw caps, we can expose it */
  if (has_all_raw_caps (pad, rawcaps, &is_raw) && is_raw) {
    /* it's all raw, create output pads. */
    GST_URI_DECODE_BIN_UNLOCK (bin);
    gst_caps_unref (rawcaps);
    expose_decoded_pad (element, pad, bin);
    return;
  }
  gst_caps_unref (rawcaps);

  /* not raw, create decoder */
  decoder = make_decoder (bin);
  if (!decoder)
    goto no_decodebin;

  /* and link to decoder */
  if (!gst_element_link_pads (bin->source, NULL, decoder, "sink"))
    goto could_not_link;

  GST_DEBUG_OBJECT (bin, "linked decoder to new pad");

  gst_element_sync_state_with_parent (decoder);
  GST_URI_DECODE_BIN_UNLOCK (bin);

  return;

  /* ERRORS */
no_decodebin:
  {
    /* error was posted */
    GST_URI_DECODE_BIN_UNLOCK (bin);
    return;
  }
could_not_link:
  {
    GST_ELEMENT_ERROR (bin, CORE, NEGOTIATION,
        (NULL), ("Can't link source to decoder element"));
    GST_URI_DECODE_BIN_UNLOCK (bin);
    do_async_done (bin);
    return;
  }
}

static gboolean
is_live_source (GstElement * source)
{
  GObjectClass *source_class = NULL;
  gboolean is_live = FALSE;
  GParamSpec *pspec;

  source_class = G_OBJECT_GET_CLASS (source);
  pspec = g_object_class_find_property (source_class, "is-live");
  if (!pspec || G_PARAM_SPEC_VALUE_TYPE (pspec) != G_TYPE_BOOLEAN)
    return FALSE;

  g_object_get (G_OBJECT (source), "is-live", &is_live, NULL);

  return is_live;
}

/* construct and run the source and decoder elements until we found
 * all the streams or until a preroll queue has been filled.
*/
static gboolean
setup_source (GstURIDecodeBin * decoder)
{
  gboolean is_raw, have_out, is_dynamic;

  GST_DEBUG_OBJECT (decoder, "setup source");

  /* delete old src */
  remove_source (decoder);

  decoder->pending = 0;

  /* create and configure an element that can handle the uri */
  if (!(decoder->source = gen_source_element (decoder)))
    goto no_source;

  /* state will be merged later - if file is not found, error will be
   * handled by the application right after. */
  gst_bin_add (GST_BIN_CAST (decoder), decoder->source);

  /* notify of the new source used */
  g_object_notify (G_OBJECT (decoder), "source");

  g_signal_emit (decoder, gst_uri_decode_bin_signals[SIGNAL_SOURCE_SETUP],
      0, decoder->source);

  if (is_live_source (decoder->source))
    decoder->is_stream = FALSE;

  /* remove the old decoders now, if any */
  remove_decoders (decoder, FALSE);

  /* stream admin setup */
  decoder->streams = g_hash_table_new_full (NULL, NULL, NULL, free_stream);

  /* see if the source element emits raw audio/video all by itself,
   * if so, we can create streams for the pads and be done with it.
   * Also check that is has source pads, if not, we assume it will
   * do everything itself.  */
  if (!analyse_source (decoder, &is_raw, &have_out, &is_dynamic,
          decoder->need_queue))
    goto invalid_source;

  if (is_raw) {
    GST_DEBUG_OBJECT (decoder, "Source provides all raw data");
    /* source provides raw data, we added the pads and we can now signal a
     * no_more pads because we are done. */
    gst_element_no_more_pads (GST_ELEMENT_CAST (decoder));
    do_async_done (decoder);
    return TRUE;
  }
  if (!have_out && !is_dynamic) {
    GST_DEBUG_OBJECT (decoder, "Source has no output pads");
    /* create a stream to indicate that this uri is handled by a self
     * contained element. We are now done. */
    add_element_stream (decoder->source, decoder);
    return TRUE;
  }
  if (is_dynamic) {
    GST_DEBUG_OBJECT (decoder, "Source has dynamic output pads");
    /* connect a handler for the new-pad signal */
    decoder->src_np_sig_id =
        g_signal_connect (decoder->source, "pad-added",
        G_CALLBACK (source_new_pad), decoder);
    decoder->src_nmp_sig_id =
        g_signal_connect (decoder->source, "no-more-pads",
        G_CALLBACK (source_no_more_pads), decoder);
    g_object_set_data (G_OBJECT (decoder->source), "pending",
        GINT_TO_POINTER (1));
    decoder->pending++;
  } else {
    if (decoder->is_stream) {
      GST_DEBUG_OBJECT (decoder, "Setting up streaming");
      /* do the stream things here */
      if (!setup_streaming (decoder))
        goto streaming_failed;
    } else {
      GstElement *dec_elem;

      /* no streaming source, we can link now */
      GST_DEBUG_OBJECT (decoder, "Plugging decodebin to source");

      dec_elem = make_decoder (decoder);
      if (!dec_elem)
        goto no_decoder;

      if (!gst_element_link_pads (decoder->source, NULL, dec_elem, "sink"))
        goto could_not_link;
    }
  }
  return TRUE;

  /* ERRORS */
no_source:
  {
    /* error message was already posted */
    return FALSE;
  }
invalid_source:
  {
    GST_ELEMENT_ERROR (decoder, CORE, FAILED,
        (_("Source element is invalid.")), (NULL));
    return FALSE;
  }
no_decoder:
  {
    /* message was posted */
    return FALSE;
  }
streaming_failed:
  {
    /* message was posted */
    return FALSE;
  }
could_not_link:
  {
    GST_ELEMENT_ERROR (decoder, CORE, NEGOTIATION,
        (NULL), ("Can't link source to decoder element"));
    return FALSE;
  }
}

static void
value_list_append_structure_list (GValue * list_val, GstStructure ** first,
    GList * structure_list)
{
  GList *l;

  for (l = structure_list; l != NULL; l = l->next) {
    GValue val = { 0, };

    if (*first == NULL)
      *first = gst_structure_copy ((GstStructure *) l->data);

    g_value_init (&val, GST_TYPE_STRUCTURE);
    g_value_take_boxed (&val, gst_structure_copy ((GstStructure *) l->data));
    gst_value_list_append_value (list_val, &val);
    g_value_unset (&val);
  }
}

/* if it's a redirect message with multiple redirect locations we might
 * want to pick a different 'best' location depending on the required
 * bitrates and the connection speed */
static GstMessage *
handle_redirect_message (GstURIDecodeBin * dec, GstMessage * msg)
{
  const GValue *locations_list, *location_val;
  GstMessage *new_msg;
  GstStructure *new_structure = NULL;
  GList *l_good = NULL, *l_neutral = NULL, *l_bad = NULL;
  GValue new_list = { 0, };
  guint size, i;
  const GstStructure *structure;

  GST_DEBUG_OBJECT (dec, "redirect message: %" GST_PTR_FORMAT, msg);
  GST_DEBUG_OBJECT (dec, "connection speed: %" G_GUINT64_FORMAT,
      dec->connection_speed);

  structure = gst_message_get_structure (msg);
  if (dec->connection_speed == 0 || structure == NULL)
    return msg;

  locations_list = gst_structure_get_value (structure, "locations");
  if (locations_list == NULL)
    return msg;

  size = gst_value_list_get_size (locations_list);
  if (size < 2)
    return msg;

  /* maintain existing order as much as possible, just sort references
   * with too high a bitrate to the end (the assumption being that if
   * bitrates are given they are given for all interesting streams and
   * that the you-need-at-least-version-xyz redirect has the same bitrate
   * as the lowest referenced redirect alternative) */
  for (i = 0; i < size; ++i) {
    const GstStructure *s;
    gint bitrate = 0;

    location_val = gst_value_list_get_value (locations_list, i);
    s = (const GstStructure *) g_value_get_boxed (location_val);
    if (!gst_structure_get_int (s, "minimum-bitrate", &bitrate) || bitrate <= 0) {
      GST_DEBUG_OBJECT (dec, "no bitrate: %" GST_PTR_FORMAT, s);
      l_neutral = g_list_append (l_neutral, (gpointer) s);
    } else if (bitrate > dec->connection_speed) {
      GST_DEBUG_OBJECT (dec, "bitrate too high: %" GST_PTR_FORMAT, s);
      l_bad = g_list_append (l_bad, (gpointer) s);
    } else if (bitrate <= dec->connection_speed) {
      GST_DEBUG_OBJECT (dec, "bitrate OK: %" GST_PTR_FORMAT, s);
      l_good = g_list_append (l_good, (gpointer) s);
    }
  }

  g_value_init (&new_list, GST_TYPE_LIST);
  value_list_append_structure_list (&new_list, &new_structure, l_good);
  value_list_append_structure_list (&new_list, &new_structure, l_neutral);
  value_list_append_structure_list (&new_list, &new_structure, l_bad);
  gst_structure_take_value (new_structure, "locations", &new_list);

  g_list_free (l_good);
  g_list_free (l_neutral);
  g_list_free (l_bad);

  new_msg = gst_message_new_element (msg->src, new_structure);
  gst_message_unref (msg);

  GST_DEBUG_OBJECT (dec, "new redirect message: %" GST_PTR_FORMAT, new_msg);
  return new_msg;
}

static void
handle_message (GstBin * bin, GstMessage * msg)
{
  GstURIDecodeBin *dec = GST_URI_DECODE_BIN (bin);

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ELEMENT:{
      if (gst_message_has_name (msg, "redirect")) {
        /* sort redirect messages based on the connection speed. This simplifies
         * the user of this element as it can in most cases just pick the first item
         * of the sorted list as a good redirection candidate. It can of course
         * choose something else from the list if it has a better way. */
        msg = handle_redirect_message (dec, msg);
      }
      break;
    }
    case GST_MESSAGE_ERROR:{
      GError *err = NULL;

      /* Filter out missing plugin error messages from the decodebins. Only if
       * all decodebins exposed no streams we will report a missing plugin
       * error from no_more_pads_full()
       */
      gst_message_parse_error (msg, &err, NULL);
      if (g_error_matches (err, GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN)
          || g_error_matches (err, GST_STREAM_ERROR,
              GST_STREAM_ERROR_CODEC_NOT_FOUND)) {
        dec->missing_plugin_errors =
            g_list_prepend (dec->missing_plugin_errors, gst_message_ref (msg));

        no_more_pads_full (GST_ELEMENT (GST_MESSAGE_SRC (msg)), FALSE,
            GST_URI_DECODE_BIN (bin));
        gst_message_unref (msg);
        msg = NULL;
      }
      g_clear_error (&err);
      break;
    }
    default:
      break;
  }

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

/* generic struct passed to all query fold methods
 * FIXME, move to core.
 */
typedef struct
{
  GstQuery *query;
  gint64 min;
  gint64 max;
  gboolean seekable;
  gboolean live;
} QueryFold;

typedef void (*QueryInitFunction) (GstURIDecodeBin * dec, QueryFold * fold);
typedef void (*QueryDoneFunction) (GstURIDecodeBin * dec, QueryFold * fold);

/* for duration/position we collect all durations/positions and take
 * the MAX of all valid results */
static void
decoder_query_init (GstURIDecodeBin * dec, QueryFold * fold)
{
  fold->min = 0;
  fold->max = -1;
  fold->seekable = TRUE;
  fold->live = 0;
}

static gboolean
decoder_query_duration_fold (const GValue * item, GValue * ret,
    QueryFold * fold)
{
  GstPad *pad = g_value_get_object (item);

  if (gst_pad_query (pad, fold->query)) {
    gint64 duration;

    g_value_set_boolean (ret, TRUE);

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

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

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

static void
decoder_query_duration_done (GstURIDecodeBin * dec, QueryFold * fold)
{
  GstFormat format;

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

  GST_DEBUG ("max duration %" G_GINT64_FORMAT, fold->max);
}

static gboolean
decoder_query_position_fold (const GValue * item, GValue * ret,
    QueryFold * fold)
{
  GstPad *pad = g_value_get_object (item);

  if (gst_pad_query (pad, fold->query)) {
    gint64 position;

    g_value_set_boolean (ret, TRUE);

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

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

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

  return TRUE;
}

static void
decoder_query_position_done (GstURIDecodeBin * dec, QueryFold * fold)
{
  GstFormat format;

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

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

static gboolean
decoder_query_latency_fold (const GValue * item, GValue * ret, QueryFold * fold)
{
  GstPad *pad = g_value_get_object (item);

  if (gst_pad_query (pad, fold->query)) {
    GstClockTime min, max;
    gboolean live;

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

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

    if (live) {
      /* for the combined latency we collect the MAX of all min latencies and
       * the MIN of all max latencies */
      if (min > fold->min)
        fold->min = min;
      if (fold->max == -1)
        fold->max = max;
      else if (max < fold->max)
        fold->max = max;

      fold->live = TRUE;
    }
  } else {
    GST_LOG_OBJECT (pad, "latency query failed");
    g_value_set_boolean (ret, FALSE);
  }

  return TRUE;
}

static void
decoder_query_latency_done (GstURIDecodeBin * dec, QueryFold * fold)
{
  /* store max in query result */
  gst_query_set_latency (fold->query, fold->live, fold->min, fold->max);

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

/* we are seekable if all srcpads are seekable */
static gboolean
decoder_query_seeking_fold (const GValue * item, GValue * ret, QueryFold * fold)
{
  GstPad *pad = g_value_get_object (item);

  if (gst_pad_query (pad, fold->query)) {
    gboolean seekable;

    g_value_set_boolean (ret, TRUE);
    gst_query_parse_seeking (fold->query, NULL, &seekable, NULL, NULL);

    GST_DEBUG_OBJECT (item, "got seekable %d", seekable);

    if (fold->seekable)
      fold->seekable = seekable;
  }

  return TRUE;
}

static void
decoder_query_seeking_done (GstURIDecodeBin * dec, QueryFold * fold)
{
  GstFormat format;

  gst_query_parse_seeking (fold->query, &format, NULL, NULL, NULL);
  gst_query_set_seeking (fold->query, format, fold->seekable, 0, -1);

  GST_DEBUG_OBJECT (dec, "seekable %d", fold->seekable);
}

/* generic fold, return first valid result */
static gboolean
decoder_query_generic_fold (const GValue * item, GValue * ret, QueryFold * fold)
{
  GstPad *pad = g_value_get_object (item);
  gboolean res;

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

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


/* we're a bin, the default query handler iterates sink elements, which we don't
 * have normally. We should just query all source pads.
 */
static gboolean
gst_uri_decode_bin_query (GstElement * element, GstQuery * query)
{
  GstURIDecodeBin *decoder;
  gboolean res = FALSE;
  GstIterator *iter;
  GstIteratorFoldFunction fold_func;
  QueryInitFunction fold_init = NULL;
  QueryDoneFunction fold_done = NULL;
  QueryFold fold_data;
  GValue ret = { 0 };
  gboolean default_ret = FALSE;

  decoder = GST_URI_DECODE_BIN (element);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      /* iterate and collect durations */
      fold_func = (GstIteratorFoldFunction) decoder_query_duration_fold;
      fold_init = decoder_query_init;
      fold_done = decoder_query_duration_done;
      break;
    case GST_QUERY_POSITION:
      /* iterate and collect durations */
      fold_func = (GstIteratorFoldFunction) decoder_query_position_fold;
      fold_init = decoder_query_init;
      fold_done = decoder_query_position_done;
      break;
    case GST_QUERY_LATENCY:
      /* iterate and collect durations */
      fold_func = (GstIteratorFoldFunction) decoder_query_latency_fold;
      fold_init = decoder_query_init;
      fold_done = decoder_query_latency_done;
      default_ret = TRUE;
      break;
    case GST_QUERY_SEEKING:
      /* iterate and collect durations */
      fold_func = (GstIteratorFoldFunction) decoder_query_seeking_fold;
      fold_init = decoder_query_init;
      fold_done = decoder_query_seeking_done;
      break;
    default:
      fold_func = (GstIteratorFoldFunction) decoder_query_generic_fold;
      break;
  }

  fold_data.query = query;

  g_value_init (&ret, G_TYPE_BOOLEAN);
  g_value_set_boolean (&ret, default_ret);

  iter = gst_element_iterate_src_pads (element);
  GST_DEBUG_OBJECT (element, "Sending query %p (type %d) to src pads",
      query, GST_QUERY_TYPE (query));

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

  while (TRUE) {
    GstIteratorResult ires;

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

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

  return res;
}

static GstStateChangeReturn
gst_uri_decode_bin_change_state (GstElement * element,
    GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstURIDecodeBin *decoder;

  decoder = GST_URI_DECODE_BIN (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      do_async_start (decoder);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto setup_failed;
  else if (ret == GST_STATE_CHANGE_NO_PREROLL)
    do_async_done (decoder);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      GST_DEBUG ("ready to paused");
      if (!setup_source (decoder))
        goto source_failed;

      ret = GST_STATE_CHANGE_ASYNC;

      /* And now sync the states of everything we added */
      g_slist_foreach (decoder->decodebins,
          (GFunc) gst_element_sync_state_with_parent, NULL);
      if (decoder->typefind)
        ret = gst_element_set_state (decoder->typefind, GST_STATE_PAUSED);
      if (ret == GST_STATE_CHANGE_FAILURE)
        goto setup_failed;
      if (decoder->queue)
        ret = gst_element_set_state (decoder->queue, GST_STATE_PAUSED);
      if (ret == GST_STATE_CHANGE_FAILURE)
        goto setup_failed;
      if (decoder->source)
        ret = gst_element_set_state (decoder->source, GST_STATE_PAUSED);
      if (ret == GST_STATE_CHANGE_FAILURE)
        goto setup_failed;
      if (ret == GST_STATE_CHANGE_SUCCESS)
        ret = GST_STATE_CHANGE_ASYNC;

      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      GST_DEBUG ("paused to ready");
      remove_decoders (decoder, FALSE);
      remove_source (decoder);
      do_async_done (decoder);
      g_list_free_full (decoder->missing_plugin_errors,
          (GDestroyNotify) gst_message_unref);
      decoder->missing_plugin_errors = NULL;
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      GST_DEBUG ("ready to null");
      remove_decoders (decoder, TRUE);
      remove_source (decoder);
      break;
    default:
      break;
  }
  return ret;

  /* ERRORS */
source_failed:
  {
    do_async_done (decoder);
    return GST_STATE_CHANGE_FAILURE;
  }
setup_failed:
  {
    /* clean up leftover groups */
    do_async_done (decoder);
    return GST_STATE_CHANGE_FAILURE;
  }
}

gboolean
gst_uri_decode_bin_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (gst_uri_decode_bin_debug, "uridecodebin", 0,
      "URI decoder element");

  return gst_element_register (plugin, "uridecodebin", GST_RANK_NONE,
      GST_TYPE_URI_DECODE_BIN);
}
