/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *                    2005 Wim Taymans <wim@fluendo.com>
 *                    2007 Andy Wingo <wingo at pobox.com>
 *                    2008 Sebastian Dröge <slomo@circular-chaos.org>
 *                    2014 Collabora
 *                        Olivier Crete <olivier.crete@collabora.com>
 *
 * gstaudiointerleave.c: audiointerleave element, N in, one out,
 * samples are added
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:element-audiointerleave
 *
 *
 */

/* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
 * with newer GLib versions (>= 2.31.0) */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

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

#include "gstaudiointerleave.h"
#include <gst/audio/audio.h>

#include <string.h>

#define GST_CAT_DEFAULT gst_audio_interleave_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_PAD_0,
  PROP_PAD_CHANNEL
};

G_DEFINE_TYPE (GstAudioInterleavePad, gst_audio_interleave_pad,
    GST_TYPE_AUDIO_AGGREGATOR_PAD);

static void
gst_audio_interleave_pad_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioInterleavePad *pad = GST_AUDIO_INTERLEAVE_PAD (object);

  switch (prop_id) {
    case PROP_PAD_CHANNEL:
      g_value_set_uint (value, pad->channel);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


static void
gst_audio_interleave_pad_class_init (GstAudioInterleavePadClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  gobject_class->get_property = gst_audio_interleave_pad_get_property;

  g_object_class_install_property (gobject_class,
      PROP_PAD_CHANNEL,
      g_param_spec_uint ("channel",
          "Channel number",
          "Number of the channel of this pad in the output", 0, G_MAXUINT, 0,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}

static void
gst_audio_interleave_pad_init (GstAudioInterleavePad * pad)
{
}

enum
{
  PROP_0,
  PROP_CHANNEL_POSITIONS,
  PROP_CHANNEL_POSITIONS_FROM_INPUT
};

/* elementfactory information */

#if G_BYTE_ORDER == G_LITTLE_ENDIAN
#define CAPS \
  GST_AUDIO_CAPS_MAKE ("{ S32LE, U32LE, S16LE, U16LE, S8, U8, F32LE, F64LE }") \
  ", layout = (string) { interleaved, non-interleaved }"
#else
#define CAPS \
  GST_AUDIO_CAPS_MAKE ("{ S32BE, U32BE, S16BE, U16BE, S8, U8, F32BE, F64BE }") \
  ", layout = (string) { interleaved, non-interleaved }"
#endif

static GstStaticPadTemplate gst_audio_interleave_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("audio/x-raw, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) 1, "
        "format = (string) " GST_AUDIO_FORMATS_ALL ", "
        "layout = (string) {non-interleaved, interleaved}")
    );

static GstStaticPadTemplate gst_audio_interleave_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) [ 1, MAX ], "
        "format = (string) " GST_AUDIO_FORMATS_ALL ", "
        "layout = (string) interleaved")
    );

static void gst_audio_interleave_child_proxy_init (gpointer g_iface,
    gpointer iface_data);

#define gst_audio_interleave_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstAudioInterleave, gst_audio_interleave,
    GST_TYPE_AUDIO_AGGREGATOR, G_IMPLEMENT_INTERFACE (GST_TYPE_CHILD_PROXY,
        gst_audio_interleave_child_proxy_init));

static void gst_audio_interleave_finalize (GObject * object);
static void gst_audio_interleave_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_audio_interleave_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_audio_interleave_setcaps (GstAudioInterleave * self,
    GstPad * pad, GstCaps * caps);
static GstPad *gst_audio_interleave_request_new_pad (GstElement * element,
    GstPadTemplate * temp, const gchar * req_name, const GstCaps * caps);
static void gst_audio_interleave_release_pad (GstElement * element,
    GstPad * pad);

static gboolean gst_audio_interleave_stop (GstAggregator * agg);

static gboolean
gst_audio_interleave_aggregate_one_buffer (GstAudioAggregator * aagg,
    GstAudioAggregatorPad * aaggpad, GstBuffer * inbuf, guint in_offset,
    GstBuffer * outbuf, guint out_offset, guint num_samples);


static void
__remove_channels (GstCaps * caps)
{
  GstStructure *s;
  gint i, size;

  size = gst_caps_get_size (caps);
  for (i = 0; i < size; i++) {
    s = gst_caps_get_structure (caps, i);
    gst_structure_remove_field (s, "channel-mask");
    gst_structure_remove_field (s, "channels");
  }
}

static void
__set_channels (GstCaps * caps, gint channels)
{
  GstStructure *s;
  gint i, size;

  size = gst_caps_get_size (caps);
  for (i = 0; i < size; i++) {
    s = gst_caps_get_structure (caps, i);
    if (channels > 0)
      gst_structure_set (s, "channels", G_TYPE_INT, channels, NULL);
    else
      gst_structure_set (s, "channels", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);
  }
}

/* we can only accept caps that we and downstream can handle.
 * if we have filtercaps set, use those to constrain the target caps.
 */
static GstCaps *
gst_audio_interleave_sink_getcaps (GstAggregator * agg, GstPad * pad,
    GstCaps * filter)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (agg);
  GstCaps *result = NULL, *peercaps, *sinkcaps;

  GST_OBJECT_LOCK (self);
  /* If we already have caps on one of the sink pads return them */
  if (self->sinkcaps)
    result = gst_caps_copy (self->sinkcaps);
  GST_OBJECT_UNLOCK (self);

  if (result == NULL) {
    /* get the downstream possible caps */
    peercaps = gst_pad_peer_query_caps (agg->srcpad, NULL);

    /* get the allowed caps on this sinkpad */
    sinkcaps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
    __remove_channels (sinkcaps);
    if (peercaps) {
      peercaps = gst_caps_make_writable (peercaps);
      __remove_channels (peercaps);
      /* if the peer has caps, intersect */
      GST_DEBUG_OBJECT (pad, "intersecting peer and template caps");
      result = gst_caps_intersect (peercaps, sinkcaps);
      gst_caps_unref (peercaps);
      gst_caps_unref (sinkcaps);
    } else {
      /* the peer has no caps (or there is no peer), just use the allowed caps
       * of this sinkpad. */
      GST_DEBUG_OBJECT (pad, "no peer caps, using sinkcaps");
      result = sinkcaps;
    }
    __set_channels (result, 1);
  }

  if (filter != NULL) {
    GstCaps *caps = result;

    GST_LOG_OBJECT (pad, "intersecting filter caps %" GST_PTR_FORMAT " with "
        "preliminary result %" GST_PTR_FORMAT, filter, caps);

    result = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
  }

  GST_DEBUG_OBJECT (pad, "Returning caps %" GST_PTR_FORMAT, result);

  return result;
}

static gboolean
gst_audio_interleave_sink_query (GstAggregator * agg, GstAggregatorPad * aggpad,
    GstQuery * query)
{
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter, *caps;

      gst_query_parse_caps (query, &filter);
      caps = gst_audio_interleave_sink_getcaps (agg, GST_PAD (aggpad), filter);
      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
      res = TRUE;
      break;
    }
    default:
      res =
          GST_AGGREGATOR_CLASS (parent_class)->sink_query (agg, aggpad, query);
      break;
  }

  return res;
}

static gint
compare_positions (gconstpointer a, gconstpointer b, gpointer user_data)
{
  const gint i = *(const gint *) a;
  const gint j = *(const gint *) b;
  const gint *pos = (const gint *) user_data;

  if (pos[i] < pos[j])
    return -1;
  else if (pos[i] > pos[j])
    return 1;
  else
    return 0;
}

static gboolean
gst_audio_interleave_channel_positions_to_mask (GValueArray * positions,
    gint default_ordering_map[64], guint64 * mask)
{
  gint i;
  guint channels;
  GstAudioChannelPosition *pos;
  gboolean ret;

  channels = positions->n_values;
  pos = g_new (GstAudioChannelPosition, channels);

  for (i = 0; i < channels; i++) {
    GValue *val;

    val = g_value_array_get_nth (positions, i);
    pos[i] = g_value_get_enum (val);
  }

  /* sort the default ordering map according to the position order */
  for (i = 0; i < channels; i++) {
    default_ordering_map[i] = i;
  }
  g_qsort_with_data (default_ordering_map, channels,
      sizeof (*default_ordering_map), compare_positions, pos);

  ret = gst_audio_channel_positions_to_mask (pos, channels, FALSE, mask);
  g_free (pos);

  return ret;
}


/* Must be called with the object lock held */

static guint64
gst_audio_interleave_get_channel_mask (GstAudioInterleave * self)
{
  guint64 channel_mask = 0;

  if (self->channel_positions != NULL &&
      self->channels == self->channel_positions->n_values) {
    if (!gst_audio_interleave_channel_positions_to_mask
        (self->channel_positions, self->default_channels_ordering_map,
            &channel_mask)) {
      GST_WARNING_OBJECT (self, "Invalid channel positions, using NONE");
      channel_mask = 0;
    }
  } else {
    GST_WARNING_OBJECT (self, "Using NONE channel positions");
  }

  return channel_mask;
}


#define MAKE_FUNC(type) \
static void interleave_##type (guint##type *out, guint##type *in, \
    guint stride, guint nframes) \
{ \
  gint i; \
  \
  for (i = 0; i < nframes; i++) { \
    *out = in[i]; \
    out += stride; \
  } \
}

MAKE_FUNC (8);
MAKE_FUNC (16);
MAKE_FUNC (32);
MAKE_FUNC (64);

static void
interleave_24 (guint8 * out, guint8 * in, guint stride, guint nframes)
{
  gint i;

  for (i = 0; i < nframes; i++) {
    memcpy (out, in, 3);
    out += stride * 3;
    in += 3;
  }
}

static void
gst_audio_interleave_set_process_function (GstAudioInterleave * self,
    GstAudioInfo * info)
{
  switch (GST_AUDIO_INFO_WIDTH (info)) {
    case 8:
      self->func = (GstInterleaveFunc) interleave_8;
      break;
    case 16:
      self->func = (GstInterleaveFunc) interleave_16;
      break;
    case 24:
      self->func = (GstInterleaveFunc) interleave_24;
      break;
    case 32:
      self->func = (GstInterleaveFunc) interleave_32;
      break;
    case 64:
      self->func = (GstInterleaveFunc) interleave_64;
      break;
    default:
      g_assert_not_reached ();
      break;
  }
}


/* the first caps we receive on any of the sinkpads will define the caps for all
 * the other sinkpads because we can only mix streams with the same caps.
 */
static gboolean
gst_audio_interleave_setcaps (GstAudioInterleave * self, GstPad * pad,
    GstCaps * caps)
{
  GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (self);
  GstAudioInfo info;
  GValue *val;
  guint channel;
  gboolean new = FALSE;

  if (!gst_audio_info_from_caps (&info, caps))
    goto invalid_format;

  GST_OBJECT_LOCK (self);
  if (self->sinkcaps && !gst_caps_is_subset (caps, self->sinkcaps))
    goto cannot_change_caps;

  if (!self->sinkcaps) {
    GstCaps *sinkcaps = gst_caps_copy (caps);
    GstStructure *s = gst_caps_get_structure (sinkcaps, 0);

    gst_structure_remove_field (s, "channel-mask");

    GST_DEBUG_OBJECT (self, "setting sinkcaps %" GST_PTR_FORMAT, sinkcaps);

    gst_caps_replace (&self->sinkcaps, sinkcaps);

    gst_caps_unref (sinkcaps);
    new = TRUE;
    self->new_caps = TRUE;
  }

  if (self->channel_positions_from_input
      && GST_AUDIO_INFO_CHANNELS (&info) == 1) {
    channel = GST_AUDIO_INTERLEAVE_PAD (pad)->channel;
    val = g_value_array_get_nth (self->input_channel_positions, channel);
    g_value_set_enum (val, GST_AUDIO_INFO_POSITION (&info, 0));
  }
  GST_OBJECT_UNLOCK (self);

  gst_audio_aggregator_set_sink_caps (aagg, GST_AUDIO_AGGREGATOR_PAD (pad),
      caps);

  if (!new)
    return TRUE;

  GST_INFO_OBJECT (pad, "handle caps change to %" GST_PTR_FORMAT, caps);

  return TRUE;

  /* ERRORS */
invalid_format:
  {
    GST_WARNING_OBJECT (self, "invalid format set as caps: %" GST_PTR_FORMAT,
        caps);
    return FALSE;
  }
cannot_change_caps:
  {
    GST_OBJECT_UNLOCK (self);
    GST_WARNING_OBJECT (self, "caps of %" GST_PTR_FORMAT " already set, can't "
        "change", self->sinkcaps);
    return FALSE;
  }
}

static gboolean
gst_audio_interleave_sink_event (GstAggregator * agg, GstAggregatorPad * aggpad,
    GstEvent * event)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (agg);
  gboolean res = TRUE;

  GST_DEBUG_OBJECT (aggpad, "Got %s event on sink pad",
      GST_EVENT_TYPE_NAME (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      res = gst_audio_interleave_setcaps (self, GST_PAD_CAST (aggpad), caps);
      gst_event_unref (event);
      event = NULL;
      break;
    }
    default:
      break;
  }

  if (event != NULL)
    return GST_AGGREGATOR_CLASS (parent_class)->sink_event (agg, aggpad, event);

  return res;
}

static GstFlowReturn
gst_audio_interleave_aggregate (GstAggregator * aggregator, gboolean timeout)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (aggregator);
  GstAudioAggregator *aagg = GST_AUDIO_AGGREGATOR (aggregator);

  GST_OBJECT_LOCK (aggregator);
  if (self->new_caps) {
    GstCaps *srccaps;
    GstStructure *s;
    gboolean ret;

    if (self->sinkcaps == NULL || self->channels == 0) {
      /* In this case, let the base class handle it */
      goto not_negotiated;
    }

    srccaps = gst_caps_copy (self->sinkcaps);
    s = gst_caps_get_structure (srccaps, 0);

    gst_structure_set (s, "channels", G_TYPE_INT, self->channels, "layout",
        G_TYPE_STRING, "interleaved", "channel-mask", GST_TYPE_BITMASK,
        gst_audio_interleave_get_channel_mask (self), NULL);


    GST_OBJECT_UNLOCK (aggregator);
    ret = gst_audio_aggregator_set_src_caps (aagg, srccaps);
    gst_caps_unref (srccaps);

    if (!ret)
      goto src_did_not_accept;

    GST_OBJECT_LOCK (aggregator);

    gst_audio_interleave_set_process_function (self, &aagg->info);

    self->new_caps = FALSE;
  }

not_negotiated:
  GST_OBJECT_UNLOCK (aggregator);

  return GST_AGGREGATOR_CLASS (parent_class)->aggregate (aggregator, timeout);

src_did_not_accept:
  GST_WARNING_OBJECT (self, "src did not accept setcaps()");
  return GST_FLOW_NOT_NEGOTIATED;;
}

static void
gst_audio_interleave_class_init (GstAudioInterleaveClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *gstelement_class = (GstElementClass *) klass;
  GstAggregatorClass *agg_class = (GstAggregatorClass *) klass;
  GstAudioAggregatorClass *aagg_class = (GstAudioAggregatorClass *) klass;

  GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "audiointerleave", 0,
      "audio interleaving element");

  gobject_class->set_property = gst_audio_interleave_set_property;
  gobject_class->get_property = gst_audio_interleave_get_property;
  gobject_class->finalize = gst_audio_interleave_finalize;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_audio_interleave_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_audio_interleave_sink_template));
  gst_element_class_set_static_metadata (gstelement_class, "AudioInterleave",
      "Generic/Audio",
      "Mixes multiple audio streams",
      "Olivier Crete <olivier.crete@collabora.com>");

  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_audio_interleave_request_new_pad);
  gstelement_class->release_pad =
      GST_DEBUG_FUNCPTR (gst_audio_interleave_release_pad);


  agg_class->sinkpads_type = GST_TYPE_AUDIO_INTERLEAVE_PAD;

  agg_class->sink_query = GST_DEBUG_FUNCPTR (gst_audio_interleave_sink_query);
  agg_class->sink_event = GST_DEBUG_FUNCPTR (gst_audio_interleave_sink_event);
  agg_class->stop = gst_audio_interleave_stop;
  agg_class->aggregate = gst_audio_interleave_aggregate;

  aagg_class->aggregate_one_buffer = gst_audio_interleave_aggregate_one_buffer;


  /**
   * GstInterleave:channel-positions
   * 
   * Channel positions: This property controls the channel positions
   * that are used on the src caps. The number of elements should be
   * the same as the number of sink pads and the array should contain
   * a valid list of channel positions. The n-th element of the array
   * is the position of the n-th sink pad.
   *
   * These channel positions will only be used if they're valid and the
   * number of elements is the same as the number of channels. If this
   * is not given a NONE layout will be used.
   *
   */
  g_object_class_install_property (gobject_class, PROP_CHANNEL_POSITIONS,
      g_param_spec_value_array ("channel-positions", "Channel positions",
          "Channel positions used on the output",
          g_param_spec_enum ("channel-position", "Channel position",
              "Channel position of the n-th input",
              GST_TYPE_AUDIO_CHANNEL_POSITION,
              GST_AUDIO_CHANNEL_POSITION_NONE,
              G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS),
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  /**
   * GstInterleave:channel-positions-from-input
   * 
   * Channel positions from input: If this property is set to %TRUE the channel
   * positions will be taken from the input caps if valid channel positions for
   * the output can be constructed from them. If this is set to %TRUE setting the
   * channel-positions property overwrites this property again.
   *
   */
  g_object_class_install_property (gobject_class,
      PROP_CHANNEL_POSITIONS_FROM_INPUT,
      g_param_spec_boolean ("channel-positions-from-input",
          "Channel positions from input",
          "Take channel positions from the input", TRUE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_audio_interleave_init (GstAudioInterleave * self)
{
  self->input_channel_positions = g_value_array_new (0);
  self->channel_positions_from_input = TRUE;
  self->channel_positions = self->input_channel_positions;
}

static void
gst_audio_interleave_finalize (GObject * object)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (object);

  if (self->channel_positions
      && self->channel_positions != self->input_channel_positions) {
    g_value_array_free (self->channel_positions);
    self->channel_positions = NULL;
  }

  if (self->input_channel_positions) {
    g_value_array_free (self->input_channel_positions);
    self->input_channel_positions = NULL;
  }

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

static void
gst_audio_interleave_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (object);

  switch (prop_id) {
    case PROP_CHANNEL_POSITIONS:
      g_return_if_fail (
          ((GValueArray *) g_value_get_boxed (value))->n_values > 0);

      if (self->channel_positions &&
          self->channel_positions != self->input_channel_positions)
        g_value_array_free (self->channel_positions);

      self->channel_positions = g_value_dup_boxed (value);
      self->channel_positions_from_input = FALSE;
      break;
    case PROP_CHANNEL_POSITIONS_FROM_INPUT:
      self->channel_positions_from_input = g_value_get_boolean (value);

      if (self->channel_positions_from_input) {
        if (self->channel_positions &&
            self->channel_positions != self->input_channel_positions)
          g_value_array_free (self->channel_positions);
        self->channel_positions = self->input_channel_positions;
      }
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_audio_interleave_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (object);

  switch (prop_id) {
    case PROP_CHANNEL_POSITIONS:
      g_value_set_boxed (value, self->channel_positions);
      break;
    case PROP_CHANNEL_POSITIONS_FROM_INPUT:
      g_value_set_boolean (value, self->channel_positions_from_input);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_audio_interleave_stop (GstAggregator * agg)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (agg);

  if (!GST_AGGREGATOR_CLASS (parent_class)->stop (agg))
    return FALSE;

  self->new_caps = FALSE;
  gst_caps_replace (&self->sinkcaps, NULL);

  return TRUE;
}

static GstPad *
gst_audio_interleave_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (element);
  GstAudioInterleavePad *newpad;
  gchar *pad_name;
  gint channel, padnumber;
  GValue val = { 0, };

  /* FIXME: We ignore req_name, this is evil! */

  padnumber = g_atomic_int_add (&self->padcounter, 1);
  channel = g_atomic_int_add (&self->channels, 1);
  if (!self->channel_positions_from_input)
    channel = padnumber;

  pad_name = g_strdup_printf ("sink_%u", padnumber);
  newpad = (GstAudioInterleavePad *)
      GST_ELEMENT_CLASS (parent_class)->request_new_pad (element,
      templ, pad_name, caps);
  g_free (pad_name);
  if (newpad == NULL)
    goto could_not_create;

  newpad->channel = channel;
  gst_pad_use_fixed_caps (GST_PAD (newpad));

  gst_child_proxy_child_added (GST_CHILD_PROXY (element), G_OBJECT (newpad),
      GST_OBJECT_NAME (newpad));


  g_value_init (&val, GST_TYPE_AUDIO_CHANNEL_POSITION);
  g_value_set_enum (&val, GST_AUDIO_CHANNEL_POSITION_NONE);
  self->input_channel_positions =
      g_value_array_append (self->input_channel_positions, &val);
  g_value_unset (&val);

  /* Update the src caps if we already have them */
  GST_OBJECT_LOCK (self);
  self->new_caps = TRUE;
  GST_OBJECT_UNLOCK (self);

  return GST_PAD_CAST (newpad);

could_not_create:
  {
    GST_DEBUG_OBJECT (element, "could not create/add  pad");
    return NULL;
  }
}

static void
gst_audio_interleave_release_pad (GstElement * element, GstPad * pad)
{
  GstAudioInterleave *self;
  gint position;
  GList *l;

  self = GST_AUDIO_INTERLEAVE (element);

  /* Take lock to make sure we're not changing this when processing buffers */
  GST_OBJECT_LOCK (self);

  g_atomic_int_add (&self->channels, -1);

  position = GST_AUDIO_INTERLEAVE_PAD (pad)->channel;
  g_value_array_remove (self->input_channel_positions, position);

  /* Update channel numbers */
  /* Taken above, GST_OBJECT_LOCK (self); */
  for (l = GST_ELEMENT_CAST (self)->sinkpads; l != NULL; l = l->next) {
    GstAudioInterleavePad *ipad = GST_AUDIO_INTERLEAVE_PAD (l->data);

    if (GST_AUDIO_INTERLEAVE_PAD (pad)->channel < ipad->channel)
      ipad->channel--;
  }

  self->new_caps = TRUE;
  GST_OBJECT_UNLOCK (self);


  GST_DEBUG_OBJECT (self, "release pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  gst_child_proxy_child_removed (GST_CHILD_PROXY (self), G_OBJECT (pad),
      GST_OBJECT_NAME (pad));

  GST_ELEMENT_CLASS (parent_class)->release_pad (element, pad);
}


/* Called with object lock and pad object lock held */
static gboolean
gst_audio_interleave_aggregate_one_buffer (GstAudioAggregator * aagg,
    GstAudioAggregatorPad * aaggpad, GstBuffer * inbuf, guint in_offset,
    GstBuffer * outbuf, guint out_offset, guint num_frames)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (aagg);
  GstAudioInterleavePad *pad = GST_AUDIO_INTERLEAVE_PAD (aaggpad);
  GstMapInfo inmap;
  GstMapInfo outmap;
  gint out_width, in_bpf, out_bpf, out_channels;
  guint8 *outdata;

  out_width = GST_AUDIO_INFO_WIDTH (&aagg->info) / 8;
  in_bpf = GST_AUDIO_INFO_BPF (&aaggpad->info);
  out_bpf = GST_AUDIO_INFO_BPF (&aagg->info);
  out_channels = GST_AUDIO_INFO_CHANNELS (&aagg->info);

  gst_buffer_map (outbuf, &outmap, GST_MAP_READWRITE);
  gst_buffer_map (inbuf, &inmap, GST_MAP_READ);
  GST_LOG_OBJECT (pad, "interleaves %u frames on channel %d/%d at offset %u"
      " from offset %u", num_frames, pad->channel, out_channels,
      out_offset * out_bpf, in_offset * in_bpf);

  outdata = outmap.data + (out_offset * out_bpf) +
      (out_width * self->default_channels_ordering_map[pad->channel]);


  self->func (outdata, inmap.data + (in_offset * in_bpf), out_channels,
      num_frames);


  gst_buffer_unmap (inbuf, &inmap);
  gst_buffer_unmap (outbuf, &outmap);

  return TRUE;
}


/* GstChildProxy implementation */
static GObject *
gst_audio_interleave_child_proxy_get_child_by_index (GstChildProxy *
    child_proxy, guint index)
{
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (child_proxy);
  GObject *obj = NULL;

  GST_OBJECT_LOCK (self);
  obj = g_list_nth_data (GST_ELEMENT_CAST (self)->sinkpads, index);
  if (obj)
    gst_object_ref (obj);
  GST_OBJECT_UNLOCK (self);

  return obj;
}

static guint
gst_audio_interleave_child_proxy_get_children_count (GstChildProxy *
    child_proxy)
{
  guint count = 0;
  GstAudioInterleave *self = GST_AUDIO_INTERLEAVE (child_proxy);

  GST_OBJECT_LOCK (self);
  count = GST_ELEMENT_CAST (self)->numsinkpads;
  GST_OBJECT_UNLOCK (self);
  GST_INFO_OBJECT (self, "Children Count: %d", count);

  return count;
}

static void
gst_audio_interleave_child_proxy_init (gpointer g_iface, gpointer iface_data)
{
  GstChildProxyInterface *iface = g_iface;

  GST_INFO ("intializing child proxy interface");
  iface->get_child_by_index =
      gst_audio_interleave_child_proxy_get_child_by_index;
  iface->get_children_count =
      gst_audio_interleave_child_proxy_get_children_count;
}
