/* GStreamer
 * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
 *               2009 Nokia Corporation
 *
 * 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:gstdiscoverer
 * @short_description: Utility for discovering information on URIs.
 *
 * The #GstDiscoverer is a utility object which allows to get as much
 * information as possible from one or many URIs.
 *
 * It provides two APIs, allowing usage in blocking or non-blocking mode.
 *
 * The blocking mode just requires calling gst_discoverer_discover_uri()
 * with the URI one wishes to discover.
 *
 * The non-blocking mode requires a running #GMainLoop iterating a
 * #GMainContext, where one connects to the various signals, appends the
 * URIs to be processed (through gst_discoverer_discover_uri_async()) and then
 * asks for the discovery to begin (through gst_discoverer_start()).
 * By default this will use the GLib default main context unless you have
 * set a custom context using g_main_context_push_thread_default().
 *
 * All the information is returned in a #GstDiscovererInfo structure.
 */

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

#include <gst/video/video.h>
#include <gst/audio/audio.h>

#include "pbutils.h"
#include "pbutils-private.h"

GST_DEBUG_CATEGORY_STATIC (discoverer_debug);
#define GST_CAT_DEFAULT discoverer_debug

static GQuark _CAPS_QUARK;
static GQuark _TAGS_QUARK;
static GQuark _TOC_QUARK;
static GQuark _STREAM_ID_QUARK;
static GQuark _MISSING_PLUGIN_QUARK;
static GQuark _STREAM_TOPOLOGY_QUARK;
static GQuark _TOPOLOGY_PAD_QUARK;


typedef struct
{
  GstDiscoverer *dc;
  GstPad *pad;
  GstElement *queue;
  GstElement *sink;
  GstTagList *tags;
  GstToc *toc;
  gchar *stream_id;
} PrivateStream;

struct _GstDiscovererPrivate
{
  gboolean async;

  /* allowed time to discover each uri in nanoseconds */
  GstClockTime timeout;

  /* list of pending URI to process (current excluded) */
  GList *pending_uris;

  GMutex lock;

  /* TRUE if processing a URI */
  gboolean processing;

  /* TRUE if discoverer has been started */
  gboolean running;

  /* TRUE if ASYNC_DONE has been received (need to check for subtitle tags) */
  gboolean async_done;

  /* current items */
  GstDiscovererInfo *current_info;
  GError *current_error;
  GstStructure *current_topology;

  /* List of private streams */
  GList *streams;

  /* List of these sinks and their handler IDs (to remove the probe) */
  guint pending_subtitle_pads;

  /* Global elements */
  GstBin *pipeline;
  GstElement *uridecodebin;
  GstBus *bus;

  GType decodebin_type;

  /* Custom main context variables */
  GMainContext *ctx;
  guint sourceid;
  guint timeoutid;

  /* reusable queries */
  GstQuery *seeking_query;

  /* Handler ids for various callbacks */
  gulong pad_added_id;
  gulong pad_remove_id;
  gulong source_chg_id;
  gulong element_added_id;
  gulong bus_cb_id;
};

#define DISCO_LOCK(dc) g_mutex_lock (&dc->priv->lock);
#define DISCO_UNLOCK(dc) g_mutex_unlock (&dc->priv->lock);

static void
_do_init (void)
{
  GST_DEBUG_CATEGORY_INIT (discoverer_debug, "discoverer", 0, "Discoverer");

  _CAPS_QUARK = g_quark_from_static_string ("caps");
  _TAGS_QUARK = g_quark_from_static_string ("tags");
  _TOC_QUARK = g_quark_from_static_string ("toc");
  _STREAM_ID_QUARK = g_quark_from_static_string ("stream-id");
  _MISSING_PLUGIN_QUARK = g_quark_from_static_string ("missing-plugin");
  _STREAM_TOPOLOGY_QUARK = g_quark_from_static_string ("stream-topology");
  _TOPOLOGY_PAD_QUARK = g_quark_from_static_string ("pad");
};

G_DEFINE_TYPE_EXTENDED (GstDiscoverer, gst_discoverer, G_TYPE_OBJECT, 0,
    _do_init ());

enum
{
  SIGNAL_FINISHED,
  SIGNAL_STARTING,
  SIGNAL_DISCOVERED,
  SIGNAL_SOURCE_SETUP,
  LAST_SIGNAL
};

#define DEFAULT_PROP_TIMEOUT 15 * GST_SECOND

enum
{
  PROP_0,
  PROP_TIMEOUT
};

static guint gst_discoverer_signals[LAST_SIGNAL] = { 0 };

static void gst_discoverer_set_timeout (GstDiscoverer * dc,
    GstClockTime timeout);
static gboolean async_timeout_cb (GstDiscoverer * dc);

static void discoverer_bus_cb (GstBus * bus, GstMessage * msg,
    GstDiscoverer * dc);
static void uridecodebin_pad_added_cb (GstElement * uridecodebin, GstPad * pad,
    GstDiscoverer * dc);
static void uridecodebin_pad_removed_cb (GstElement * uridecodebin,
    GstPad * pad, GstDiscoverer * dc);
static void uridecodebin_source_changed_cb (GstElement * uridecodebin,
    GParamSpec * pspec, GstDiscoverer * dc);

static void gst_discoverer_dispose (GObject * dc);
static void gst_discoverer_finalize (GObject * dc);
static void gst_discoverer_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_discoverer_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void
gst_discoverer_class_init (GstDiscovererClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  gobject_class->dispose = gst_discoverer_dispose;
  gobject_class->finalize = gst_discoverer_finalize;

  gobject_class->set_property = gst_discoverer_set_property;
  gobject_class->get_property = gst_discoverer_get_property;

  g_type_class_add_private (klass, sizeof (GstDiscovererPrivate));

  /* properties */
  /**
   * GstDiscoverer:timeout:
   *
   * The duration (in nanoseconds) after which the discovery of an individual
   * URI will timeout.
   *
   * If the discovery of a URI times out, the %GST_DISCOVERER_TIMEOUT will be
   * set on the result flags.
   */
  g_object_class_install_property (gobject_class, PROP_TIMEOUT,
      g_param_spec_uint64 ("timeout", "timeout", "Timeout",
          GST_SECOND, 3600 * GST_SECOND, DEFAULT_PROP_TIMEOUT,
          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));

  /* signals */
  /**
   * GstDiscoverer::finished:
   * @discoverer: the #GstDiscoverer
   *
   * Will be emitted in async mode when all pending URIs have been processed.
   */
  gst_discoverer_signals[SIGNAL_FINISHED] =
      g_signal_new ("finished", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstDiscovererClass, finished),
      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);

  /**
   * GstDiscoverer::starting:
   * @discoverer: the #GstDiscoverer
   *
   * Will be emitted when the discover starts analyzing the pending URIs
   */
  gst_discoverer_signals[SIGNAL_STARTING] =
      g_signal_new ("starting", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstDiscovererClass, starting),
      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE);

  /**
   * GstDiscoverer::discovered:
   * @discoverer: the #GstDiscoverer
   * @info: the results #GstDiscovererInfo
   * @error: (type GLib.Error): #GError, which will be non-NULL if an error
   *                            occurred during discovery. You must not
   *                            free this #GError, it will be freed by
   *                            the discoverer.
   *
   * Will be emitted in async mode when all information on a URI could be
   * discovered, or an error occurred.
   *
   * When an error occurs, @info might still contain some partial information,
   * depending on the circumstances of the error.
   */
  gst_discoverer_signals[SIGNAL_DISCOVERED] =
      g_signal_new ("discovered", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
      G_STRUCT_OFFSET (GstDiscovererClass, discovered),
      NULL, NULL, g_cclosure_marshal_generic,
      G_TYPE_NONE, 2, GST_TYPE_DISCOVERER_INFO,
      G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE);

  /**
   * GstDiscoverer::source-setup:
   * @discoverer: the #GstDiscoverer
   * @source: source element
   *
   * This signal is emitted after the source element has been created for, so
   * the URI being discovered, 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 signal is usually emitted from the context of a GStreamer streaming
   * thread.
   */
  gst_discoverer_signals[SIGNAL_SOURCE_SETUP] =
      g_signal_new ("source-setup", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDiscovererClass, source_setup),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
}

static void
uridecodebin_element_added_cb (GstElement * uridecodebin,
    GstElement * child, GstDiscoverer * dc)
{
  GST_DEBUG ("New element added to uridecodebin : %s",
      GST_ELEMENT_NAME (child));

  if (G_OBJECT_TYPE (child) == dc->priv->decodebin_type) {
    g_object_set (child, "post-stream-topology", TRUE, NULL);
  }
}

static void
gst_discoverer_init (GstDiscoverer * dc)
{
  GstElement *tmp;
  GstFormat format = GST_FORMAT_TIME;

  dc->priv = G_TYPE_INSTANCE_GET_PRIVATE (dc, GST_TYPE_DISCOVERER,
      GstDiscovererPrivate);

  dc->priv->timeout = DEFAULT_PROP_TIMEOUT;
  dc->priv->async = FALSE;
  dc->priv->async_done = FALSE;

  g_mutex_init (&dc->priv->lock);

  dc->priv->pending_subtitle_pads = 0;

  GST_LOG ("Creating pipeline");
  dc->priv->pipeline = (GstBin *) gst_pipeline_new ("Discoverer");
  GST_LOG_OBJECT (dc, "Creating uridecodebin");
  dc->priv->uridecodebin =
      gst_element_factory_make ("uridecodebin", "discoverer-uri");
  if (G_UNLIKELY (dc->priv->uridecodebin == NULL)) {
    GST_ERROR ("Can't create uridecodebin");
    return;
  }
  GST_LOG_OBJECT (dc, "Adding uridecodebin to pipeline");
  gst_bin_add (dc->priv->pipeline, dc->priv->uridecodebin);

  dc->priv->pad_added_id =
      g_signal_connect_object (dc->priv->uridecodebin, "pad-added",
      G_CALLBACK (uridecodebin_pad_added_cb), dc, 0);
  dc->priv->pad_remove_id =
      g_signal_connect_object (dc->priv->uridecodebin, "pad-removed",
      G_CALLBACK (uridecodebin_pad_removed_cb), dc, 0);
  dc->priv->source_chg_id =
      g_signal_connect_object (dc->priv->uridecodebin, "notify::source",
      G_CALLBACK (uridecodebin_source_changed_cb), dc, 0);

  GST_LOG_OBJECT (dc, "Getting pipeline bus");
  dc->priv->bus = gst_pipeline_get_bus ((GstPipeline *) dc->priv->pipeline);

  dc->priv->bus_cb_id =
      g_signal_connect_object (dc->priv->bus, "message",
      G_CALLBACK (discoverer_bus_cb), dc, 0);

  GST_DEBUG_OBJECT (dc, "Done initializing Discoverer");

  /* This is ugly. We get the GType of decodebin so we can quickly detect
   * when a decodebin is added to uridecodebin so we can set the
   * post-stream-topology setting to TRUE */
  dc->priv->element_added_id =
      g_signal_connect_object (dc->priv->uridecodebin, "element-added",
      G_CALLBACK (uridecodebin_element_added_cb), dc, 0);
  tmp = gst_element_factory_make ("decodebin", NULL);
  dc->priv->decodebin_type = G_OBJECT_TYPE (tmp);
  gst_object_unref (tmp);

  /* create queries */
  dc->priv->seeking_query = gst_query_new_seeking (format);
}

static void
discoverer_reset (GstDiscoverer * dc)
{
  GST_DEBUG_OBJECT (dc, "Resetting");

  if (dc->priv->pending_uris) {
    g_list_foreach (dc->priv->pending_uris, (GFunc) g_free, NULL);
    g_list_free (dc->priv->pending_uris);
    dc->priv->pending_uris = NULL;
  }

  if (dc->priv->pipeline)
    gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_NULL);
}

#define DISCONNECT_SIGNAL(o,i) G_STMT_START{           \
  if ((i) && g_signal_handler_is_connected ((o), (i))) \
    g_signal_handler_disconnect ((o), (i));            \
  (i) = 0;                                             \
}G_STMT_END

static void
gst_discoverer_dispose (GObject * obj)
{
  GstDiscoverer *dc = (GstDiscoverer *) obj;

  GST_DEBUG_OBJECT (dc, "Disposing");

  discoverer_reset (dc);

  if (G_LIKELY (dc->priv->pipeline)) {
    /* Workaround for bug #118536 */
    DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_added_id);
    DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->pad_remove_id);
    DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->source_chg_id);
    DISCONNECT_SIGNAL (dc->priv->uridecodebin, dc->priv->element_added_id);
    DISCONNECT_SIGNAL (dc->priv->bus, dc->priv->bus_cb_id);

    /* pipeline was set to NULL in _reset */
    gst_object_unref (dc->priv->pipeline);
    gst_object_unref (dc->priv->bus);

    dc->priv->pipeline = NULL;
    dc->priv->uridecodebin = NULL;
    dc->priv->bus = NULL;
  }

  gst_discoverer_stop (dc);

  if (dc->priv->seeking_query) {
    gst_query_unref (dc->priv->seeking_query);
    dc->priv->seeking_query = NULL;
  }

  G_OBJECT_CLASS (gst_discoverer_parent_class)->dispose (obj);
}

static void
gst_discoverer_finalize (GObject * obj)
{
  GstDiscoverer *dc = (GstDiscoverer *) obj;

  g_mutex_clear (&dc->priv->lock);

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

static void
gst_discoverer_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDiscoverer *dc = (GstDiscoverer *) object;

  switch (prop_id) {
    case PROP_TIMEOUT:
      gst_discoverer_set_timeout (dc, g_value_get_uint64 (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_discoverer_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstDiscoverer *dc = (GstDiscoverer *) object;

  switch (prop_id) {
    case PROP_TIMEOUT:
      DISCO_LOCK (dc);
      g_value_set_uint64 (value, dc->priv->timeout);
      DISCO_UNLOCK (dc);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_discoverer_set_timeout (GstDiscoverer * dc, GstClockTime timeout)
{
  GST_DEBUG_OBJECT (dc, "timeout : %" GST_TIME_FORMAT, GST_TIME_ARGS (timeout));

  /* FIXME : update current pending timeout if we're running */
  DISCO_LOCK (dc);
  dc->priv->timeout = timeout;
  DISCO_UNLOCK (dc);
}

static GstPadProbeReturn
_event_probe (GstPad * pad, GstPadProbeInfo * info, PrivateStream * ps)
{
  GstEvent *event = GST_PAD_PROBE_INFO_EVENT (info);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TAG:{
      GstTagList *tl = NULL, *tmp;

      gst_event_parse_tag (event, &tl);
      GST_DEBUG_OBJECT (pad, "tags %" GST_PTR_FORMAT, tl);
      DISCO_LOCK (ps->dc);
      /* If preroll is complete, drop these tags - the collected information is
       * possibly already being processed and adding more tags would be racy */
      if (G_LIKELY (ps->dc->priv->processing)) {
        GST_DEBUG_OBJECT (pad, "private stream %p old tags %" GST_PTR_FORMAT,
            ps, ps->tags);
        tmp = gst_tag_list_merge (ps->tags, tl, GST_TAG_MERGE_APPEND);
        if (ps->tags)
          gst_tag_list_unref (ps->tags);
        ps->tags = tmp;
        GST_DEBUG_OBJECT (pad, "private stream %p new tags %" GST_PTR_FORMAT,
            ps, tmp);
      } else
        GST_DEBUG_OBJECT (pad, "Dropping tags since preroll is done");
      DISCO_UNLOCK (ps->dc);
      break;
    }
    case GST_EVENT_TOC:{
      GstToc *tmp;

      gst_event_parse_toc (event, &tmp, NULL);
      GST_DEBUG_OBJECT (pad, "toc %" GST_PTR_FORMAT, tmp);
      DISCO_LOCK (ps->dc);
      ps->toc = tmp;
      if (G_LIKELY (ps->dc->priv->processing)) {
        GST_DEBUG_OBJECT (pad, "private stream %p toc %" GST_PTR_FORMAT, ps,
            tmp);
      } else
        GST_DEBUG_OBJECT (pad, "Dropping toc since preroll is done");
      DISCO_UNLOCK (ps->dc);
      break;
    }
    case GST_EVENT_STREAM_START:{
      const gchar *stream_id;

      gst_event_parse_stream_start (event, &stream_id);

      g_free (ps->stream_id);
      ps->stream_id = stream_id ? g_strdup (stream_id) : NULL;
      break;
    }
    default:
      break;
  }

  return GST_PAD_PROBE_OK;
}

static GstStaticCaps subtitle_caps = GST_STATIC_CAPS ("text/x-raw; "
    "subpicture/x-pgs; subpicture/x-dvb; subpicture/x-dvd; "
    "application/x-subtitle-unknown; application/x-ssa; application/x-ass; "
    "subtitle/x-kate; application/x-kate; subpicture/x-xsub");

static gboolean
is_subtitle_caps (const GstCaps * caps)
{
  GstCaps *subs_caps;
  gboolean ret;

  subs_caps = gst_static_caps_get (&subtitle_caps);
  ret = gst_caps_can_intersect (caps, subs_caps);
  gst_caps_unref (subs_caps);

  return ret;
}

static GstPadProbeReturn
got_subtitle_data (GstPad * pad, GstPadProbeInfo * info, GstDiscoverer * dc)
{

  if (!(GST_IS_BUFFER (info->data) || (GST_IS_EVENT (info->data)
              && GST_EVENT_TYPE ((GstEvent *) info->data) == GST_EVENT_GAP)))
    return GST_PAD_PROBE_OK;


  DISCO_LOCK (dc);

  dc->priv->pending_subtitle_pads--;

  if (dc->priv->pending_subtitle_pads == 0) {
    GstMessage *msg = gst_message_new_application (NULL,
        gst_structure_new_empty ("DiscovererDone"));
    gst_element_post_message ((GstElement *) dc->priv->pipeline, msg);
  }
  DISCO_UNLOCK (dc);

  return GST_PAD_PROBE_REMOVE;

}

static void
uridecodebin_source_changed_cb (GstElement * uridecodebin,
    GParamSpec * pspec, GstDiscoverer * dc)
{
  GstElement *src;
  /* get a handle to the source */
  g_object_get (uridecodebin, pspec->name, &src, NULL);

  GST_DEBUG_OBJECT (dc, "got a new source %p", src);

  g_signal_emit (dc, gst_discoverer_signals[SIGNAL_SOURCE_SETUP], 0, src);
  gst_object_unref (src);
}

static void
uridecodebin_pad_added_cb (GstElement * uridecodebin, GstPad * pad,
    GstDiscoverer * dc)
{
  PrivateStream *ps;
  GstPad *sinkpad = NULL;
  GstCaps *caps;

  GST_DEBUG_OBJECT (dc, "pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  ps = g_slice_new0 (PrivateStream);

  ps->dc = dc;
  ps->pad = pad;
  ps->queue = gst_element_factory_make ("queue", NULL);
  ps->sink = gst_element_factory_make ("fakesink", NULL);

  if (G_UNLIKELY (ps->queue == NULL || ps->sink == NULL))
    goto error;

  g_object_set (ps->sink, "silent", TRUE, NULL);
  g_object_set (ps->queue, "max-size-buffers", 1, "silent", TRUE, NULL);

  caps = gst_pad_query_caps (pad, NULL);

  sinkpad = gst_element_get_static_pad (ps->queue, "sink");
  if (sinkpad == NULL)
    goto error;

  if (is_subtitle_caps (caps)) {
    /* Subtitle streams are sparse and may not provide any information - don't
     * wait for data to preroll */
    gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM,
        (GstPadProbeCallback) got_subtitle_data, dc, NULL);
    g_object_set (ps->sink, "async", FALSE, NULL);
    DISCO_LOCK (dc);
    dc->priv->pending_subtitle_pads++;
    DISCO_UNLOCK (dc);
  }

  gst_caps_unref (caps);

  gst_bin_add_many (dc->priv->pipeline, ps->queue, ps->sink, NULL);

  if (!gst_element_link_pads_full (ps->queue, "src", ps->sink, "sink",
          GST_PAD_LINK_CHECK_NOTHING))
    goto error;
  if (!gst_element_sync_state_with_parent (ps->sink))
    goto error;
  if (!gst_element_sync_state_with_parent (ps->queue))
    goto error;

  if (gst_pad_link_full (pad, sinkpad,
          GST_PAD_LINK_CHECK_NOTHING) != GST_PAD_LINK_OK)
    goto error;
  gst_object_unref (sinkpad);

  /* Add an event probe */
  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
      (GstPadProbeCallback) _event_probe, ps, NULL);

  DISCO_LOCK (dc);
  dc->priv->streams = g_list_append (dc->priv->streams, ps);
  DISCO_UNLOCK (dc);

  GST_DEBUG_OBJECT (dc, "Done handling pad");

  return;

error:
  GST_ERROR_OBJECT (dc, "Error while handling pad");
  if (sinkpad)
    gst_object_unref (sinkpad);
  if (ps->queue)
    gst_object_unref (ps->queue);
  if (ps->sink)
    gst_object_unref (ps->sink);
  g_slice_free (PrivateStream, ps);
  return;
}

static void
uridecodebin_pad_removed_cb (GstElement * uridecodebin, GstPad * pad,
    GstDiscoverer * dc)
{
  GList *tmp;
  PrivateStream *ps;
  GstPad *sinkpad;

  GST_DEBUG_OBJECT (dc, "pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  /* Find the PrivateStream */
  DISCO_LOCK (dc);
  for (tmp = dc->priv->streams; tmp; tmp = tmp->next) {
    ps = (PrivateStream *) tmp->data;
    if (ps->pad == pad)
      break;
  }

  if (tmp == NULL) {
    DISCO_UNLOCK (dc);
    GST_DEBUG ("The removed pad wasn't controlled by us !");
    return;
  }

  dc->priv->streams = g_list_delete_link (dc->priv->streams, tmp);
  DISCO_UNLOCK (dc);

  gst_element_set_state (ps->sink, GST_STATE_NULL);
  gst_element_set_state (ps->queue, GST_STATE_NULL);
  gst_element_unlink (ps->queue, ps->sink);

  sinkpad = gst_element_get_static_pad (ps->queue, "sink");
  gst_pad_unlink (pad, sinkpad);
  gst_object_unref (sinkpad);

  /* references removed here */
  gst_bin_remove_many (dc->priv->pipeline, ps->sink, ps->queue, NULL);

  if (ps->tags) {
    gst_tag_list_unref (ps->tags);
  }
  if (ps->toc) {
    gst_toc_unref (ps->toc);
  }
  g_free (ps->stream_id);

  g_slice_free (PrivateStream, ps);

  GST_DEBUG ("Done handling pad");
}

static GstStructure *
collect_stream_information (GstDiscoverer * dc, PrivateStream * ps, guint idx)
{
  GstCaps *caps;
  GstStructure *st;
  gchar *stname;

  stname = g_strdup_printf ("stream-%02d", idx);
  st = gst_structure_new_empty (stname);
  g_free (stname);

  /* Get caps */
  caps = gst_pad_get_current_caps (ps->pad);
  if (!caps) {
    GST_WARNING ("Couldn't get negotiated caps from %s:%s",
        GST_DEBUG_PAD_NAME (ps->pad));
    caps = gst_pad_query_caps (ps->pad, NULL);
  }
  if (caps) {
    GST_DEBUG ("stream-%02d, got caps %" GST_PTR_FORMAT, idx, caps);
    gst_structure_id_set (st, _CAPS_QUARK, GST_TYPE_CAPS, caps, NULL);
    gst_caps_unref (caps);
  }
  if (ps->tags)
    gst_structure_id_set (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, ps->tags, NULL);
  if (ps->toc)
    gst_structure_id_set (st, _TOC_QUARK, GST_TYPE_TOC, ps->toc, NULL);
  if (ps->stream_id)
    gst_structure_id_set (st, _STREAM_ID_QUARK, G_TYPE_STRING, ps->stream_id,
        NULL);

  return st;
}

/* takes ownership of new_tags, may replace *taglist with a new one */
static void
gst_discoverer_merge_and_replace_tags (GstTagList ** taglist,
    GstTagList * new_tags)
{
  if (new_tags == NULL)
    return;

  if (*taglist == NULL) {
    *taglist = new_tags;
    return;
  }

  gst_tag_list_insert (*taglist, new_tags, GST_TAG_MERGE_REPLACE);
  gst_tag_list_unref (new_tags);
}

static void
collect_common_information (GstDiscovererStreamInfo * info,
    const GstStructure * st)
{
  if (gst_structure_id_has_field (st, _TOC_QUARK)) {
    gst_structure_id_get (st, _TOC_QUARK, GST_TYPE_TOC, &info->toc, NULL);
  }

  if (gst_structure_id_has_field (st, _STREAM_ID_QUARK)) {
    gst_structure_id_get (st, _STREAM_ID_QUARK, G_TYPE_STRING, &info->stream_id,
        NULL);
  }
}

static GstDiscovererStreamInfo *
make_info (GstDiscovererStreamInfo * parent, GType type, GstCaps * caps)
{
  GstDiscovererStreamInfo *info;

  if (parent)
    info = gst_discoverer_stream_info_ref (parent);
  else {
    info = g_object_new (type, NULL);
    if (caps)
      info->caps = gst_caps_ref (caps);
  }
  return info;
}

/* Parses a set of caps and tags in st and populates a GstDiscovererStreamInfo
 * structure (parent, if !NULL, otherwise it allocates one)
 */
static GstDiscovererStreamInfo *
collect_information (GstDiscoverer * dc, const GstStructure * st,
    GstDiscovererStreamInfo * parent)
{
  GstCaps *caps;
  GstStructure *caps_st;
  GstTagList *tags_st;
  const gchar *name;
  int tmp;
  guint utmp;

  if (!st || !gst_structure_id_has_field (st, _CAPS_QUARK)) {
    GST_WARNING ("Couldn't find caps !");
    return make_info (parent, GST_TYPE_DISCOVERER_STREAM_INFO, NULL);
  }

  gst_structure_id_get (st, _CAPS_QUARK, GST_TYPE_CAPS, &caps, NULL);
  caps_st = gst_caps_get_structure (caps, 0);
  name = gst_structure_get_name (caps_st);

  if (g_str_has_prefix (name, "audio/")) {
    GstDiscovererAudioInfo *info;
    const gchar *format_str;

    info = (GstDiscovererAudioInfo *) make_info (parent,
        GST_TYPE_DISCOVERER_AUDIO_INFO, caps);

    if (gst_structure_get_int (caps_st, "rate", &tmp))
      info->sample_rate = (guint) tmp;

    if (gst_structure_get_int (caps_st, "channels", &tmp))
      info->channels = (guint) tmp;

    /* FIXME: we only want to extract depth if raw audio is what's in the
     * container (i.e. not if there is a decoder involved) */
    format_str = gst_structure_get_string (caps_st, "format");
    if (format_str != NULL) {
      const GstAudioFormatInfo *finfo;
      GstAudioFormat format;

      format = gst_audio_format_from_string (format_str);
      finfo = gst_audio_format_get_info (format);
      info->depth = GST_AUDIO_FORMAT_INFO_DEPTH (finfo);
    }

    if (gst_structure_id_has_field (st, _TAGS_QUARK)) {
      gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, &tags_st, NULL);
      if (gst_tag_list_get_uint (tags_st, GST_TAG_BITRATE, &utmp) ||
          gst_tag_list_get_uint (tags_st, GST_TAG_NOMINAL_BITRATE, &utmp))
        info->bitrate = utmp;

      if (gst_tag_list_get_uint (tags_st, GST_TAG_MAXIMUM_BITRATE, &utmp))
        info->max_bitrate = utmp;

      /* FIXME: Is it worth it to remove the tags we've parsed? */
      gst_discoverer_merge_and_replace_tags (&info->parent.tags, tags_st);
    }

    collect_common_information (&info->parent, st);

    if (!info->language && ((GstDiscovererStreamInfo *) info)->tags) {
      gchar *language;
      if (gst_tag_list_get_string (((GstDiscovererStreamInfo *) info)->tags,
              GST_TAG_LANGUAGE_CODE, &language)) {
        info->language = language;
      }
    }

    gst_caps_unref (caps);
    return (GstDiscovererStreamInfo *) info;

  } else if (g_str_has_prefix (name, "video/") ||
      g_str_has_prefix (name, "image/")) {
    GstDiscovererVideoInfo *info;
    GstVideoInfo vinfo;

    info = (GstDiscovererVideoInfo *) make_info (parent,
        GST_TYPE_DISCOVERER_VIDEO_INFO, caps);

    if (gst_video_info_from_caps (&vinfo, caps)) {
      info->width = (guint) vinfo.width;
      info->height = (guint) vinfo.height;

      info->depth = vinfo.finfo->bits * vinfo.finfo->n_components;

      info->par_num = vinfo.par_n;
      info->par_denom = vinfo.par_d;

      info->framerate_num = vinfo.fps_n;
      info->framerate_denom = vinfo.fps_d;

      info->interlaced =
          vinfo.interlace_mode != GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
    }

    if (gst_structure_id_has_field (st, _TAGS_QUARK)) {
      gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, &tags_st, NULL);
      if (gst_tag_list_get_uint (tags_st, GST_TAG_BITRATE, &utmp) ||
          gst_tag_list_get_uint (tags_st, GST_TAG_NOMINAL_BITRATE, &utmp))
        info->bitrate = utmp;

      if (gst_tag_list_get_uint (tags_st, GST_TAG_MAXIMUM_BITRATE, &utmp))
        info->max_bitrate = utmp;

      /* FIXME: Is it worth it to remove the tags we've parsed? */
      gst_discoverer_merge_and_replace_tags (&info->parent.tags, tags_st);
    }

    collect_common_information (&info->parent, st);

    gst_caps_unref (caps);
    return (GstDiscovererStreamInfo *) info;

  } else if (is_subtitle_caps (caps)) {
    GstDiscovererSubtitleInfo *info;

    info = (GstDiscovererSubtitleInfo *) make_info (parent,
        GST_TYPE_DISCOVERER_SUBTITLE_INFO, caps);

    if (gst_structure_id_has_field (st, _TAGS_QUARK)) {
      const gchar *language;

      gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, &tags_st, NULL);

      language = gst_structure_get_string (caps_st, GST_TAG_LANGUAGE_CODE);
      if (language)
        info->language = g_strdup (language);

      /* FIXME: Is it worth it to remove the tags we've parsed? */
      gst_discoverer_merge_and_replace_tags (&info->parent.tags, tags_st);
    }

    collect_common_information (&info->parent, st);

    if (!info->language && ((GstDiscovererStreamInfo *) info)->tags) {
      gchar *language;
      if (gst_tag_list_get_string (((GstDiscovererStreamInfo *) info)->tags,
              GST_TAG_LANGUAGE_CODE, &language)) {
        info->language = language;
      }
    }

    gst_caps_unref (caps);
    return (GstDiscovererStreamInfo *) info;

  } else {
    /* None of the above - populate what information we can */
    GstDiscovererStreamInfo *info;

    info = make_info (parent, GST_TYPE_DISCOVERER_STREAM_INFO, caps);

    if (gst_structure_id_get (st, _TAGS_QUARK, GST_TYPE_TAG_LIST, &tags_st,
            NULL)) {
      gst_discoverer_merge_and_replace_tags (&info->tags, tags_st);
    }

    collect_common_information (info, st);

    gst_caps_unref (caps);
    return info;
  }

}

static GstStructure *
find_stream_for_node (GstDiscoverer * dc, const GstStructure * topology)
{
  GstPad *pad;
  GstPad *target_pad = NULL;
  GstStructure *st = NULL;
  PrivateStream *ps;
  guint i;
  GList *tmp;

  if (!dc->priv->streams) {
    return NULL;
  }

  if (!gst_structure_id_has_field (topology, _TOPOLOGY_PAD_QUARK)) {
    GST_DEBUG ("Could not find pad for node %" GST_PTR_FORMAT, topology);
    return NULL;
  }

  gst_structure_id_get (topology, _TOPOLOGY_PAD_QUARK,
      GST_TYPE_PAD, &pad, NULL);

  for (i = 0, tmp = dc->priv->streams; tmp; tmp = tmp->next, i++) {
    ps = (PrivateStream *) tmp->data;

    target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (ps->pad));
    gst_object_unref (target_pad);

    if (target_pad == pad)
      break;
  }

  if (tmp)
    st = collect_stream_information (dc, ps, i);

  gst_object_unref (pad);

  return st;
}

/* this can fail due to {framed,parsed}={TRUE,FALSE} differences, thus we filter
 * the parent */
static gboolean
child_is_same_stream (const GstCaps * _parent, const GstCaps * child)
{
  GstCaps *parent = gst_caps_copy (_parent);
  guint i, size = gst_caps_get_size (parent);
  gboolean res;

  for (i = 0; i < size; i++) {
    gst_structure_remove_field (gst_caps_get_structure (parent, i), "parsed");
    gst_structure_remove_field (gst_caps_get_structure (parent, i), "framed");
  }
  res = gst_caps_can_intersect (parent, child);
  gst_caps_unref (parent);
  return res;
}


static gboolean
child_is_raw_stream (const GstCaps * parent, const GstCaps * child)
{
  const GstStructure *st1, *st2;
  const gchar *name1, *name2;

  st1 = gst_caps_get_structure (parent, 0);
  name1 = gst_structure_get_name (st1);
  st2 = gst_caps_get_structure (child, 0);
  name2 = gst_structure_get_name (st2);

  if ((g_str_has_prefix (name1, "audio/") &&
          g_str_has_prefix (name2, "audio/x-raw")) ||
      ((g_str_has_prefix (name1, "video/") ||
              g_str_has_prefix (name1, "image/")) &&
          g_str_has_prefix (name2, "video/x-raw"))) {
    /* child is the "raw" sub-stream corresponding to parent */
    return TRUE;
  }

  if (is_subtitle_caps (parent))
    return TRUE;

  return FALSE;
}

/* If a parent is non-NULL, collected stream information will be appended to it
 * (and where the information exists, it will be overriden)
 */
static GstDiscovererStreamInfo *
parse_stream_topology (GstDiscoverer * dc, const GstStructure * topology,
    GstDiscovererStreamInfo * parent)
{
  GstDiscovererStreamInfo *res = NULL;
  GstCaps *caps = NULL;
  const GValue *nval = NULL;

  GST_DEBUG ("parsing: %" GST_PTR_FORMAT, topology);

  nval = gst_structure_get_value (topology, "next");

  if (nval == NULL || GST_VALUE_HOLDS_STRUCTURE (nval)) {
    GstStructure *st = find_stream_for_node (dc, topology);
    gboolean add_to_list = TRUE;

    if (st) {
      res = collect_information (dc, st, parent);
      gst_structure_free (st);
    } else {
      /* Didn't find a stream structure, so let's just use the caps we have */
      res = collect_information (dc, topology, parent);
    }

    if (nval == NULL) {
      /* FIXME : aggregate with information from main streams */
      GST_DEBUG ("Coudn't find 'next' ! might be the last entry");
    } else {
      st = (GstStructure *) gst_value_get_structure (nval);

      GST_DEBUG ("next is a structure %" GST_PTR_FORMAT, st);

      if (!parent)
        parent = res;

      if (gst_structure_id_get (st, _CAPS_QUARK, GST_TYPE_CAPS, &caps, NULL)) {
        if (child_is_same_stream (parent->caps, caps)) {
          /* We sometimes get an extra sub-stream from the parser. If this is
           * the case, we just replace the parent caps with this stream's caps
           * since they might contain more information */
          gst_caps_replace (&parent->caps, caps);

          parse_stream_topology (dc, st, parent);
          add_to_list = FALSE;
        } else if (child_is_raw_stream (parent->caps, caps)) {
          /* This is the "raw" stream corresponding to the parent. This
           * contains more information than the parent, tags etc. */
          parse_stream_topology (dc, st, parent);
          add_to_list = FALSE;
        } else {
          GstDiscovererStreamInfo *next = parse_stream_topology (dc, st, NULL);
          res->next = next;
          next->previous = res;
        }
        gst_caps_unref (caps);
      }
    }

    if (add_to_list) {
      dc->priv->current_info->stream_list =
          g_list_append (dc->priv->current_info->stream_list, res);
    } else {
      gst_discoverer_stream_info_unref (res);
    }

  } else if (GST_VALUE_HOLDS_LIST (nval)) {
    guint i, len;
    GstDiscovererContainerInfo *cont;
    GstTagList *tags;

    if (!gst_structure_id_get (topology, _CAPS_QUARK,
            GST_TYPE_CAPS, &caps, NULL))
      GST_WARNING ("Couldn't find caps !");

    len = gst_value_list_get_size (nval);
    GST_DEBUG ("next is a list of %d entries", len);

    cont = (GstDiscovererContainerInfo *)
        g_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO, NULL);
    cont->parent.caps = caps;
    res = (GstDiscovererStreamInfo *) cont;

    if (gst_structure_id_has_field (topology, _TAGS_QUARK)) {
      GstTagList *tmp;

      gst_structure_id_get (topology, _TAGS_QUARK,
          GST_TYPE_TAG_LIST, &tags, NULL);

      GST_DEBUG ("Merge tags %" GST_PTR_FORMAT, tags);

      tmp =
          gst_tag_list_merge (cont->parent.tags, (GstTagList *) tags,
          GST_TAG_MERGE_APPEND);
      gst_tag_list_unref (tags);
      if (cont->parent.tags)
        gst_tag_list_unref (cont->parent.tags);
      cont->parent.tags = tmp;
      GST_DEBUG ("Container info tags %" GST_PTR_FORMAT, tmp);
    }

    for (i = 0; i < len; i++) {
      const GValue *subv = gst_value_list_get_value (nval, i);
      const GstStructure *subst = gst_value_get_structure (subv);
      GstDiscovererStreamInfo *substream;

      GST_DEBUG ("%d %" GST_PTR_FORMAT, i, subst);

      substream = parse_stream_topology (dc, subst, NULL);

      substream->previous = res;
      cont->streams =
          g_list_append (cont->streams,
          gst_discoverer_stream_info_ref (substream));
    }
  }

  return res;
}

/* Called when pipeline is pre-rolled */
static void
discoverer_collect (GstDiscoverer * dc)
{
  GST_DEBUG ("Collecting information");

  /* Stop the timeout handler if present */
  if (dc->priv->timeoutid) {
    g_source_remove (dc->priv->timeoutid);
    dc->priv->timeoutid = 0;
  }

  if (dc->priv->streams) {
    /* FIXME : Make this querying optional */
    if (TRUE) {
      GstElement *pipeline = (GstElement *) dc->priv->pipeline;
      gint64 dur;

      GST_DEBUG ("Attempting to query duration");

      if (gst_element_query_duration (pipeline, GST_FORMAT_TIME, &dur)) {
        GST_DEBUG ("Got duration %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
        dc->priv->current_info->duration = (guint64) dur;
      } else {
        GstStateChangeReturn sret;

        /* Some parsers may not even return a rough estimate right away, e.g.
         * because they've only processed a single frame so far, so if we
         * didn't get a duration the first time, spin a bit and try again.
         * Ugly, but still better than making parsers or other elements return
         * completely bogus values. We need some API extensions to solve this
         * better. */
        GST_INFO ("No duration yet, try a bit harder..");
        sret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
        if (sret != GST_STATE_CHANGE_FAILURE) {
          int i;

          for (i = 0; i < 2; ++i) {
            g_usleep (G_USEC_PER_SEC / 20);
            if (gst_element_query_duration (pipeline, GST_FORMAT_TIME, &dur)
                && dur > 0) {
              GST_DEBUG ("Got duration %" GST_TIME_FORMAT, GST_TIME_ARGS (dur));
              dc->priv->current_info->duration = (guint64) dur;
              break;
            }
          }
          gst_element_set_state (pipeline, GST_STATE_PAUSED);
        }
      }

      if (dc->priv->seeking_query) {
        if (gst_element_query (pipeline, dc->priv->seeking_query)) {
          GstFormat format;
          gboolean seekable;

          gst_query_parse_seeking (dc->priv->seeking_query, &format,
              &seekable, NULL, NULL);
          if (format == GST_FORMAT_TIME) {
            GST_DEBUG ("Got seekable %d", seekable);
            dc->priv->current_info->seekable = seekable;
          }
        }
      }
    }

    if (dc->priv->current_topology)
      dc->priv->current_info->stream_info = parse_stream_topology (dc,
          dc->priv->current_topology, NULL);

    /*
     * Images need some special handling. They do not have a duration, have
     * caps named image/<foo> (th exception being MJPEG video which is also
     * type image/jpeg), and should consist of precisely one stream (actually
     * initially there are 2, the image and raw stream, but we squash these
     * while parsing the stream topology). At some point, if we find that these
     * conditions are not sufficient, we can count the number of decoders and
     * parsers in the chain, and if there's more than one decoder, or any
     * parser at all, we should not mark this as an image.
     */
    if (dc->priv->current_info->duration == 0 &&
        dc->priv->current_info->stream_info != NULL &&
        dc->priv->current_info->stream_info->next == NULL) {
      GstDiscovererStreamInfo *stream_info;
      GstStructure *st;

      stream_info = dc->priv->current_info->stream_info;
      st = gst_caps_get_structure (stream_info->caps, 0);

      if (g_str_has_prefix (gst_structure_get_name (st), "image/"))
        ((GstDiscovererVideoInfo *) stream_info)->is_image = TRUE;
    }
  }

  if (dc->priv->async) {
    GST_DEBUG ("Emitting 'discoverered'");
    g_signal_emit (dc, gst_discoverer_signals[SIGNAL_DISCOVERED], 0,
        dc->priv->current_info, dc->priv->current_error);
    /* Clients get a copy of current_info since it is a boxed type */
    gst_discoverer_info_unref (dc->priv->current_info);
    dc->priv->current_info = NULL;
  }
}

static void
get_async_cb (gpointer cb_data, GSource * source, GSourceFunc * func,
    gpointer * data)
{
  *func = (GSourceFunc) async_timeout_cb;
  *data = cb_data;
}

/* Wrapper since GSourceCallbackFuncs don't expect a return value from ref() */
static void
_void_g_object_ref (gpointer object)
{
  g_object_ref (G_OBJECT (object));
}

static void
handle_current_async (GstDiscoverer * dc)
{
  GSource *source;
  static GSourceCallbackFuncs cb_funcs = {
    _void_g_object_ref,
    g_object_unref,
    get_async_cb,
  };

  /* Attach a timeout to the main context */
  source = g_timeout_source_new (dc->priv->timeout / GST_MSECOND);
  g_source_set_callback_indirect (source, g_object_ref (dc), &cb_funcs);
  dc->priv->timeoutid = g_source_attach (source, dc->priv->ctx);
  g_source_unref (source);
}


/* Returns TRUE if processing should stop */
static gboolean
handle_message (GstDiscoverer * dc, GstMessage * msg)
{
  gboolean done = FALSE;

  GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "got a %s message",
      GST_MESSAGE_TYPE_NAME (msg));

  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_ERROR:{
      GError *gerr;
      gchar *debug;

      gst_message_parse_error (msg, &gerr, &debug);
      GST_WARNING_OBJECT (GST_MESSAGE_SRC (msg),
          "Got an error [debug:%s], [message:%s]", debug, gerr->message);
      dc->priv->current_error = gerr;
      g_free (debug);

      /* We need to stop */
      done = TRUE;

      /* Don't override missing plugin result code for missing plugin errors */
      if (dc->priv->current_info->result != GST_DISCOVERER_MISSING_PLUGINS ||
          (!g_error_matches (gerr, GST_CORE_ERROR,
                  GST_CORE_ERROR_MISSING_PLUGIN) &&
              !g_error_matches (gerr, GST_STREAM_ERROR,
                  GST_STREAM_ERROR_CODEC_NOT_FOUND))) {
        GST_DEBUG ("Setting result to ERROR");
        dc->priv->current_info->result = GST_DISCOVERER_ERROR;
      }
    }
      break;

    case GST_MESSAGE_EOS:
      GST_DEBUG ("Got EOS !");
      done = TRUE;
      break;

    case GST_MESSAGE_APPLICATION:{
      const gchar *name;
      gboolean async_done;
      name = gst_structure_get_name (gst_message_get_structure (msg));
      /* Maybe ASYNC_DONE is received & we're just waiting for subtitle tags */
      DISCO_LOCK (dc);
      async_done = dc->priv->async_done;
      DISCO_UNLOCK (dc);
      if (g_str_equal (name, "DiscovererDone") && async_done)
        return TRUE;
      break;
    }

    case GST_MESSAGE_ASYNC_DONE:
      if (GST_MESSAGE_SRC (msg) == (GstObject *) dc->priv->pipeline) {
        GST_DEBUG ("Finished changing state asynchronously");
        DISCO_LOCK (dc);
        if (dc->priv->pending_subtitle_pads == 0) {
          done = TRUE;
        } else {
          /* Remember that ASYNC_DONE has been received, wait for subtitles */
          dc->priv->async_done = TRUE;
        }
        DISCO_UNLOCK (dc);

      }
      break;

    case GST_MESSAGE_ELEMENT:
    {
      GQuark sttype;
      const GstStructure *structure;

      structure = gst_message_get_structure (msg);
      sttype = gst_structure_get_name_id (structure);
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg),
          "structure %" GST_PTR_FORMAT, structure);
      if (sttype == _MISSING_PLUGIN_QUARK) {
        GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg),
            "Setting result to MISSING_PLUGINS");
        dc->priv->current_info->result = GST_DISCOVERER_MISSING_PLUGINS;
        /* FIXME 2.0 Remove completely the ->misc
         * Keep the old behaviour for now.
         */
        if (dc->priv->current_info->misc)
          gst_structure_free (dc->priv->current_info->misc);
        g_ptr_array_add (dc->priv->current_info->missing_elements_details,
            gst_missing_plugin_message_get_installer_detail (msg));
      } else if (sttype == _STREAM_TOPOLOGY_QUARK) {
        if (dc->priv->current_topology)
          gst_structure_free (dc->priv->current_topology);
        dc->priv->current_topology = gst_structure_copy (structure);
      }
    }
      break;

    case GST_MESSAGE_TAG:
    {
      GstTagList *tl, *tmp;

      gst_message_parse_tag (msg, &tl);
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Got tags %" GST_PTR_FORMAT, tl);
      /* Merge with current tags */
      tmp =
          gst_tag_list_merge (dc->priv->current_info->tags, tl,
          GST_TAG_MERGE_APPEND);
      gst_tag_list_unref (tl);
      if (dc->priv->current_info->tags)
        gst_tag_list_unref (dc->priv->current_info->tags);
      dc->priv->current_info->tags = tmp;
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Current info %p, tags %"
          GST_PTR_FORMAT, dc->priv->current_info, tmp);
    }
      break;

    case GST_MESSAGE_TOC:
    {
      GstToc *tmp;

      gst_message_parse_toc (msg, &tmp, NULL);
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Got toc %" GST_PTR_FORMAT, tmp);
      if (dc->priv->current_info->toc)
        gst_toc_unref (dc->priv->current_info->toc);
      dc->priv->current_info->toc = tmp;        /* transfer ownership */
      GST_DEBUG_OBJECT (GST_MESSAGE_SRC (msg), "Current info %p, toc %"
          GST_PTR_FORMAT, dc->priv->current_info, tmp);
    }
      break;

    default:
      break;
  }

  return done;
}

static void
handle_current_sync (GstDiscoverer * dc)
{
  GTimer *timer;
  gdouble deadline = ((gdouble) dc->priv->timeout) / GST_SECOND;
  GstMessage *msg;
  gboolean done = FALSE;

  timer = g_timer_new ();
  g_timer_start (timer);

  do {
    /* poll bus with timeout */
    /* FIXME : make the timeout more fine-tuned */
    if ((msg = gst_bus_timed_pop (dc->priv->bus, GST_SECOND / 2))) {
      done = handle_message (dc, msg);
      gst_message_unref (msg);
    }
  } while (!done && (g_timer_elapsed (timer, NULL) < deadline));

  /* return result */
  if (!done) {
    GST_DEBUG ("we timed out! Setting result to TIMEOUT");
    dc->priv->current_info->result = GST_DISCOVERER_TIMEOUT;
  }

  DISCO_LOCK (dc);
  dc->priv->processing = FALSE;
  DISCO_UNLOCK (dc);


  GST_DEBUG ("Done");

  g_timer_stop (timer);
  g_timer_destroy (timer);
}

static void
_setup_locked (GstDiscoverer * dc)
{
  GstStateChangeReturn ret;

  GST_DEBUG ("Setting up");

  /* Pop URI off the pending URI list */
  dc->priv->current_info =
      (GstDiscovererInfo *) g_object_new (GST_TYPE_DISCOVERER_INFO, NULL);
  dc->priv->current_info->uri = (gchar *) dc->priv->pending_uris->data;
  dc->priv->pending_uris =
      g_list_delete_link (dc->priv->pending_uris, dc->priv->pending_uris);

  /* set uri on uridecodebin */
  g_object_set (dc->priv->uridecodebin, "uri", dc->priv->current_info->uri,
      NULL);

  GST_DEBUG ("Current is now %s", dc->priv->current_info->uri);

  dc->priv->processing = TRUE;

  /* set pipeline to PAUSED */
  DISCO_UNLOCK (dc);
  GST_DEBUG ("Setting pipeline to PAUSED");
  ret =
      gst_element_set_state ((GstElement *) dc->priv->pipeline,
      GST_STATE_PAUSED);
  if (ret == GST_STATE_CHANGE_NO_PREROLL) {
    GST_DEBUG ("Source is live, switching to PLAYING");
    ret =
        gst_element_set_state ((GstElement *) dc->priv->pipeline,
        GST_STATE_PLAYING);
  }
  DISCO_LOCK (dc);

  GST_DEBUG_OBJECT (dc, "Pipeline going to PAUSED : %s",
      gst_element_state_change_return_get_name (ret));
}

static void
discoverer_cleanup (GstDiscoverer * dc)
{
  GST_DEBUG ("Cleaning up");

  gst_bus_set_flushing (dc->priv->bus, TRUE);

  DISCO_LOCK (dc);
  if (dc->priv->current_error) {
    g_error_free (dc->priv->current_error);
    DISCO_UNLOCK (dc);
    gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_NULL);
  } else {
    DISCO_UNLOCK (dc);
  }

  gst_element_set_state ((GstElement *) dc->priv->pipeline, GST_STATE_READY);
  gst_bus_set_flushing (dc->priv->bus, FALSE);

  DISCO_LOCK (dc);
  dc->priv->current_error = NULL;
  if (dc->priv->current_topology) {
    gst_structure_free (dc->priv->current_topology);
    dc->priv->current_topology = NULL;
  }

  dc->priv->current_info = NULL;

  dc->priv->pending_subtitle_pads = 0;
  dc->priv->async_done = FALSE;

  /* Try popping the next uri */
  if (dc->priv->async) {
    if (dc->priv->pending_uris != NULL) {
      _setup_locked (dc);
      DISCO_UNLOCK (dc);
      /* Start timeout */
      handle_current_async (dc);
    } else {
      /* We're done ! */
      DISCO_UNLOCK (dc);
      g_signal_emit (dc, gst_discoverer_signals[SIGNAL_FINISHED], 0);
    }
  } else
    DISCO_UNLOCK (dc);

  GST_DEBUG ("out");
}

static void
discoverer_bus_cb (GstBus * bus, GstMessage * msg, GstDiscoverer * dc)
{
  if (dc->priv->processing) {
    if (handle_message (dc, msg)) {
      GST_DEBUG ("Stopping asynchronously");
      /* Serialise with _event_probe() */
      DISCO_LOCK (dc);
      dc->priv->processing = FALSE;
      DISCO_UNLOCK (dc);
      discoverer_collect (dc);
      discoverer_cleanup (dc);
    }
  }
}

static gboolean
async_timeout_cb (GstDiscoverer * dc)
{
  if (!g_source_is_destroyed (g_main_current_source ())) {
    dc->priv->timeoutid = 0;
    GST_DEBUG ("Setting result to TIMEOUT");
    dc->priv->current_info->result = GST_DISCOVERER_TIMEOUT;
    dc->priv->processing = FALSE;
    discoverer_collect (dc);
    discoverer_cleanup (dc);
  }
  return FALSE;
}

/* If there is a pending URI, it will pop it from the list of pending
 * URIs and start the discovery on it.
 *
 * Returns GST_DISCOVERER_OK if the next URI was popped and is processing,
 * else a error flag.
 */
static GstDiscovererResult
start_discovering (GstDiscoverer * dc)
{
  GstDiscovererResult res = GST_DISCOVERER_OK;

  GST_DEBUG ("Starting");

  DISCO_LOCK (dc);
  if (dc->priv->pending_uris == NULL) {
    GST_WARNING ("No URI to process");
    res = GST_DISCOVERER_URI_INVALID;
    DISCO_UNLOCK (dc);
    goto beach;
  }

  if (dc->priv->current_info != NULL) {
    GST_WARNING ("Already processing a file");
    res = GST_DISCOVERER_BUSY;
    DISCO_UNLOCK (dc);
    goto beach;
  }

  g_signal_emit (dc, gst_discoverer_signals[SIGNAL_STARTING], 0);

  _setup_locked (dc);

  DISCO_UNLOCK (dc);

  if (dc->priv->async)
    handle_current_async (dc);
  else
    handle_current_sync (dc);

beach:
  return res;
}

/* Serializing code */

static GVariant *
_serialize_common_stream_info (GstDiscovererStreamInfo * sinfo,
    GstDiscovererSerializeFlags flags)
{
  GVariant *common;
  gchar *caps_str = NULL, *tags_str = NULL, *misc_str = NULL;

  if (sinfo->caps && (flags & GST_DISCOVERER_SERIALIZE_CAPS))
    caps_str = gst_caps_to_string (sinfo->caps);

  if (sinfo->tags && (flags & GST_DISCOVERER_SERIALIZE_TAGS))
    tags_str = gst_tag_list_to_string (sinfo->tags);

  if (sinfo->misc && (flags & GST_DISCOVERER_SERIALIZE_MISC))
    misc_str = gst_structure_to_string (sinfo->misc);

  common =
      g_variant_new ("(msmsmsms)", sinfo->stream_id, caps_str, tags_str,
      misc_str);

  g_free (caps_str);
  g_free (tags_str);
  g_free (misc_str);

  return common;
}

static GVariant *
_serialize_info (GstDiscovererInfo * info, GstDiscovererSerializeFlags flags)
{
  gchar *tags_str = NULL;
  GVariant *ret;

  if (info->tags && (flags & GST_DISCOVERER_SERIALIZE_TAGS))
    tags_str = gst_tag_list_to_string (info->tags);

  ret =
      g_variant_new ("(mstbms)", info->uri, info->duration, info->seekable,
      tags_str);

  g_free (tags_str);

  return ret;
}

static GVariant *
_serialize_audio_stream_info (GstDiscovererAudioInfo * ainfo)
{
  return g_variant_new ("(uuuuums)",
      ainfo->channels,
      ainfo->sample_rate,
      ainfo->bitrate, ainfo->max_bitrate, ainfo->depth, ainfo->language);
}

static GVariant *
_serialize_video_stream_info (GstDiscovererVideoInfo * vinfo)
{
  return g_variant_new ("(uuuuuuubuub)",
      vinfo->width,
      vinfo->height,
      vinfo->depth,
      vinfo->framerate_num,
      vinfo->framerate_denom,
      vinfo->par_num,
      vinfo->par_denom,
      vinfo->interlaced, vinfo->bitrate, vinfo->max_bitrate, vinfo->is_image);
}

static GVariant *
_serialize_subtitle_stream_info (GstDiscovererSubtitleInfo * sinfo)
{
  return g_variant_new ("ms", sinfo->language);
}

static GVariant *
gst_discoverer_info_to_variant_recurse (GstDiscovererStreamInfo * sinfo,
    GstDiscovererSerializeFlags flags)
{
  GVariant *stream_variant = NULL;
  GVariant *common_stream_variant =
      _serialize_common_stream_info (sinfo, flags);

  if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
    GList *tmp;
    GList *streams =
        gst_discoverer_container_info_get_streams (GST_DISCOVERER_CONTAINER_INFO
        (sinfo));

    if (g_list_length (streams) > 0) {
      GVariantBuilder children;
      GVariant *child_variant;
      g_variant_builder_init (&children, G_VARIANT_TYPE_ARRAY);

      for (tmp = streams; tmp; tmp = tmp->next) {
        child_variant =
            gst_discoverer_info_to_variant_recurse (tmp->data, flags);
        g_variant_builder_add (&children, "v", child_variant);
      }
      stream_variant =
          g_variant_new ("(yvav)", 'c', common_stream_variant, &children);
    } else {
      stream_variant =
          g_variant_new ("(yvav)", 'c', common_stream_variant, NULL);
    }

    gst_discoverer_stream_info_list_free (streams);
  } else if (GST_IS_DISCOVERER_AUDIO_INFO (sinfo)) {
    GVariant *audio_stream_info =
        _serialize_audio_stream_info (GST_DISCOVERER_AUDIO_INFO (sinfo));
    stream_variant =
        g_variant_new ("(yvv)", 'a', common_stream_variant, audio_stream_info);
  } else if (GST_IS_DISCOVERER_VIDEO_INFO (sinfo)) {
    GVariant *video_stream_info =
        _serialize_video_stream_info (GST_DISCOVERER_VIDEO_INFO (sinfo));
    stream_variant =
        g_variant_new ("(yvv)", 'v', common_stream_variant, video_stream_info);
  } else if (GST_IS_DISCOVERER_SUBTITLE_INFO (sinfo)) {
    GVariant *subtitle_stream_info =
        _serialize_subtitle_stream_info (GST_DISCOVERER_SUBTITLE_INFO (sinfo));
    stream_variant =
        g_variant_new ("(yvv)", 's', common_stream_variant,
        subtitle_stream_info);
  }

  return stream_variant;
}

/* Parsing code */

#define GET_FROM_TUPLE(v, t, n, val) G_STMT_START{         \
  GVariant *child = g_variant_get_child_value (v, n); \
  *val = g_variant_get_##t(child); \
  g_variant_unref (child); \
}G_STMT_END

static const gchar *
_maybe_get_string_from_tuple (GVariant * tuple, guint index)
{
  const gchar *ret = NULL;
  GVariant *maybe;
  GET_FROM_TUPLE (tuple, maybe, index, &maybe);
  if (maybe) {
    ret = g_variant_get_string (maybe, NULL);
    g_variant_unref (maybe);
  }

  return ret;
}

static void
_parse_info (GstDiscovererInfo * info, GVariant * info_variant)
{
  const gchar *str;

  str = _maybe_get_string_from_tuple (info_variant, 0);
  if (str)
    info->uri = g_strdup (str);

  GET_FROM_TUPLE (info_variant, uint64, 1, &info->duration);
  GET_FROM_TUPLE (info_variant, boolean, 2, &info->seekable);

  str = _maybe_get_string_from_tuple (info_variant, 3);
  if (str)
    info->tags = gst_tag_list_new_from_string (str);
}

static void
_parse_common_stream_info (GstDiscovererStreamInfo * sinfo, GVariant * common)
{
  const gchar *str;

  str = _maybe_get_string_from_tuple (common, 0);
  if (str)
    sinfo->stream_id = g_strdup (str);

  str = _maybe_get_string_from_tuple (common, 1);
  if (str)
    sinfo->caps = gst_caps_from_string (str);

  str = _maybe_get_string_from_tuple (common, 2);
  if (str)
    sinfo->tags = gst_tag_list_new_from_string (str);

  str = _maybe_get_string_from_tuple (common, 3);
  if (str)
    sinfo->misc = gst_structure_new_from_string (str);

  g_variant_unref (common);
}

static void
_parse_audio_stream_info (GstDiscovererAudioInfo * ainfo, GVariant * specific)
{
  const gchar *str;

  GET_FROM_TUPLE (specific, uint32, 0, &ainfo->channels);
  GET_FROM_TUPLE (specific, uint32, 1, &ainfo->sample_rate);
  GET_FROM_TUPLE (specific, uint32, 2, &ainfo->bitrate);
  GET_FROM_TUPLE (specific, uint32, 3, &ainfo->max_bitrate);
  GET_FROM_TUPLE (specific, uint32, 4, &ainfo->depth);

  str = _maybe_get_string_from_tuple (specific, 5);

  if (str)
    ainfo->language = g_strdup (str);

  g_variant_unref (specific);
}

static void
_parse_video_stream_info (GstDiscovererVideoInfo * vinfo, GVariant * specific)
{
  GET_FROM_TUPLE (specific, uint32, 0, &vinfo->width);
  GET_FROM_TUPLE (specific, uint32, 1, &vinfo->height);
  GET_FROM_TUPLE (specific, uint32, 2, &vinfo->depth);
  GET_FROM_TUPLE (specific, uint32, 3, &vinfo->framerate_num);
  GET_FROM_TUPLE (specific, uint32, 4, &vinfo->framerate_denom);
  GET_FROM_TUPLE (specific, uint32, 5, &vinfo->par_num);
  GET_FROM_TUPLE (specific, uint32, 6, &vinfo->par_denom);
  GET_FROM_TUPLE (specific, boolean, 7, &vinfo->interlaced);
  GET_FROM_TUPLE (specific, uint32, 8, &vinfo->bitrate);
  GET_FROM_TUPLE (specific, uint32, 9, &vinfo->max_bitrate);
  GET_FROM_TUPLE (specific, boolean, 10, &vinfo->is_image);

  g_variant_unref (specific);
}

static void
_parse_subtitle_stream_info (GstDiscovererSubtitleInfo * sinfo,
    GVariant * specific)
{
  GVariant *maybe;

  maybe = g_variant_get_maybe (specific);
  if (maybe) {
    sinfo->language = g_strdup (g_variant_get_string (maybe, NULL));
    g_variant_unref (maybe);
  }

  g_variant_unref (specific);
}

static GstDiscovererStreamInfo *
_parse_discovery (GVariant * variant, GstDiscovererInfo * info)
{
  gchar type;
  GVariant *common = g_variant_get_child_value (variant, 1);
  GVariant *specific = g_variant_get_child_value (variant, 2);
  GstDiscovererStreamInfo *sinfo = NULL;

  GET_FROM_TUPLE (variant, byte, 0, &type);
  switch (type) {
    case 'c':
      sinfo = g_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO, NULL);
      break;
    case 'a':
      sinfo = g_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO, NULL);
      _parse_audio_stream_info (GST_DISCOVERER_AUDIO_INFO (sinfo),
          g_variant_get_child_value (specific, 0));
      break;
    case 'v':
      sinfo = g_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO, NULL);
      _parse_video_stream_info (GST_DISCOVERER_VIDEO_INFO (sinfo),
          g_variant_get_child_value (specific, 0));
      break;
    case 's':
      sinfo = g_object_new (GST_TYPE_DISCOVERER_SUBTITLE_INFO, NULL);
      _parse_subtitle_stream_info (GST_DISCOVERER_SUBTITLE_INFO (sinfo),
          g_variant_get_child_value (specific, 0));
      break;
    default:
      GST_WARNING ("Unexpected discoverer info type %d", type);
      goto out;
  }

  _parse_common_stream_info (sinfo, g_variant_get_child_value (common, 0));

  info->stream_list = g_list_append (info->stream_list, sinfo);

  if (!info->stream_info) {
    info->stream_info = sinfo;
  }

  if (GST_IS_DISCOVERER_CONTAINER_INFO (sinfo)) {
    GVariantIter iter;
    GVariant *child;

    GstDiscovererContainerInfo *cinfo = GST_DISCOVERER_CONTAINER_INFO (sinfo);
    g_variant_iter_init (&iter, specific);
    while ((child = g_variant_iter_next_value (&iter))) {
      GstDiscovererStreamInfo *child_info;
      child_info = _parse_discovery (g_variant_get_variant (child), info);
      if (child_info != NULL) {
        cinfo->streams =
            g_list_append (cinfo->streams,
            gst_discoverer_stream_info_ref (child_info));
      }
      g_variant_unref (child);
    }
  }

out:

  g_variant_unref (common);
  g_variant_unref (specific);
  g_variant_unref (variant);
  return sinfo;
}

/**
 * gst_discoverer_start:
 * @discoverer: A #GstDiscoverer
 *
 * Allow asynchronous discovering of URIs to take place.
 * A #GMainLoop must be available for #GstDiscoverer to properly work in
 * asynchronous mode.
 */
void
gst_discoverer_start (GstDiscoverer * discoverer)
{
  GSource *source;
  GMainContext *ctx = NULL;

  g_return_if_fail (GST_IS_DISCOVERER (discoverer));

  GST_DEBUG_OBJECT (discoverer, "Starting...");

  if (discoverer->priv->async) {
    GST_DEBUG_OBJECT (discoverer, "We were already started");
    return;
  }

  discoverer->priv->async = TRUE;
  discoverer->priv->running = TRUE;

  ctx = g_main_context_get_thread_default ();

  /* Connect to bus signals */
  if (ctx == NULL)
    ctx = g_main_context_default ();

  source = gst_bus_create_watch (discoverer->priv->bus);
  g_source_set_callback (source, (GSourceFunc) gst_bus_async_signal_func,
      NULL, NULL);
  discoverer->priv->sourceid = g_source_attach (source, ctx);
  g_source_unref (source);
  discoverer->priv->ctx = g_main_context_ref (ctx);

  start_discovering (discoverer);
  GST_DEBUG_OBJECT (discoverer, "Started");
}

/**
 * gst_discoverer_stop:
 * @discoverer: A #GstDiscoverer
 *
 * Stop the discovery of any pending URIs and clears the list of
 * pending URIS (if any).
 */
void
gst_discoverer_stop (GstDiscoverer * discoverer)
{
  g_return_if_fail (GST_IS_DISCOVERER (discoverer));

  GST_DEBUG_OBJECT (discoverer, "Stopping...");

  if (!discoverer->priv->async) {
    GST_DEBUG_OBJECT (discoverer,
        "We were already stopped, or running synchronously");
    return;
  }

  DISCO_LOCK (discoverer);
  if (discoverer->priv->processing) {
    /* We prevent any further processing by setting the bus to
     * flushing and setting the pipeline to READY.
     * _reset() will take care of the rest of the cleanup */
    if (discoverer->priv->bus)
      gst_bus_set_flushing (discoverer->priv->bus, TRUE);
    if (discoverer->priv->pipeline)
      gst_element_set_state ((GstElement *) discoverer->priv->pipeline,
          GST_STATE_READY);
  }
  discoverer->priv->running = FALSE;
  DISCO_UNLOCK (discoverer);

  /* Remove timeout handler */
  if (discoverer->priv->timeoutid) {
    g_source_remove (discoverer->priv->timeoutid);
    discoverer->priv->timeoutid = 0;
  }
  /* Remove signal watch */
  if (discoverer->priv->sourceid) {
    g_source_remove (discoverer->priv->sourceid);
    discoverer->priv->sourceid = 0;
  }
  /* Unref main context */
  if (discoverer->priv->ctx) {
    g_main_context_unref (discoverer->priv->ctx);
    discoverer->priv->ctx = NULL;
  }
  discoverer_reset (discoverer);

  discoverer->priv->async = FALSE;

  GST_DEBUG_OBJECT (discoverer, "Stopped");
}

/**
 * gst_discoverer_discover_uri_async:
 * @discoverer: A #GstDiscoverer
 * @uri: the URI to add.
 *
 * Appends the given @uri to the list of URIs to discoverer. The actual
 * discovery of the @uri will only take place if gst_discoverer_start() has
 * been called.
 *
 * A copy of @uri will be made internally, so the caller can safely g_free()
 * afterwards.
 *
 * Returns: %TRUE if the @uri was successfully appended to the list of pending
 * uris, else %FALSE
 */
gboolean
gst_discoverer_discover_uri_async (GstDiscoverer * discoverer,
    const gchar * uri)
{
  gboolean can_run;

  g_return_val_if_fail (GST_IS_DISCOVERER (discoverer), FALSE);

  GST_DEBUG_OBJECT (discoverer, "uri : %s", uri);

  DISCO_LOCK (discoverer);
  can_run = (discoverer->priv->pending_uris == NULL);
  discoverer->priv->pending_uris =
      g_list_append (discoverer->priv->pending_uris, g_strdup (uri));
  DISCO_UNLOCK (discoverer);

  if (can_run)
    start_discovering (discoverer);

  return TRUE;
}


/* Synchronous mode */
/**
 * gst_discoverer_discover_uri:
 * @discoverer: A #GstDiscoverer
 * @uri: The URI to run on.
 * @err: (out) (allow-none): If an error occurred, this field will be filled in.
 *
 * Synchronously discovers the given @uri.
 *
 * A copy of @uri will be made internally, so the caller can safely g_free()
 * afterwards.
 *
 * Returns: (transfer full): the result of the scanning. Can be %NULL if an
 * error occurred.
 */
GstDiscovererInfo *
gst_discoverer_discover_uri (GstDiscoverer * discoverer, const gchar * uri,
    GError ** err)
{
  GstDiscovererResult res = 0;
  GstDiscovererInfo *info;

  g_return_val_if_fail (GST_IS_DISCOVERER (discoverer), NULL);
  g_return_val_if_fail (uri, NULL);

  GST_DEBUG_OBJECT (discoverer, "uri:%s", uri);

  DISCO_LOCK (discoverer);
  if (G_UNLIKELY (discoverer->priv->current_info)) {
    DISCO_UNLOCK (discoverer);
    GST_WARNING_OBJECT (discoverer, "Already handling a uri");
    if (err)
      *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_FAILED,
          "Already handling a uri");
    return NULL;
  }

  discoverer->priv->pending_uris =
      g_list_append (discoverer->priv->pending_uris, g_strdup (uri));
  DISCO_UNLOCK (discoverer);

  res = start_discovering (discoverer);
  discoverer_collect (discoverer);

  /* Get results */
  if (err) {
    if (discoverer->priv->current_error)
      *err = g_error_copy (discoverer->priv->current_error);
    else
      *err = NULL;
  }
  if (res != GST_DISCOVERER_OK) {
    GST_DEBUG ("Setting result to %d (was %d)", res,
        discoverer->priv->current_info->result);
    discoverer->priv->current_info->result = res;
  }
  info = discoverer->priv->current_info;

  discoverer_cleanup (discoverer);

  return info;
}

/**
 * gst_discoverer_new:
 * @timeout: timeout per file, in nanoseconds. Allowed are values between
 *     one second (#GST_SECOND) and one hour (3600 * #GST_SECOND)
 * @err: a pointer to a #GError. can be %NULL
 *
 * Creates a new #GstDiscoverer with the provided timeout.
 *
 * Returns: (transfer full): The new #GstDiscoverer.
 * If an error occurred when creating the discoverer, @err will be set
 * accordingly and %NULL will be returned. If @err is set, the caller must
 * free it when no longer needed using g_error_free().
 */
GstDiscoverer *
gst_discoverer_new (GstClockTime timeout, GError ** err)
{
  GstDiscoverer *res;

  res = g_object_new (GST_TYPE_DISCOVERER, "timeout", timeout, NULL);
  if (res->priv->uridecodebin == NULL) {
    if (err)
      *err = g_error_new (GST_CORE_ERROR, GST_CORE_ERROR_MISSING_PLUGIN,
          "Couldn't create 'uridecodebin' element");
    gst_object_unref (res);
    res = NULL;
  }
  return res;
}

/**
 * gst_discoverer_info_to_variant:
 * @info: A #GstDiscovererInfo
 * @flags: A combination of #GstDiscovererSerializeFlags to specify
 * what needs to be serialized.
 *
 * Serializes @info to a #GVariant that can be parsed again
 * through gst_discoverer_info_from_variant().
 *
 * Note that any #GstToc (s) that might have been discovered will not be serialized
 * for now.
 *
 * Returns: (transfer full): A newly-allocated #GVariant representing @info.
 *
 * Since: 1.6
 */
GVariant *
gst_discoverer_info_to_variant (GstDiscovererInfo * info,
    GstDiscovererSerializeFlags flags)
{
  /* FIXME: implement TOC support */
  GVariant *stream_variant;
  GVariant *variant;
  GstDiscovererStreamInfo *sinfo = gst_discoverer_info_get_stream_info (info);
  GVariant *wrapper;

  g_return_val_if_fail (GST_IS_DISCOVERER_INFO (info), NULL);

  stream_variant = gst_discoverer_info_to_variant_recurse (sinfo, flags);
  variant =
      g_variant_new ("(vv)", _serialize_info (info, flags), stream_variant);

  /* Returning a wrapper implies some small overhead, but simplifies 
   * deserializing from bytes */
  wrapper = g_variant_new_variant (variant);

  gst_discoverer_stream_info_unref (sinfo);
  return wrapper;
}

/**
 * gst_discoverer_info_from_variant:
 * @variant: A #GVariant to deserialize into a #GstDiscovererInfo.
 *
 * Parses a #GVariant as produced by gst_discoverer_info_to_variant()
 * back to a #GstDiscovererInfo.
 *
 * Returns: (transfer full): A newly-allocated #GstDiscovererInfo.
 *
 * Since: 1.6
 */
GstDiscovererInfo *
gst_discoverer_info_from_variant (GVariant * variant)
{
  GstDiscovererInfo *info = g_object_new (GST_TYPE_DISCOVERER_INFO, NULL);
  GVariant *info_variant = g_variant_get_variant (variant);
  GVariant *info_specific_variant;
  GVariant *wrapped;

  GET_FROM_TUPLE (info_variant, variant, 0, &info_specific_variant);
  GET_FROM_TUPLE (info_variant, variant, 1, &wrapped);

  _parse_info (info, info_specific_variant);
  _parse_discovery (wrapped, info);
  g_variant_unref (info_specific_variant);
  g_variant_unref (info_variant);

  return info;
}
