/* GStreamer encoding bin
 * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
 *           (C) 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.
 */

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

#include <string.h>
#include "gstencodebin.h"
#include "gstsmartencoder.h"
#include "gststreamsplitter.h"
#include "gststreamcombiner.h"
#include <gst/gst-i18n-plugin.h>

/**
 * SECTION:element-encodebin
 *
 * EncodeBin provides a bin for encoding/muxing various streams according to
 * a specified #GstEncodingProfile.
 *
 * Based on the profile that was set (via the #GstEncodeBin:profile property),
 * EncodeBin will internally select and configure the required elements
 * (encoders, muxers, but also audio and video converters) so that you can
 * provide it raw or pre-encoded streams of data in input and have your
 * encoded/muxed/converted stream in output.
 *
 * <refsect2>
 * <title>Features</title>
 * <itemizedlist>
 * <listitem>
 * Automatic encoder and muxer selection based on elements available on the
 * system.
 * </listitem>
 * <listitem>
 * Conversion of raw audio/video streams (scaling, framerate conversion,
 * colorspace conversion, samplerate conversion) to conform to the profile
 * output format.
 * </listitem>
 * <listitem>
 * Variable number of streams. If the presence property for a stream encoding
 * profile is 0, you can request any number of sink pads for it via the
 * standard request pad gstreamer API or the #GstEncodeBin::request-pad action
 * signal.
 * </listitem>
 * <listitem>
 * Avoid reencoding (passthrough). If the input stream is already encoded and is
 * compatible with what the #GstEncodingProfile expects, then the stream won't
 * be re-encoded but just passed through downstream to the muxer or the output.
 * </listitem>
 * <listitem>
 * Mix pre-encoded and raw streams as input. In addition to the passthrough
 * feature above, you can feed both raw audio/video *AND* already-encoded data
 * to a pad. #GstEncodeBin will take care of passing through the compatible
 * segments and re-encoding the segments of media that need encoding.
 * </listitem>
 * <listitem>
 * Standard behaviour is to use a #GstEncodingContainerProfile to have both
 * encoding and muxing performed. But you can also provide a single stream
 * profile (like #GstEncodingAudioProfile) to only have the encoding done and
 * handle the encoded output yourself.
 * </listitem>
 * <listitem>
 * Audio imperfection corrections. Incoming audio streams can have non perfect
 * timestamps (jitter), like the streams coming from ASF files. #GstEncodeBin
 * will automatically fix those imperfections for you. See
 * #GstEncodeBin:audio-jitter-tolerance for more details.
 * </listitem>
 * <listitem>
 * Variable or Constant video framerate. If your #GstEncodingVideoProfile has
 * the variableframerate property deactivated (default), then the incoming
 * raw video stream will be retimestampped in order to produce a constant
 * framerate.
 * </listitem>
 * <listitem>
 * Cross-boundary re-encoding. When feeding compatible pre-encoded streams that
 * fall on segment boundaries, and for supported formats (right now only H263),
 * the GOP will be decoded/reencoded when needed to produce an encoded output
 * that fits exactly within the request GstSegment.
 * </listitem>
 * <listitem>
 * Missing plugin support. If a #GstElement is missing to encode/mux to the
 * request profile formats, a missing-plugin #GstMessage will be posted on the
 * #GstBus, allowing systems that support the missing-plugin system to offer the
 * user a way to install the missing element.
 * </listitem>
 * </itemizedlist>
 * </refsect2>
 */


/* TODO/FIXME
 *
 * Handling mp3!xing!idv3 and theora!ogg tagsetting scenarios:
 *  Once we have chosen a muxer:
 *   When a new stream is requested:
 *    If muxer isn't 'Formatter' OR doesn't have a TagSetter interface:
 *      Find a Formatter for the given stream (preferably with TagSetter)
 *       Insert that before muxer
 **/

#define fast_pad_link(a,b) gst_pad_link_full((a),(b),GST_PAD_LINK_CHECK_NOTHING)
#define fast_element_link(a,b) gst_element_link_pads_full((a),"src",(b),"sink",GST_PAD_LINK_CHECK_NOTHING)

typedef enum
{
  GST_ENCODEBIN_FLAG_NO_AUDIO_CONVERSION = (1 << 0),
  GST_ENCODEBIN_FLAG_NO_VIDEO_CONVERSION = (1 << 1)
} GstEncodeBinFlags;

#define GST_TYPE_ENCODEBIN_FLAGS (gst_encodebin_flags_get_type())
GType gst_encodebin_flags_get_type (void);

/* generic templates */
static GstStaticPadTemplate muxer_src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate video_sink_template =
GST_STATIC_PAD_TEMPLATE ("video_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate audio_sink_template =
GST_STATIC_PAD_TEMPLATE ("audio_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS_ANY);
/* static GstStaticPadTemplate text_sink_template = */
/* GST_STATIC_PAD_TEMPLATE ("text_%u", */
/*     GST_PAD_SINK, */
/*     GST_PAD_REQUEST, */
/*     GST_STATIC_CAPS_ANY); */
static GstStaticPadTemplate private_sink_template =
GST_STATIC_PAD_TEMPLATE ("private_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS_ANY);

struct _GstEncodeBin
{
  GstBin parent;

  /* the profile field is only valid if it could be entirely setup */
  GstEncodingProfile *profile;

  GList *streams;               /* List of StreamGroup, not sorted */

  GstElement *muxer;
  /* Ghostpad with changing target */
  GstPad *srcpad;

  /* TRUE if in PAUSED/PLAYING */
  gboolean active;

  /* available muxers, encoders and parsers */
  GList *muxers;
  GList *formatters;
  GList *encoders;
  GList *parsers;

  /* Increasing counter for unique pad name */
  guint last_pad_id;

  /* Cached caps for identification */
  GstCaps *raw_video_caps;
  GstCaps *raw_audio_caps;
  /* GstCaps *raw_text_caps; */

  guint queue_buffers_max;
  guint queue_bytes_max;
  guint64 queue_time_max;

  guint64 tolerance;
  gboolean avoid_reencoding;

  GstEncodeBinFlags flags;
};

struct _GstEncodeBinClass
{
  GstBinClass parent;

  /* Action Signals */
  GstPad *(*request_pad) (GstEncodeBin * encodebin, GstCaps * caps);
  GstPad *(*request_profile_pad) (GstEncodeBin * encodebin,
      const gchar * profilename);
};

typedef struct _StreamGroup StreamGroup;

struct _StreamGroup
{
  GstEncodeBin *ebin;
  GstEncodingProfile *profile;
  GstPad *ghostpad;             /* Sink ghostpad */
  GstElement *inqueue;          /* Queue just after the ghostpad */
  GstElement *splitter;
  GList *converters;            /* List of conversion GstElement */
  GstElement *capsfilter;       /* profile->restriction (if non-NULL/ANY) */
  GstElement *encoder;          /* Encoder (can be NULL) */
  GstElement *fakesink;         /* Fakesink (can be NULL) */
  GstElement *combiner;
  GstElement *parser;
  GstElement *smartencoder;
  GstElement *outfilter;        /* Output capsfilter (streamprofile.format) */
  gulong outputfilter_caps_sid;
  GstElement *formatter;
  GstElement *outqueue;         /* Queue just before the muxer */
  gulong restriction_sid;
};

/* Default for queues (same defaults as queue element) */
#define DEFAULT_QUEUE_BUFFERS_MAX  200
#define DEFAULT_QUEUE_BYTES_MAX    10 * 1024 * 1024
#define DEFAULT_QUEUE_TIME_MAX     GST_SECOND
#define DEFAULT_AUDIO_JITTER_TOLERANCE 20 * GST_MSECOND
#define DEFAULT_AVOID_REENCODING   FALSE
#define DEFAULT_FLAGS              0

#define DEFAULT_RAW_CAPS			\
  "video/x-raw; "				\
  "audio/x-raw; "				\
  "text/x-raw; "				\
  "subpicture/x-dvd; "			\
  "subpicture/x-pgs"

/* Properties */
enum
{
  PROP_0,
  PROP_PROFILE,
  PROP_QUEUE_BUFFERS_MAX,
  PROP_QUEUE_BYTES_MAX,
  PROP_QUEUE_TIME_MAX,
  PROP_AUDIO_JITTER_TOLERANCE,
  PROP_AVOID_REENCODING,
  PROP_FLAGS
};

/* Signals */
enum
{
  SIGNAL_REQUEST_PAD,
  SIGNAL_REQUEST_PROFILE_PAD,
  LAST_SIGNAL
};

#define C_FLAGS(v) ((guint) v)

GType
gst_encodebin_flags_get_type (void)
{
  static const GFlagsValue values[] = {
    {C_FLAGS (GST_ENCODEBIN_FLAG_NO_AUDIO_CONVERSION), "Do not use audio "
          "conversion elements", "no-audio-conversion"},
    {C_FLAGS (GST_ENCODEBIN_FLAG_NO_VIDEO_CONVERSION), "Do not use video "
          "conversion elements", "no-video-conversion"},
    {0, NULL, NULL}
  };
  static volatile GType id = 0;

  if (g_once_init_enter ((gsize *) & id)) {
    GType _id;

    _id = g_flags_register_static ("GstEncodeBinFlags", values);

    g_once_init_leave ((gsize *) & id, _id);
  }

  return id;
}

static guint gst_encode_bin_signals[LAST_SIGNAL] = { 0 };

static GstStaticCaps default_raw_caps = GST_STATIC_CAPS (DEFAULT_RAW_CAPS);

GST_DEBUG_CATEGORY_STATIC (gst_encode_bin_debug);
#define GST_CAT_DEFAULT gst_encode_bin_debug

G_DEFINE_TYPE (GstEncodeBin, gst_encode_bin, GST_TYPE_BIN);

static void gst_encode_bin_dispose (GObject * object);
static void gst_encode_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_encode_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static GstStateChangeReturn gst_encode_bin_change_state (GstElement * element,
    GstStateChange transition);

static GstPad *gst_encode_bin_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void gst_encode_bin_release_pad (GstElement * element, GstPad * pad);

static gboolean
gst_encode_bin_set_profile (GstEncodeBin * ebin, GstEncodingProfile * profile);
static void gst_encode_bin_tear_down_profile (GstEncodeBin * ebin);
static gboolean gst_encode_bin_setup_profile (GstEncodeBin * ebin,
    GstEncodingProfile * profile);

static StreamGroup *_create_stream_group (GstEncodeBin * ebin,
    GstEncodingProfile * sprof, const gchar * sinkpadname, GstCaps * sinkcaps);
static void stream_group_remove (GstEncodeBin * ebin, StreamGroup * sgroup);
static void stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup);
static GstPad *gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin,
    GstCaps * caps);
static GstPad *gst_encode_bin_request_profile_pad_signal (GstEncodeBin *
    encodebin, const gchar * profilename);

static inline GstElement *_get_formatter (GstEncodeBin * ebin,
    GstEncodingProfile * sprof);

static void
gst_encode_bin_class_init (GstEncodeBinClass * klass)
{
  GObjectClass *gobject_klass;
  GstElementClass *gstelement_klass;

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

  gobject_klass->dispose = gst_encode_bin_dispose;
  gobject_klass->set_property = gst_encode_bin_set_property;
  gobject_klass->get_property = gst_encode_bin_get_property;

  /* Properties */

  /**
   * GstEncodeBin:profile:
   *
   * The #GstEncodingProfile to use. This property must be set before going
   * to %GST_STATE_PAUSED or higher.
   */
  g_object_class_install_property (gobject_klass, PROP_PROFILE,
      g_param_spec_object ("profile", "Profile",
          "The GstEncodingProfile to use", GST_TYPE_ENCODING_PROFILE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_klass, PROP_QUEUE_BYTES_MAX,
      g_param_spec_uint ("queue-bytes-max", "Max. size (kB)",
          "Max. amount of data in the queue (bytes, 0=disable)",
          0, G_MAXUINT, DEFAULT_QUEUE_BYTES_MAX,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_klass, PROP_QUEUE_BUFFERS_MAX,
      g_param_spec_uint ("queue-buffers-max", "Max. size (buffers)",
          "Max. number of buffers in the queue (0=disable)", 0, G_MAXUINT,
          DEFAULT_QUEUE_BUFFERS_MAX,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_klass, PROP_QUEUE_TIME_MAX,
      g_param_spec_uint64 ("queue-time-max", "Max. size (ns)",
          "Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64,
          DEFAULT_QUEUE_TIME_MAX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_klass, PROP_AUDIO_JITTER_TOLERANCE,
      g_param_spec_uint64 ("audio-jitter-tolerance", "Audio jitter tolerance",
          "Amount of timestamp jitter/imperfection to allow on audio streams before inserting/dropping samples (ns)",
          0, G_MAXUINT64, DEFAULT_AUDIO_JITTER_TOLERANCE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_klass, PROP_AVOID_REENCODING,
      g_param_spec_boolean ("avoid-reencoding", "Avoid re-encoding",
          "Whether to re-encode portions of compatible video streams that lay on segment boundaries",
          DEFAULT_AVOID_REENCODING,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstEncodeBin:flags
   *
   * Control the behaviour of encodebin.
   */
  g_object_class_install_property (gobject_klass, PROP_FLAGS,
      g_param_spec_flags ("flags", "Flags", "Flags to control behaviour",
          GST_TYPE_ENCODEBIN_FLAGS, DEFAULT_FLAGS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /* Signals */
  /**
   * GstEncodeBin::request-pad
   * @encodebin: a #GstEncodeBin instance
   * @caps: a #GstCaps
   *
   * Use this method to request an unused sink request #GstPad that can take the
   * provided @caps as input. You must release the pad with
   * gst_element_release_request_pad() when you are done with it.
   *
   * Returns: A compatible #GstPad, or %NULL if no compatible #GstPad could be
   * created or is available.
   */
  gst_encode_bin_signals[SIGNAL_REQUEST_PAD] =
      g_signal_new ("request-pad", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstEncodeBinClass,
          request_pad), NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_PAD, 1, GST_TYPE_CAPS);

  /**
   * GstEncodeBin::request-profile-pad
   * @encodebin: a #GstEncodeBin instance
   * @profilename: the name of a #GstEncodingProfile
   *
   * Use this method to request an unused sink request #GstPad from the profile
   * @profilename. You must release the pad with
   * gst_element_release_request_pad() when you are done with it.
   *
   * Returns: A compatible #GstPad, or %NULL if no compatible #GstPad could be
   * created or is available.
   */
  gst_encode_bin_signals[SIGNAL_REQUEST_PROFILE_PAD] =
      g_signal_new ("request-profile-pad", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstEncodeBinClass,
          request_profile_pad), NULL, NULL, g_cclosure_marshal_generic,
      GST_TYPE_PAD, 1, G_TYPE_STRING);

  klass->request_pad = gst_encode_bin_request_pad_signal;
  klass->request_profile_pad = gst_encode_bin_request_profile_pad_signal;

  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&muxer_src_template));
  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&video_sink_template));
  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&audio_sink_template));
  /* gst_element_class_add_pad_template (gstelement_klass, */
  /*     gst_static_pad_template_get (&text_sink_template)); */
  gst_element_class_add_pad_template (gstelement_klass,
      gst_static_pad_template_get (&private_sink_template));

  gstelement_klass->change_state =
      GST_DEBUG_FUNCPTR (gst_encode_bin_change_state);
  gstelement_klass->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_encode_bin_request_new_pad);
  gstelement_klass->release_pad =
      GST_DEBUG_FUNCPTR (gst_encode_bin_release_pad);

  gst_element_class_set_static_metadata (gstelement_klass,
      "Encoder Bin",
      "Generic/Bin/Encoder",
      "Convenience encoding/muxing element",
      "Edward Hervey <edward.hervey@collabora.co.uk>");
}

static void
gst_encode_bin_dispose (GObject * object)
{
  GstEncodeBin *ebin = (GstEncodeBin *) object;

  if (ebin->muxers)
    gst_plugin_feature_list_free (ebin->muxers);

  if (ebin->formatters)
    gst_plugin_feature_list_free (ebin->formatters);

  if (ebin->encoders)
    gst_plugin_feature_list_free (ebin->encoders);

  if (ebin->parsers)
    gst_plugin_feature_list_free (ebin->parsers);

  gst_encode_bin_tear_down_profile (ebin);

  if (ebin->raw_video_caps)
    gst_caps_unref (ebin->raw_video_caps);
  if (ebin->raw_audio_caps)
    gst_caps_unref (ebin->raw_audio_caps);
  /* if (ebin->raw_text_caps) */
  /*   gst_caps_unref (ebin->raw_text_caps); */

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

static void
gst_encode_bin_init (GstEncodeBin * encode_bin)
{
  GstPadTemplate *tmpl;

  encode_bin->muxers =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
      GST_RANK_MARGINAL);

  encode_bin->formatters =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_FORMATTER,
      GST_RANK_SECONDARY);

  encode_bin->encoders =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER,
      GST_RANK_MARGINAL);

  encode_bin->parsers =
      gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_PARSER,
      GST_RANK_MARGINAL);

  encode_bin->raw_video_caps = gst_caps_from_string ("video/x-raw");
  encode_bin->raw_audio_caps = gst_caps_from_string ("audio/x-raw");
  /* encode_bin->raw_text_caps = */
  /*     gst_caps_from_string ("text/x-raw"); */

  encode_bin->queue_buffers_max = DEFAULT_QUEUE_BUFFERS_MAX;
  encode_bin->queue_bytes_max = DEFAULT_QUEUE_BYTES_MAX;
  encode_bin->queue_time_max = DEFAULT_QUEUE_TIME_MAX;
  encode_bin->tolerance = DEFAULT_AUDIO_JITTER_TOLERANCE;
  encode_bin->avoid_reencoding = DEFAULT_AVOID_REENCODING;
  encode_bin->flags = DEFAULT_FLAGS;

  tmpl = gst_static_pad_template_get (&muxer_src_template);
  encode_bin->srcpad = gst_ghost_pad_new_no_target_from_template ("src", tmpl);
  gst_object_unref (tmpl);
  gst_pad_set_active (encode_bin->srcpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (encode_bin), encode_bin->srcpad);
}

static void
gst_encode_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstEncodeBin *ebin = (GstEncodeBin *) object;

  switch (prop_id) {
    case PROP_PROFILE:
      gst_encode_bin_set_profile (ebin,
          (GstEncodingProfile *) g_value_get_object (value));
      break;
    case PROP_QUEUE_BUFFERS_MAX:
      ebin->queue_buffers_max = g_value_get_uint (value);
      break;
    case PROP_QUEUE_BYTES_MAX:
      ebin->queue_bytes_max = g_value_get_uint (value);
      break;
    case PROP_QUEUE_TIME_MAX:
      ebin->queue_time_max = g_value_get_uint64 (value);
      break;
    case PROP_AUDIO_JITTER_TOLERANCE:
      ebin->tolerance = g_value_get_uint64 (value);
      break;
    case PROP_AVOID_REENCODING:
      ebin->avoid_reencoding = g_value_get_boolean (value);
      break;
    case PROP_FLAGS:
      ebin->flags = g_value_get_flags (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_encode_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstEncodeBin *ebin = (GstEncodeBin *) object;

  switch (prop_id) {
    case PROP_PROFILE:
      g_value_set_object (value, (GObject *) ebin->profile);
      break;
    case PROP_QUEUE_BUFFERS_MAX:
      g_value_set_uint (value, ebin->queue_buffers_max);
      break;
    case PROP_QUEUE_BYTES_MAX:
      g_value_set_uint (value, ebin->queue_bytes_max);
      break;
    case PROP_QUEUE_TIME_MAX:
      g_value_set_uint64 (value, ebin->queue_time_max);
      break;
    case PROP_AUDIO_JITTER_TOLERANCE:
      g_value_set_uint64 (value, ebin->tolerance);
      break;
    case PROP_AVOID_REENCODING:
      g_value_set_boolean (value, ebin->avoid_reencoding);
      break;
    case PROP_FLAGS:
      g_value_set_flags (value, ebin->flags);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static inline gboolean
are_raw_caps (const GstCaps * caps)
{
  GstCaps *raw = gst_static_caps_get (&default_raw_caps);

  if (gst_caps_can_intersect (caps, raw)) {
    gst_caps_unref (raw);
    return TRUE;
  }
  gst_caps_unref (raw);
  return FALSE;
}

/* Returns the number of time a given stream profile is currently used
 * in encodebin */
static inline guint
stream_profile_used_count (GstEncodeBin * ebin, GstEncodingProfile * sprof)
{
  guint nbprofused = 0;
  GList *tmp;

  for (tmp = ebin->streams; tmp; tmp = tmp->next) {
    StreamGroup *sgroup = (StreamGroup *) tmp->data;

    if (sgroup->profile == sprof)
      nbprofused++;
  }

  return nbprofused;
}

static inline GstEncodingProfile *
next_unused_stream_profile (GstEncodeBin * ebin, GType ptype,
    const gchar * name, GstCaps * caps)
{
  GST_DEBUG_OBJECT (ebin, "ptype:%s, caps:%" GST_PTR_FORMAT,
      g_type_name (ptype), caps);

  if (G_UNLIKELY (ptype == G_TYPE_NONE && caps != NULL)) {
    /* Identify the profile type based on raw caps */
    if (gst_caps_can_intersect (ebin->raw_video_caps, caps))
      ptype = GST_TYPE_ENCODING_VIDEO_PROFILE;
    else if (gst_caps_can_intersect (ebin->raw_audio_caps, caps))
      ptype = GST_TYPE_ENCODING_AUDIO_PROFILE;
    /* else if (gst_caps_can_intersect (ebin->raw_text_caps, caps)) */
    /*   ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */
    GST_DEBUG_OBJECT (ebin, "Detected profile type as being %s",
        g_type_name (ptype));
  }

  if (GST_IS_ENCODING_CONTAINER_PROFILE (ebin->profile)) {
    const GList *tmp;

    if (name) {
      /* If we have a name, try to find a profile with the same name */
      tmp =
          gst_encoding_container_profile_get_profiles
          (GST_ENCODING_CONTAINER_PROFILE (ebin->profile));

      for (; tmp; tmp = tmp->next) {
        GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data;
        const gchar *profilename = gst_encoding_profile_get_name (sprof);

        if (profilename && !strcmp (name, profilename)) {
          guint presence = gst_encoding_profile_get_presence (sprof);

          GST_DEBUG ("Found profile matching the requested name");

          if (!gst_encoding_profile_is_enabled (sprof)) {
            GST_INFO_OBJECT (ebin, "%p is disabled, not using it", sprof);

            return NULL;
          }

          if (presence == 0
              || presence > stream_profile_used_count (ebin, sprof))
            return sprof;

          GST_WARNING ("Matching stream already used");
          return NULL;
        }
      }
      GST_DEBUG
          ("No profiles matching requested pad name, carrying on with normal stream matching");
    }

    for (tmp =
        gst_encoding_container_profile_get_profiles
        (GST_ENCODING_CONTAINER_PROFILE (ebin->profile)); tmp;
        tmp = tmp->next) {
      GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data;

      /* Pick an available Stream profile for which:
       * * either it is of the compatible raw type,
       * * OR we can pass it through directly without encoding
       */
      if (G_TYPE_FROM_INSTANCE (sprof) == ptype) {
        guint presence = gst_encoding_profile_get_presence (sprof);
        GST_DEBUG ("Found a stream profile with the same type");
        if (!gst_encoding_profile_is_enabled (sprof)) {
          GST_INFO_OBJECT (ebin, "%p is disabled, not using it", sprof);
        } else if (presence == 0
            || (presence > stream_profile_used_count (ebin, sprof)))
          return sprof;
      } else if (caps && ptype == G_TYPE_NONE) {
        GstCaps *outcaps;
        gboolean res;

        outcaps = gst_encoding_profile_get_input_caps (sprof);
        GST_DEBUG ("Unknown stream, seeing if it's compatible with %"
            GST_PTR_FORMAT, outcaps);
        res = gst_caps_can_intersect (outcaps, caps);
        gst_caps_unref (outcaps);

        if (res)
          return sprof;
      }
    }
  }

  return NULL;
}

static GstPad *
request_pad_for_stream (GstEncodeBin * encodebin, GType ptype,
    const gchar * name, GstCaps * caps)
{
  StreamGroup *sgroup;
  GstEncodingProfile *sprof;

  GST_DEBUG_OBJECT (encodebin, "name:%s caps:%" GST_PTR_FORMAT, name, caps);

  /* Figure out if we have a unused GstEncodingProfile we can use for
   * these caps */
  sprof = next_unused_stream_profile (encodebin, ptype, name, caps);

  if (G_UNLIKELY (sprof == NULL))
    goto no_stream_profile;

  sgroup = _create_stream_group (encodebin, sprof, name, caps);
  if (G_UNLIKELY (sgroup == NULL))
    goto no_stream_group;

  return sgroup->ghostpad;

no_stream_profile:
  {
    GST_WARNING_OBJECT (encodebin, "Couldn't find a compatible stream profile");
    return NULL;
  }

no_stream_group:
  {
    GST_WARNING_OBJECT (encodebin, "Couldn't create a StreamGroup");
    return NULL;
  }
}

static GstPad *
gst_encode_bin_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstEncodeBin *ebin = (GstEncodeBin *) element;
  GstPad *res = NULL;

  GST_DEBUG_OBJECT (element, "templ:%s, name:%s", templ->name_template, name);

  /* Identify the stream group (if name or caps have been provided) */
  if (caps != NULL || name != NULL) {
    res = request_pad_for_stream (ebin, G_TYPE_NONE, name, (GstCaps *) caps);
  }

  if (res == NULL) {
    GType ptype = G_TYPE_NONE;

    if (!strcmp (templ->name_template, "video_%u"))
      ptype = GST_TYPE_ENCODING_VIDEO_PROFILE;
    else if (!strcmp (templ->name_template, "audio_%u"))
      ptype = GST_TYPE_ENCODING_AUDIO_PROFILE;
    /* else if (!strcmp (templ->name_template, "text_%u")) */
    /*   ptype = GST_TYPE_ENCODING_TEXT_PROFILE; */

    /* FIXME : Check uniqueness of pad */
    /* FIXME : Check that the requested number is the last one, and if not,
     * update the last_pad_id variable so that we don't create a pad with
     * the same name/number in the future */

    res = request_pad_for_stream (ebin, ptype, name, NULL);
  }

  return res;
}

static GstPad *
gst_encode_bin_request_pad_signal (GstEncodeBin * encodebin, GstCaps * caps)
{
  GstPad *pad = request_pad_for_stream (encodebin, G_TYPE_NONE, NULL, caps);

  return pad ? GST_PAD_CAST (gst_object_ref (pad)) : NULL;
}

static GstPad *
gst_encode_bin_request_profile_pad_signal (GstEncodeBin * encodebin,
    const gchar * profilename)
{
  GstPad *pad =
      request_pad_for_stream (encodebin, G_TYPE_NONE, profilename, NULL);

  return pad ? GST_PAD_CAST (gst_object_ref (pad)) : NULL;
}

static inline StreamGroup *
find_stream_group_from_pad (GstEncodeBin * ebin, GstPad * pad)
{
  GList *tmp;

  for (tmp = ebin->streams; tmp; tmp = tmp->next) {
    StreamGroup *sgroup = (StreamGroup *) tmp->data;
    if (G_UNLIKELY (sgroup->ghostpad == pad))
      return sgroup;
  }

  return NULL;
}

static void
gst_encode_bin_release_pad (GstElement * element, GstPad * pad)
{
  GstEncodeBin *ebin = (GstEncodeBin *) element;
  StreamGroup *sgroup;

  /* Find the associated StreamGroup */

  sgroup = find_stream_group_from_pad (ebin, pad);
  if (G_UNLIKELY (sgroup == NULL))
    goto no_stream_group;

  /* Release objects/data associated with the StreamGroup */
  stream_group_remove (ebin, sgroup);

  return;

no_stream_group:
  {
    GST_WARNING_OBJECT (ebin, "Couldn't find corresponding StreamGroup");
    return;
  }
}

/* Create a parser for the given stream profile */
static inline GstElement *
_get_parser (GstEncodeBin * ebin, GstEncodingProfile * sprof)
{
  GList *parsers1, *parsers, *tmp;
  GstElement *parser = NULL;
  GstElementFactory *parserfact = NULL;
  GstCaps *format;

  format = gst_encoding_profile_get_format (sprof);

  GST_DEBUG ("Getting list of parsers for format %" GST_PTR_FORMAT, format);

  /* FIXME : requesting twice the parsers twice is a bit ugly, we should
   * have a method to request on more than one condition */
  parsers1 =
      gst_element_factory_list_filter (ebin->parsers, format,
      GST_PAD_SRC, FALSE);
  parsers =
      gst_element_factory_list_filter (parsers1, format, GST_PAD_SINK, FALSE);
  gst_plugin_feature_list_free (parsers1);

  if (G_UNLIKELY (parsers == NULL)) {
    GST_DEBUG ("Couldn't find any compatible parsers");
    goto beach;
  }

  for (tmp = parsers; tmp; tmp = tmp->next) {
    /* FIXME : We're only picking the first one so far */
    /* FIXME : signal the user if he wants this */
    parserfact = (GstElementFactory *) tmp->data;
    break;
  }

  if (parserfact)
    parser = gst_element_factory_create (parserfact, NULL);

  gst_plugin_feature_list_free (parsers);

beach:
  if (format)
    gst_caps_unref (format);

  return parser;
}

static GstElement *
_create_element_and_set_preset (GstElementFactory * factory,
    const gchar * preset, const gchar * name, const gchar * preset_name)
{
  GstElement *res = NULL;

  GST_DEBUG ("Creating element from factory %s (preset factory name: %s"
      " preset name: %s)", GST_OBJECT_NAME (factory), preset, preset_name);

  res = gst_element_factory_create (factory, name);

  if (preset && GST_IS_PRESET (res)) {
    if (preset_name == NULL ||
        g_strcmp0 (GST_OBJECT_NAME (factory), preset_name) == 0) {

      if (!gst_preset_load_preset (GST_PRESET (res), preset)) {
        GST_WARNING ("Couldn't set preset [%s] on element [%s]",
            preset, GST_OBJECT_NAME (factory));
        gst_object_unref (res);
        res = NULL;
      }
    } else {
      GST_DEBUG ("Using a preset with no preset name, making use of the"
          " proper element without setting any property");
    }
  } else if (preset_name && g_strcmp0 (GST_OBJECT_NAME (factory), preset_name)) {
    gst_object_unref (res);
    res = NULL;
  }
  /* Else we keep it */

  return res;
}

/* Create the encoder for the given stream profile */
static inline GstElement *
_get_encoder (GstEncodeBin * ebin, GstEncodingProfile * sprof)
{
  GList *encoders, *tmp;
  GstElement *encoder = NULL;
  GstElementFactory *encoderfact = NULL;
  GstCaps *format;
  const gchar *preset, *preset_name;

  format = gst_encoding_profile_get_format (sprof);
  preset = gst_encoding_profile_get_preset (sprof);
  preset_name = gst_encoding_profile_get_preset_name (sprof);

  GST_DEBUG ("Getting list of encoders for format %" GST_PTR_FORMAT, format);

  /* If stream caps are raw, return identity */
  if (G_UNLIKELY (are_raw_caps (format))) {
    GST_DEBUG ("Stream format is raw, returning identity as the encoder");
    encoder = gst_element_factory_make ("identity", NULL);
    goto beach;
  }

  encoders =
      gst_element_factory_list_filter (ebin->encoders, format,
      GST_PAD_SRC, FALSE);

  if (G_UNLIKELY (encoders == NULL)) {
    GST_DEBUG ("Couldn't find any compatible encoders");
    goto beach;
  }

  for (tmp = encoders; tmp; tmp = tmp->next) {
    encoderfact = (GstElementFactory *) tmp->data;
    if ((encoder = _create_element_and_set_preset (encoderfact, preset,
                NULL, preset_name)))
      break;
  }

  gst_plugin_feature_list_free (encoders);

beach:
  if (format)
    gst_caps_unref (format);

  return encoder;
}

static GstPad *
local_element_request_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * name, const GstCaps * caps)
{
  GstPad *newpad = NULL;
  GstElementClass *oclass;

  oclass = GST_ELEMENT_GET_CLASS (element);

  if (oclass->request_new_pad)
    newpad = (oclass->request_new_pad) (element, templ, name, caps);

  if (newpad)
    gst_object_ref (newpad);

  return newpad;
}

static GstPad *
gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
{
  GstPad *ret = NULL;
  GstPadPresence presence;

  /* If this function is ever exported, we need check the validity of `element'
   * and `templ', and to make sure the template actually belongs to the
   * element. */

  presence = GST_PAD_TEMPLATE_PRESENCE (templ);

  switch (presence) {
    case GST_PAD_ALWAYS:
    case GST_PAD_SOMETIMES:
      ret = gst_element_get_static_pad (element, templ->name_template);
      if (!ret && presence == GST_PAD_ALWAYS)
        g_warning
            ("Element %s has an ALWAYS template %s, but no pad of the same name",
            GST_OBJECT_NAME (element), templ->name_template);
      break;

    case GST_PAD_REQUEST:
      ret = gst_element_request_pad (element, templ, NULL, NULL);
      break;
  }

  return ret;
}

/* FIXME : Improve algorithm for finding compatible muxer sink pad */
static inline GstPad *
get_compatible_muxer_sink_pad (GstEncodeBin * ebin, GstElement * encoder,
    GstCaps * sinkcaps)
{
  GstPad *sinkpad;
  GstPadTemplate *srctempl = NULL;
  GstPadTemplate *sinktempl;

  if (encoder) {
    GstPad *srcpad;
    srcpad = gst_element_get_static_pad (encoder, "src");

    srctempl = gst_pad_get_pad_template (srcpad);

    GST_DEBUG_OBJECT (ebin,
        "Attempting to find pad from muxer %s compatible with %s:%s",
        GST_ELEMENT_NAME (ebin->muxer), GST_DEBUG_PAD_NAME (srcpad));

    gst_object_unref (srcpad);
    sinktempl = gst_element_get_compatible_pad_template (ebin->muxer, srctempl);
    gst_object_unref (srctempl);
  } else {
    srctempl =
        gst_pad_template_new ("whatever", GST_PAD_SRC, GST_PAD_ALWAYS,
        sinkcaps);
    g_assert (srctempl != NULL);
    sinktempl = gst_element_get_compatible_pad_template (ebin->muxer, srctempl);
    g_object_unref (srctempl);
  }

  if (G_UNLIKELY (sinktempl == NULL))
    goto no_template;

  sinkpad = gst_element_get_pad_from_template (ebin->muxer, sinktempl);

  return sinkpad;

no_template:
  {
    GST_WARNING_OBJECT (ebin, "No compatible pad available on muxer");
    return NULL;
  }
}

static gboolean
_has_class (GstElement * element, const gchar * classname)
{
  GstElementClass *klass;
  const gchar *value;

  klass = GST_ELEMENT_GET_CLASS (element);
  value = gst_element_class_get_metadata (klass, GST_ELEMENT_METADATA_KLASS);
  if (!value)
    return FALSE;

  return strstr (value, classname) != NULL;
}

static void
_profile_restriction_caps_cb (GstEncodingProfile * profile,
    GParamSpec * arg G_GNUC_UNUSED, StreamGroup * group)
{
  GstCaps *restriction = gst_encoding_profile_get_restriction (profile);

  g_object_set (group->capsfilter, "caps", restriction, NULL);
}

static void
_outfilter_caps_set_cb (GstPad * outfilter_sinkpad,
    GParamSpec * arg G_GNUC_UNUSED, StreamGroup * group)
{
  GstCaps *caps;

  g_object_get (outfilter_sinkpad, "caps", &caps, NULL);
  GST_INFO_OBJECT (group->ebin, "Forcing caps to %" GST_PTR_FORMAT, caps);
  g_object_set (group->outfilter, "caps", caps, NULL);
  g_signal_handler_disconnect (outfilter_sinkpad, group->outputfilter_caps_sid);
  group->outputfilter_caps_sid = 0;
}

static void
_set_group_caps_format (StreamGroup * sgroup, GstEncodingProfile * prof,
    GstCaps * format)
{
  g_object_set (sgroup->outfilter, "caps", format, NULL);

  if (!gst_encoding_profile_get_allow_dynamic_output (prof)) {
    if (!sgroup->outputfilter_caps_sid) {
      sgroup->outputfilter_caps_sid =
          g_signal_connect (sgroup->outfilter->sinkpads->data,
          "notify::caps", G_CALLBACK (_outfilter_caps_set_cb), sgroup);
    }
  }
}

static void
_post_missing_plugin_message (GstEncodeBin * ebin, GstEncodingProfile * prof)
{
  GstCaps *format;
  format = gst_encoding_profile_get_format (prof);

  GST_ERROR_OBJECT (ebin, "Couldn't create encoder for format %" GST_PTR_FORMAT,
      format);
  /* missing plugin support */
  gst_element_post_message (GST_ELEMENT_CAST (ebin),
      gst_missing_encoder_message_new (GST_ELEMENT_CAST (ebin), format));
  GST_ELEMENT_ERROR (ebin, CORE, MISSING_PLUGIN, (NULL),
      ("Couldn't create encoder for format %" GST_PTR_FORMAT, format));

  gst_caps_unref (format);
}

static GstPadProbeReturn
_missing_plugin_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
{
  StreamGroup *sgroup = udata;
  GstEncodeBin *ebin = sgroup->ebin;

  _post_missing_plugin_message (ebin, sgroup->profile);

  return GST_PAD_PROBE_OK;
}

static void
_set_up_fake_encoder_pad_probe (GstEncodeBin * ebin, StreamGroup * sgroup)
{
  GstPad *pad = gst_element_get_static_pad (sgroup->fakesink, "sink");

  gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER, _missing_plugin_probe,
      sgroup, NULL);

  gst_object_unref (pad);
}

/* FIXME : Add handling of streams that don't require conversion elements */
/*
 * Create the elements, StreamGroup, add the sink pad, link it to the muxer
 *
 * sinkpadname: If non-NULL, that name will be assigned to the sink ghost pad
 * sinkcaps: If non-NULL will be used to figure out how to setup the group */
static StreamGroup *
_create_stream_group (GstEncodeBin * ebin, GstEncodingProfile * sprof,
    const gchar * sinkpadname, GstCaps * sinkcaps)
{
  StreamGroup *sgroup = NULL;
  GstPad *sinkpad, *srcpad, *muxerpad = NULL;
  /* Element we will link to the encoder */
  GstElement *last = NULL;
  GstElement *encoder = NULL;
  GList *tmp, *tosync = NULL;
  GstCaps *format, *restriction;
  const gchar *missing_element_name;

  format = gst_encoding_profile_get_format (sprof);
  restriction = gst_encoding_profile_get_restriction (sprof);

  GST_DEBUG ("Creating group. format %" GST_PTR_FORMAT ", for caps %"
      GST_PTR_FORMAT, format, sinkcaps);
  GST_DEBUG ("avoid_reencoding:%d", ebin->avoid_reencoding);

  sgroup = g_slice_new0 (StreamGroup);
  sgroup->ebin = ebin;
  sgroup->profile = sprof;

  /* NOTE for people reading this code:
   * 
   * We construct the group starting by the furthest downstream element
   * and making our way up adding/syncing/linking as we go.
   *
   * There are two parallel paths:
   * * One for raw data which goes through converters and encoders
   * * One for already encoded data
   */

  /* Muxer.
   * If we are handling a container profile, figure out if the muxer has a
   * sinkpad compatible with the selected profile */
  if (ebin->muxer) {
    muxerpad = get_compatible_muxer_sink_pad (ebin, NULL, format);
    if (G_UNLIKELY (muxerpad == NULL))
      goto no_muxer_pad;

  }

  /* Output Queue.
   * We only use a 1buffer long queue here, the actual queueing will be done
   * in the input queue */
  last = sgroup->outqueue = gst_element_factory_make ("queue", NULL);
  g_object_set (sgroup->outqueue, "max-size-buffers", (guint32) 1,
      "max-size-bytes", (guint32) 0, "max-size-time", (guint64) 0,
      "silent", TRUE, NULL);

  gst_bin_add (GST_BIN (ebin), sgroup->outqueue);
  tosync = g_list_append (tosync, sgroup->outqueue);
  srcpad = gst_element_get_static_pad (sgroup->outqueue, "src");
  if (muxerpad) {
    if (G_UNLIKELY (fast_pad_link (srcpad, muxerpad) != GST_PAD_LINK_OK)) {
      goto muxer_link_failure;
    }
    gst_object_unref (muxerpad);
  } else {
    gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), srcpad);
  }
  gst_object_unref (srcpad);

  /* Check if we need a formatter
   * If we have no muxer or
   * if the muxer isn't a formatter and doesn't implement the tagsetter interface
   */
  if (!ebin->muxer || (!GST_IS_TAG_SETTER (ebin->muxer)
          && !_has_class (ebin->muxer, "Formatter"))) {
    sgroup->formatter = _get_formatter (ebin, sprof);
    if (sgroup->formatter) {
      GST_DEBUG ("Adding formatter for %" GST_PTR_FORMAT, format);

      gst_bin_add (GST_BIN (ebin), sgroup->formatter);
      tosync = g_list_append (tosync, sgroup->formatter);
      if (G_UNLIKELY (!fast_element_link (sgroup->formatter, last)))
        goto formatter_link_failure;
      last = sgroup->formatter;
    }
  }


  /* Output capsfilter
   * This will receive the format caps from the streamprofile */
  GST_DEBUG ("Adding output capsfilter for %" GST_PTR_FORMAT, format);
  sgroup->outfilter = gst_element_factory_make ("capsfilter", NULL);
  _set_group_caps_format (sgroup, sprof, format);

  gst_bin_add (GST_BIN (ebin), sgroup->outfilter);
  tosync = g_list_append (tosync, sgroup->outfilter);
  if (G_UNLIKELY (!fast_element_link (sgroup->outfilter, last)))
    goto outfilter_link_failure;
  last = sgroup->outfilter;


  sgroup->parser = _get_parser (ebin, sprof);

  if (sgroup->parser != NULL) {
    GST_DEBUG ("Got a parser %s", GST_ELEMENT_NAME (sgroup->parser));
    gst_bin_add (GST_BIN (ebin), sgroup->parser);
    tosync = g_list_append (tosync, sgroup->parser);
    if (G_UNLIKELY (!gst_element_link (sgroup->parser, last)))
      goto parser_link_failure;
    last = sgroup->parser;
  }

  /* Stream combiner */
  sgroup->combiner = g_object_new (GST_TYPE_STREAM_COMBINER, NULL);

  gst_bin_add (GST_BIN (ebin), sgroup->combiner);
  tosync = g_list_append (tosync, sgroup->combiner);
  if (G_UNLIKELY (!fast_element_link (sgroup->combiner, last)))
    goto combiner_link_failure;


  /* Stream splitter */
  sgroup->splitter = g_object_new (GST_TYPE_STREAM_SPLITTER, NULL);

  gst_bin_add (GST_BIN (ebin), sgroup->splitter);
  tosync = g_list_append (tosync, sgroup->splitter);

  /* Input queue
   * FIXME : figure out what max-size to use for the input queue */
  sgroup->inqueue = gst_element_factory_make ("queue", NULL);
  g_object_set (sgroup->inqueue, "max-size-buffers",
      (guint32) ebin->queue_buffers_max, "max-size-bytes",
      (guint32) ebin->queue_bytes_max, "max-size-time",
      (guint64) ebin->queue_time_max, "silent", TRUE, NULL);

  gst_bin_add (GST_BIN (ebin), sgroup->inqueue);
  tosync = g_list_append (tosync, sgroup->inqueue);
  if (G_UNLIKELY (!fast_element_link (sgroup->inqueue, sgroup->splitter)))
    goto splitter_link_failure;

  /* Expose input queue sink pad as ghostpad */
  sinkpad = gst_element_get_static_pad (sgroup->inqueue, "sink");
  if (sinkpadname == NULL) {
    gchar *pname =
        g_strdup_printf ("%s_%u", gst_encoding_profile_get_type_nick (sprof),
        ebin->last_pad_id++);
    GST_DEBUG ("Adding ghost pad %s", pname);
    sgroup->ghostpad = gst_ghost_pad_new (pname, sinkpad);
    g_free (pname);
  } else
    sgroup->ghostpad = gst_ghost_pad_new (sinkpadname, sinkpad);
  gst_object_unref (sinkpad);


  /* Path 1 : Already-encoded data */
  sinkpad =
      local_element_request_pad (sgroup->combiner, NULL, "passthroughsink",
      NULL);
  if (G_UNLIKELY (sinkpad == NULL))
    goto no_combiner_sinkpad;

  if (ebin->avoid_reencoding) {
    GstCaps *tmpcaps;

    GST_DEBUG ("Asked to use Smart Encoder");
    sgroup->smartencoder = g_object_new (GST_TYPE_SMART_ENCODER, NULL);

    /* Check if stream format is compatible */
    srcpad = gst_element_get_static_pad (sgroup->smartencoder, "src");
    tmpcaps = gst_pad_query_caps (srcpad, NULL);
    if (!gst_caps_can_intersect (tmpcaps, format)) {
      GST_DEBUG ("We don't have a smart encoder for the stream format");
      gst_object_unref (sgroup->smartencoder);
      sgroup->smartencoder = NULL;
    } else {
      gst_bin_add ((GstBin *) ebin, sgroup->smartencoder);
      fast_pad_link (srcpad, sinkpad);
      tosync = g_list_append (tosync, sgroup->smartencoder);
      sinkpad = gst_element_get_static_pad (sgroup->smartencoder, "sink");
    }
    gst_caps_unref (tmpcaps);
    g_object_unref (srcpad);
  }

  srcpad =
      local_element_request_pad (sgroup->splitter, NULL, "passthroughsrc",
      NULL);
  if (G_UNLIKELY (srcpad == NULL))
    goto no_splitter_srcpad;

  /* Go straight to splitter */
  if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK))
    goto passthrough_link_failure;
  g_object_unref (sinkpad);
  g_object_unref (srcpad);


  /* Path 2 : Conversion / Encoding */

  /* 1. Create the encoder */
  GST_LOG ("Adding encoder");
  sgroup->encoder = _get_encoder (ebin, sprof);
  if (sgroup->encoder != NULL) {
    gst_bin_add ((GstBin *) ebin, sgroup->encoder);
    tosync = g_list_append (tosync, sgroup->encoder);

    sinkpad =
        local_element_request_pad (sgroup->combiner, NULL, "encodingsink",
        NULL);
    if (G_UNLIKELY (sinkpad == NULL))
      goto no_combiner_sinkpad;
    srcpad = gst_element_get_static_pad (sgroup->encoder, "src");
    if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK))
      goto encoder_link_failure;
    g_object_unref (sinkpad);
    g_object_unref (srcpad);
  } else if (gst_encoding_profile_get_preset (sgroup->profile)
      || gst_encoding_profile_get_preset_name (sgroup->profile)) {
    _post_missing_plugin_message (ebin, sprof);
    goto cleanup;
  } else {
    /* passthrough can still work, if we discover that *
     * encoding is required we post a missing plugin message */
  }


  /* 3. Create the conversion/restriction elements */
  /* 3.1. capsfilter */
  GST_LOG ("Adding capsfilter for restriction caps : %" GST_PTR_FORMAT,
      restriction);

  last = sgroup->capsfilter = gst_element_factory_make ("capsfilter", NULL);
  if (restriction && !gst_caps_is_any (restriction))
    g_object_set (sgroup->capsfilter, "caps", restriction, NULL);
  gst_bin_add ((GstBin *) ebin, sgroup->capsfilter);
  tosync = g_list_append (tosync, sgroup->capsfilter);
  if (sgroup->encoder == NULL) {
    /* no encoder available but it might be possible to just do passthrough, so
     * let's just set up a fake pad to detect that encoding was attempted and
     * if so it posts the missing plugin message */
    sgroup->fakesink = gst_element_factory_make ("fakesink", NULL);
    g_object_set (sgroup->fakesink, "async", FALSE, NULL);
    gst_bin_add (GST_BIN_CAST (ebin), sgroup->fakesink);
    tosync = g_list_append (tosync, sgroup->fakesink);
    encoder = sgroup->fakesink;

    _set_up_fake_encoder_pad_probe (ebin, sgroup);
  } else {
    encoder = sgroup->encoder;
  }
  fast_element_link (sgroup->capsfilter, encoder);
  sgroup->restriction_sid = g_signal_connect (sprof, "notify::restriction-caps",
      G_CALLBACK (_profile_restriction_caps_cb), sgroup);

  /* 3.2. restriction elements */
  /* FIXME : Once we have properties for specific converters, use those */
  if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) {
    const gboolean native_video =
        ! !(ebin->flags & GST_ENCODEBIN_FLAG_NO_VIDEO_CONVERSION);
    GstElement *cspace = NULL, *scale, *vrate, *cspace2 = NULL;

    GST_LOG ("Adding conversion elements for video stream");

    if (!native_video) {
      cspace = gst_element_factory_make ("videoconvert", NULL);
      scale = gst_element_factory_make ("videoscale", NULL);
      if (!scale) {
        missing_element_name = "videoscale";
        goto missing_element;
      }
      /* 4-tap scaling and black borders */
      g_object_set (scale, "method", 2, "add-borders", TRUE, NULL);
      cspace2 = gst_element_factory_make ("videoconvert", NULL);

      if (!cspace || !cspace2) {
        missing_element_name = "videoconvert";
        goto missing_element;
      }

      gst_bin_add_many ((GstBin *) ebin, cspace, scale, cspace2, NULL);
      tosync = g_list_append (tosync, cspace);
      tosync = g_list_append (tosync, scale);
      tosync = g_list_append (tosync, cspace2);

      sgroup->converters = g_list_prepend (sgroup->converters, cspace);
      sgroup->converters = g_list_prepend (sgroup->converters, scale);
      sgroup->converters = g_list_prepend (sgroup->converters, cspace2);

      if (!fast_element_link (cspace, scale) ||
          !fast_element_link (scale, cspace2))
        goto converter_link_failure;
    }

    if (!gst_encoding_video_profile_get_variableframerate
        (GST_ENCODING_VIDEO_PROFILE (sprof))) {
      vrate = gst_element_factory_make ("videorate", NULL);
      if (!vrate) {
        missing_element_name = "videorate";
        goto missing_element;
      }

      gst_bin_add ((GstBin *) ebin, vrate);
      tosync = g_list_prepend (tosync, vrate);
      sgroup->converters = g_list_prepend (sgroup->converters, vrate);

      if ((!native_video && !fast_element_link (cspace2, vrate))
          || !fast_element_link (vrate, last))
        goto converter_link_failure;

      if (!native_video)
        last = cspace;
      else
        last = vrate;
    } else if (!native_video) {
      if (!fast_element_link (cspace2, last))
        goto converter_link_failure;
      last = cspace;
    }

  } else if (GST_IS_ENCODING_AUDIO_PROFILE (sprof)
      && !(ebin->flags & GST_ENCODEBIN_FLAG_NO_AUDIO_CONVERSION)) {
    GstElement *aconv, *ares, *arate, *aconv2;

    GST_LOG ("Adding conversion elements for audio stream");

    arate = gst_element_factory_make ("audiorate", NULL);
    g_object_set (arate, "tolerance", (guint64) ebin->tolerance, NULL);
    if (!arate) {
      missing_element_name = "audiorate";
      goto missing_element;
    }
    aconv = gst_element_factory_make ("audioconvert", NULL);
    aconv2 = gst_element_factory_make ("audioconvert", NULL);
    ares = gst_element_factory_make ("audioresample", NULL);
    if (!aconv || !aconv2) {
      missing_element_name = "audioconvert";
      goto missing_element;
    }
    if (!ares) {
      missing_element_name = "audioresample";
      goto missing_element;
    }

    gst_bin_add_many ((GstBin *) ebin, arate, aconv, ares, aconv2, NULL);
    tosync = g_list_append (tosync, arate);
    tosync = g_list_append (tosync, aconv);
    tosync = g_list_append (tosync, ares);
    tosync = g_list_append (tosync, aconv2);
    if (!fast_element_link (arate, aconv) ||
        !fast_element_link (aconv, ares) ||
        !fast_element_link (ares, aconv2) || !fast_element_link (aconv2, last))
      goto converter_link_failure;

    sgroup->converters = g_list_prepend (sgroup->converters, arate);
    sgroup->converters = g_list_prepend (sgroup->converters, aconv);
    sgroup->converters = g_list_prepend (sgroup->converters, ares);
    sgroup->converters = g_list_prepend (sgroup->converters, aconv2);

    last = arate;
  }

  /* Link to stream splitter */
  sinkpad = gst_element_get_static_pad (last, "sink");
  srcpad =
      local_element_request_pad (sgroup->splitter, NULL, "encodingsrc", NULL);
  if (G_UNLIKELY (srcpad == NULL))
    goto no_splitter_srcpad;
  if (G_UNLIKELY (fast_pad_link (srcpad, sinkpad) != GST_PAD_LINK_OK))
    goto splitter_encoding_failure;
  g_object_unref (sinkpad);
  g_object_unref (srcpad);

  /* End of Stream 2 setup */

  /* Sync all elements to parent state */
  for (tmp = tosync; tmp; tmp = tmp->next)
    gst_element_sync_state_with_parent ((GstElement *) tmp->data);
  g_list_free (tosync);

  /* Add ghostpad */
  GST_DEBUG ("Adding ghostpad %s:%s", GST_DEBUG_PAD_NAME (sgroup->ghostpad));
  gst_pad_set_active (sgroup->ghostpad, TRUE);
  gst_element_add_pad ((GstElement *) ebin, sgroup->ghostpad);

  /* Add StreamGroup to our list of streams */

  GST_DEBUG
      ("Done creating elements, adding StreamGroup to our controlled stream list");

  ebin->streams = g_list_prepend (ebin->streams, sgroup);

  if (format)
    gst_caps_unref (format);
  if (restriction)
    gst_caps_unref (restriction);

  return sgroup;

splitter_encoding_failure:
  GST_ERROR_OBJECT (ebin, "Error linking splitter to encoding stream");
  goto cleanup;

no_muxer_pad:
  GST_ERROR_OBJECT (ebin,
      "Couldn't find a compatible muxer pad to link encoder to");
  goto cleanup;

missing_element:
  gst_element_post_message (GST_ELEMENT_CAST (ebin),
      gst_missing_element_message_new (GST_ELEMENT_CAST (ebin),
          missing_element_name));
  GST_ELEMENT_ERROR (ebin, CORE, MISSING_PLUGIN,
      (_("Missing element '%s' - check your GStreamer installation."),
          missing_element_name), (NULL));
  goto cleanup;

encoder_link_failure:
  GST_ERROR_OBJECT (ebin, "Failed to link the encoder");
  goto cleanup;

muxer_link_failure:
  GST_ERROR_OBJECT (ebin, "Couldn't link encoder to muxer");
  goto cleanup;

formatter_link_failure:
  GST_ERROR_OBJECT (ebin, "Couldn't link output filter to output queue");
  goto cleanup;

outfilter_link_failure:
  GST_ERROR_OBJECT (ebin,
      "Couldn't link output filter to output queue/formatter");
  goto cleanup;

passthrough_link_failure:
  GST_ERROR_OBJECT (ebin, "Failed linking splitter in passthrough mode");
  goto cleanup;

no_splitter_srcpad:
  GST_ERROR_OBJECT (ebin, "Couldn't get a source pad from the splitter");
  goto cleanup;

no_combiner_sinkpad:
  GST_ERROR_OBJECT (ebin, "Couldn't get a sink pad from the combiner");
  goto cleanup;

splitter_link_failure:
  GST_ERROR_OBJECT (ebin, "Failure linking to the splitter");
  goto cleanup;

combiner_link_failure:
  GST_ERROR_OBJECT (ebin, "Failure linking to the combiner");
  goto cleanup;

parser_link_failure:
  GST_ERROR_OBJECT (ebin, "Failure linking the parser");
  goto cleanup;

converter_link_failure:
  GST_ERROR_OBJECT (ebin, "Failure linking the video converters");
  goto cleanup;

cleanup:
  /* FIXME : Actually properly cleanup everything */
  if (format)
    gst_caps_unref (format);
  if (restriction)
    gst_caps_unref (restriction);
  stream_group_free (ebin, sgroup);
  g_list_free (tosync);
  return NULL;
}

static gboolean
_gst_caps_match_foreach (GQuark field_id, const GValue * value, gpointer data)
{
  GstStructure *structure = data;
  const GValue *other_value = gst_structure_id_get_value (structure, field_id);

  if (G_UNLIKELY (other_value == NULL))
    return FALSE;
  if (gst_value_compare (value, other_value) == GST_VALUE_EQUAL) {
    return TRUE;
  }

  return FALSE;
}

/*
 * checks that there is at least one structure on caps_a that has
 * all its fields exactly the same as one structure on caps_b
 */
static gboolean
_gst_caps_match (const GstCaps * caps_a, const GstCaps * caps_b)
{
  gint i, j;
  gboolean res = FALSE;

  for (i = 0; i < gst_caps_get_size (caps_a); i++) {
    GstStructure *structure_a = gst_caps_get_structure (caps_a, i);
    for (j = 0; j < gst_caps_get_size (caps_b); j++) {
      GstStructure *structure_b = gst_caps_get_structure (caps_b, j);

      res = gst_structure_foreach (structure_a, _gst_caps_match_foreach,
          structure_b);
      if (res)
        goto end;
    }
  }
end:
  return res;
}

static gboolean
_factory_can_handle_caps (GstElementFactory * factory, const GstCaps * caps,
    GstPadDirection dir, gboolean exact)
{
  const GList *templates;

  templates = gst_element_factory_get_static_pad_templates (factory);
  while (templates) {
    GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;

    if (template->direction == dir) {
      GstCaps *tmp = gst_static_caps_get (&template->static_caps);

      if ((exact && _gst_caps_match (caps, tmp)) ||
          (!exact && gst_caps_can_intersect (tmp, caps))) {
        gst_caps_unref (tmp);
        return TRUE;
      }
      gst_caps_unref (tmp);
    }
    templates = g_list_next (templates);
  }

  return FALSE;
}

static inline GstElement *
_get_formatter (GstEncodeBin * ebin, GstEncodingProfile * sprof)
{
  GList *formatters, *tmpfmtr;
  GstElement *formatter = NULL;
  GstElementFactory *formatterfact = NULL;
  GstCaps *format;
  const gchar *preset, *preset_name;

  format = gst_encoding_profile_get_format (sprof);
  preset = gst_encoding_profile_get_preset (sprof);
  preset_name = gst_encoding_profile_get_preset_name (sprof);

  GST_DEBUG ("Getting list of formatters for format %" GST_PTR_FORMAT, format);

  formatters =
      gst_element_factory_list_filter (ebin->formatters, format, GST_PAD_SRC,
      FALSE);

  if (formatters == NULL)
    goto beach;

  /* FIXME : signal the user if he wants this */
  for (tmpfmtr = formatters; tmpfmtr; tmpfmtr = tmpfmtr->next) {
    formatterfact = (GstElementFactory *) tmpfmtr->data;

    GST_DEBUG_OBJECT (ebin, "Trying formatter %s",
        GST_OBJECT_NAME (formatterfact));

    if ((formatter =
            _create_element_and_set_preset (formatterfact, preset,
                NULL, preset_name)))
      break;
  }

  gst_plugin_feature_list_free (formatters);

beach:
  if (format)
    gst_caps_unref (format);
  return formatter;
}

static gint
compare_elements (gconstpointer a, gconstpointer b, gpointer udata)
{
  GstCaps *caps = udata;
  GstElementFactory *fac_a = (GstElementFactory *) a;
  GstElementFactory *fac_b = (GstElementFactory *) b;

  /* FIXME not quite sure this is the best algorithm to order the elements
   * Some caps similarity comparison algorithm would fit better than going
   * boolean (equals/not equals).
   */
  gboolean equals_a = _factory_can_handle_caps (fac_a, caps, GST_PAD_SRC, TRUE);
  gboolean equals_b = _factory_can_handle_caps (fac_b, caps, GST_PAD_SRC, TRUE);

  if (equals_a == equals_b) {
    return gst_plugin_feature_get_rank ((GstPluginFeature *) fac_b) -
        gst_plugin_feature_get_rank ((GstPluginFeature *) fac_a);
  } else if (equals_a) {
    return -1;
  } else if (equals_b) {
    return 1;
  }
  return 0;
}

static inline GstElement *
_get_muxer (GstEncodeBin * ebin)
{
  GList *muxers, *formatters, *tmpmux;
  GstElement *muxer = NULL;
  GstElementFactory *muxerfact = NULL;
  const GList *tmp;
  GstCaps *format;
  const gchar *preset, *preset_name;

  format = gst_encoding_profile_get_format (ebin->profile);
  preset = gst_encoding_profile_get_preset (ebin->profile);
  preset_name = gst_encoding_profile_get_preset_name (ebin->profile);

  GST_DEBUG ("Getting list of muxers for format %" GST_PTR_FORMAT, format);

  muxers =
      gst_element_factory_list_filter (ebin->muxers, format, GST_PAD_SRC, TRUE);

  formatters =
      gst_element_factory_list_filter (ebin->formatters, format, GST_PAD_SRC,
      TRUE);

  muxers = g_list_sort_with_data (muxers, compare_elements, (gpointer) format);
  formatters =
      g_list_sort_with_data (formatters, compare_elements, (gpointer) format);

  muxers = g_list_concat (muxers, formatters);

  if (muxers == NULL)
    goto beach;

  /* FIXME : signal the user if he wants this */
  for (tmpmux = muxers; tmpmux; tmpmux = tmpmux->next) {
    gboolean cansinkstreams = TRUE;
    const GList *profiles =
        gst_encoding_container_profile_get_profiles
        (GST_ENCODING_CONTAINER_PROFILE (ebin->profile));

    muxerfact = (GstElementFactory *) tmpmux->data;

    GST_DEBUG ("Trying muxer %s", GST_OBJECT_NAME (muxerfact));

    /* See if the muxer can sink all of our stream profile caps */
    for (tmp = profiles; tmp; tmp = tmp->next) {
      GstEncodingProfile *sprof = (GstEncodingProfile *) tmp->data;
      GstCaps *sformat = gst_encoding_profile_get_format (sprof);

      if (!_factory_can_handle_caps (muxerfact, sformat, GST_PAD_SINK, FALSE)) {
        GST_DEBUG ("Skipping muxer because it can't sink caps %"
            GST_PTR_FORMAT, sformat);
        cansinkstreams = FALSE;
        if (sformat)
          gst_caps_unref (sformat);
        break;
      }
      if (sformat)
        gst_caps_unref (sformat);
    }

    /* Only use a muxer than can use all streams and than can accept the
     * preset (which may be present or not) */
    if (cansinkstreams && (muxer =
            _create_element_and_set_preset (muxerfact, preset, "muxer",
                preset_name)))
      break;
  }

  gst_plugin_feature_list_free (muxers);

beach:
  if (format)
    gst_caps_unref (format);
  return muxer;
}

static gboolean
create_elements_and_pads (GstEncodeBin * ebin)
{
  gboolean ret = TRUE;
  GstElement *muxer = NULL;
  GstPad *muxerpad;
  const GList *tmp, *profiles;
  GstEncodingProfile *sprof;

  GST_DEBUG ("Current profile : %s",
      gst_encoding_profile_get_name (ebin->profile));

  if (GST_IS_ENCODING_CONTAINER_PROFILE (ebin->profile)) {
    /* 1. Get the compatible muxer */
    muxer = _get_muxer (ebin);
    if (G_UNLIKELY (muxer == NULL))
      goto no_muxer;

    /* Record the muxer */
    ebin->muxer = muxer;
    gst_bin_add ((GstBin *) ebin, muxer);

    /* 2. Ghost the muxer source pad */

    /* FIXME : We should figure out if it's a static/request/dyamic pad, 
     * but for the time being let's assume it's a static pad :) */
    muxerpad = gst_element_get_static_pad (muxer, "src");
    if (G_UNLIKELY (muxerpad == NULL))
      goto no_muxer_pad;

    if (!gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), muxerpad))
      goto no_muxer_ghost_pad;

    gst_object_unref (muxerpad);
    /* 3. Activate fixed presence streams */
    profiles =
        gst_encoding_container_profile_get_profiles
        (GST_ENCODING_CONTAINER_PROFILE (ebin->profile));
    for (tmp = profiles; tmp; tmp = tmp->next) {
      sprof = (GstEncodingProfile *) tmp->data;

      GST_DEBUG ("Trying stream profile with presence %d",
          gst_encoding_profile_get_presence (sprof));

      if (gst_encoding_profile_get_presence (sprof) != 0 &&
          gst_encoding_profile_is_enabled (sprof)) {
        if (G_UNLIKELY (_create_stream_group (ebin, sprof, NULL, NULL) == NULL))
          goto stream_error;
      }
    }
    gst_element_sync_state_with_parent (muxer);
  } else {
    if (G_UNLIKELY (_create_stream_group (ebin, ebin->profile, NULL,
                NULL) == NULL))
      goto stream_error;
  }

  return ret;

no_muxer:
  {
    GstCaps *format = gst_encoding_profile_get_format (ebin->profile);

    GST_WARNING ("No available muxer for %" GST_PTR_FORMAT, format);
    /* missing plugin support */
    gst_element_post_message (GST_ELEMENT_CAST (ebin),
        gst_missing_encoder_message_new (GST_ELEMENT_CAST (ebin), format));
    GST_ELEMENT_ERROR (ebin, CORE, MISSING_PLUGIN, (NULL),
        ("No available muxer for format %" GST_PTR_FORMAT, format));
    if (format)
      gst_caps_unref (format);
    return FALSE;
  }

no_muxer_pad:
  {
    GST_WARNING ("Can't get source pad from muxer (%s)",
        GST_ELEMENT_NAME (muxer));
    gst_bin_remove (GST_BIN (ebin), muxer);
    return FALSE;
  }

no_muxer_ghost_pad:
  {
    GST_WARNING ("Couldn't set %s:%s as source ghostpad target",
        GST_DEBUG_PAD_NAME (muxerpad));
    gst_bin_remove (GST_BIN (ebin), muxer);
    gst_object_unref (muxerpad);
    return FALSE;
  }

stream_error:
  {
    GST_WARNING ("Could not create Streams");
    if (muxer)
      gst_bin_remove (GST_BIN (ebin), muxer);
    ebin->muxer = NULL;
    return FALSE;
  }
}

static void
release_pads (const GValue * item, GstElement * elt)
{
  GstPad *pad = g_value_get_object (item);
  GstPad *peer = NULL;

  GST_DEBUG_OBJECT (elt, "Releasing pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  /* Unlink from its peer pad */
  if ((peer = gst_pad_get_peer (pad))) {
    if (GST_PAD_DIRECTION (peer) == GST_PAD_SRC)
      gst_pad_unlink (peer, pad);
    else
      gst_pad_unlink (pad, peer);
    gst_object_unref (peer);
  }

  /* Release it from the object */
  gst_element_release_request_pad (elt, pad);
}

static void
stream_group_free (GstEncodeBin * ebin, StreamGroup * sgroup)
{
  GList *tmp;
  GstPad *tmppad;
  GstPad *pad;

  GST_DEBUG_OBJECT (ebin, "Freeing StreamGroup %p", sgroup);

  if (sgroup->restriction_sid != 0)
    g_signal_handler_disconnect (sgroup->profile, sgroup->restriction_sid);

  if (ebin->muxer) {
    /* outqueue - Muxer */
    tmppad = gst_element_get_static_pad (sgroup->outqueue, "src");
    pad = gst_pad_get_peer (tmppad);

    if (pad) {
      /* Remove muxer request sink pad */
      gst_pad_unlink (tmppad, pad);
      if (GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad)) ==
          GST_PAD_REQUEST)
        gst_element_release_request_pad (ebin->muxer, pad);
      gst_object_unref (pad);
    }
    gst_object_unref (tmppad);
  }
  if (sgroup->outqueue)
    gst_element_set_state (sgroup->outqueue, GST_STATE_NULL);

  if (sgroup->formatter) {
    /* capsfilter - formatter - outqueue */
    gst_element_set_state (sgroup->formatter, GST_STATE_NULL);
    gst_element_set_state (sgroup->outfilter, GST_STATE_NULL);
    gst_element_unlink (sgroup->formatter, sgroup->outqueue);
    gst_element_unlink (sgroup->outfilter, sgroup->formatter);
  } else {
    /* Capsfilter - outqueue */
    gst_element_set_state (sgroup->outfilter, GST_STATE_NULL);
    gst_element_unlink (sgroup->outfilter, sgroup->outqueue);
  }
  gst_element_set_state (sgroup->outqueue, GST_STATE_NULL);
  gst_bin_remove (GST_BIN (ebin), sgroup->outqueue);

  /* streamcombiner - parser - capsfilter */
  if (sgroup->parser) {
    gst_element_set_state (sgroup->parser, GST_STATE_NULL);
    gst_element_unlink (sgroup->parser, sgroup->outfilter);
    gst_element_unlink (sgroup->combiner, sgroup->parser);
    gst_bin_remove ((GstBin *) ebin, sgroup->parser);
  }

  /* Sink Ghostpad */
  if (sgroup->ghostpad) {
    if (GST_PAD_PARENT (sgroup->ghostpad) != NULL)
      gst_element_remove_pad (GST_ELEMENT_CAST (ebin), sgroup->ghostpad);
    else
      gst_object_unref (sgroup->ghostpad);
  }

  if (sgroup->inqueue)
    gst_element_set_state (sgroup->inqueue, GST_STATE_NULL);

  if (sgroup->encoder)
    gst_element_set_state (sgroup->encoder, GST_STATE_NULL);
  if (sgroup->fakesink)
    gst_element_set_state (sgroup->fakesink, GST_STATE_NULL);
  if (sgroup->outfilter) {
    gst_element_set_state (sgroup->outfilter, GST_STATE_NULL);

    if (sgroup->outputfilter_caps_sid) {
      g_signal_handler_disconnect (sgroup->outfilter->sinkpads->data,
          sgroup->outputfilter_caps_sid);
      sgroup->outputfilter_caps_sid = 0;
    }
  }
  if (sgroup->smartencoder)
    gst_element_set_state (sgroup->smartencoder, GST_STATE_NULL);

  if (sgroup->capsfilter) {
    gst_element_set_state (sgroup->capsfilter, GST_STATE_NULL);
    if (sgroup->encoder)
      gst_element_unlink (sgroup->capsfilter, sgroup->encoder);
    else
      gst_element_unlink (sgroup->capsfilter, sgroup->fakesink);
    gst_bin_remove ((GstBin *) ebin, sgroup->capsfilter);
  }

  for (tmp = sgroup->converters; tmp; tmp = tmp->next) {
    GstElement *elt = (GstElement *) tmp->data;

    gst_element_set_state (elt, GST_STATE_NULL);
    gst_bin_remove ((GstBin *) ebin, elt);
  }
  if (sgroup->converters)
    g_list_free (sgroup->converters);

  if (sgroup->combiner) {
    GstIterator *it = gst_element_iterate_sink_pads (sgroup->combiner);
    GstIteratorResult itret = GST_ITERATOR_OK;

    while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) {
      itret =
          gst_iterator_foreach (it, (GstIteratorForeachFunction) release_pads,
          sgroup->combiner);
      gst_iterator_resync (it);
    }
    gst_iterator_free (it);
    gst_element_set_state (sgroup->combiner, GST_STATE_NULL);
    gst_bin_remove ((GstBin *) ebin, sgroup->combiner);
  }

  if (sgroup->splitter) {
    GstIterator *it = gst_element_iterate_src_pads (sgroup->splitter);
    GstIteratorResult itret = GST_ITERATOR_OK;
    while (itret == GST_ITERATOR_OK || itret == GST_ITERATOR_RESYNC) {
      itret =
          gst_iterator_foreach (it, (GstIteratorForeachFunction) release_pads,
          sgroup->splitter);
      gst_iterator_resync (it);
    }
    gst_iterator_free (it);

    gst_element_set_state (sgroup->splitter, GST_STATE_NULL);
    gst_bin_remove ((GstBin *) ebin, sgroup->splitter);
  }

  if (sgroup->inqueue)
    gst_bin_remove ((GstBin *) ebin, sgroup->inqueue);

  if (sgroup->encoder)
    gst_bin_remove ((GstBin *) ebin, sgroup->encoder);

  if (sgroup->fakesink)
    gst_bin_remove ((GstBin *) ebin, sgroup->fakesink);

  if (sgroup->smartencoder)
    gst_bin_remove ((GstBin *) ebin, sgroup->smartencoder);

  if (sgroup->outfilter)
    gst_bin_remove ((GstBin *) ebin, sgroup->outfilter);

  g_slice_free (StreamGroup, sgroup);
}

static void
stream_group_remove (GstEncodeBin * ebin, StreamGroup * sgroup)
{
  ebin->streams = g_list_remove (ebin->streams, sgroup);

  stream_group_free (ebin, sgroup);
}

static void
gst_encode_bin_tear_down_profile (GstEncodeBin * ebin)
{
  if (G_UNLIKELY (ebin->profile == NULL))
    return;

  GST_DEBUG ("Tearing down profile %s",
      gst_encoding_profile_get_name (ebin->profile));

  while (ebin->streams)
    stream_group_remove (ebin, (StreamGroup *) ebin->streams->data);

  /* Set ghostpad target to NULL */
  gst_ghost_pad_set_target (GST_GHOST_PAD (ebin->srcpad), NULL);

  /* Remove muxer if present */
  if (ebin->muxer) {
    gst_element_set_state (ebin->muxer, GST_STATE_NULL);
    gst_bin_remove (GST_BIN (ebin), ebin->muxer);
    ebin->muxer = NULL;
  }

  /* free/clear profile */
  gst_encoding_profile_unref (ebin->profile);
  ebin->profile = NULL;
}

static gboolean
gst_encode_bin_setup_profile (GstEncodeBin * ebin, GstEncodingProfile * profile)
{
  gboolean res;

  g_return_val_if_fail (ebin->profile == NULL, FALSE);

  GST_DEBUG ("Setting up profile %p:%s (type:%s)", profile,
      gst_encoding_profile_get_name (profile),
      gst_encoding_profile_get_type_nick (profile));

  ebin->profile = profile;
  gst_object_ref (ebin->profile);

  /* Create elements */
  res = create_elements_and_pads (ebin);
  if (!res)
    gst_encode_bin_tear_down_profile (ebin);

  return res;
}

static gboolean
gst_encode_bin_set_profile (GstEncodeBin * ebin, GstEncodingProfile * profile)
{
  g_return_val_if_fail (GST_IS_ENCODING_PROFILE (profile), FALSE);

  GST_DEBUG_OBJECT (ebin, "profile (%p) : %s", profile,
      gst_encoding_profile_get_name (profile));

  if (G_UNLIKELY (ebin->active)) {
    GST_WARNING_OBJECT (ebin, "Element already active, can't change profile");
    return FALSE;
  }

  /* If we're not active, we can deactivate the previous profile */
  if (ebin->profile) {
    gst_encode_bin_tear_down_profile (ebin);
  }

  return gst_encode_bin_setup_profile (ebin, profile);
}

static inline gboolean
gst_encode_bin_activate (GstEncodeBin * ebin)
{
  ebin->active = ebin->profile != NULL;
  return ebin->active;
}

static void
gst_encode_bin_deactivate (GstEncodeBin * ebin)
{
  GList *tmp;

  for (tmp = ebin->streams; tmp; tmp = tmp->next) {
    StreamGroup *sgroup = tmp->data;
    GstCaps *format = gst_encoding_profile_get_format (sgroup->profile);

    _set_group_caps_format (sgroup, sgroup->profile, format);

    if (format)
      gst_caps_unref (format);
  }

  ebin->active = FALSE;
}

static GstStateChangeReturn
gst_encode_bin_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstEncodeBin *ebin = (GstEncodeBin *) element;

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      if (!gst_encode_bin_activate (ebin)) {
        ret = GST_STATE_CHANGE_FAILURE;
        goto beach;
      }
      break;
    default:
      break;
  }

  ret =
      GST_ELEMENT_CLASS (gst_encode_bin_parent_class)->change_state (element,
      transition);
  if (ret == GST_STATE_CHANGE_FAILURE)
    goto beach;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_encode_bin_deactivate (ebin);
      break;
    default:
      break;
  }

beach:
  return ret;
}


static gboolean
plugin_init (GstPlugin * plugin)
{
  gboolean res;

  GST_DEBUG_CATEGORY_INIT (gst_encode_bin_debug, "encodebin", 0, "encoder bin");

#ifdef ENABLE_NLS
  GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
      LOCALEDIR);
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */


  res = gst_element_register (plugin, "encodebin", GST_RANK_NONE,
      GST_TYPE_ENCODE_BIN);

  return res;
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    encoding,
    "various encoding-related elements", plugin_init, VERSION, GST_LICENSE,
    GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
