/* GStreamer FAAD (Free AAC Decoder) plugin
 * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
 *
 * 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-faad
 * @seealso: faac
 *
 * faad decodes AAC (MPEG-4 part 3) stream.
 *
 * <refsect2>
 * <title>Example launch lines</title>
 * |[
 * gst-launch-1.0 filesrc location=example.mp4 ! qtdemux ! faad ! audioconvert ! audioresample ! autoaudiosink
 * ]| Play aac from mp4 file.
 * |[
 * gst-launch-1.0 filesrc location=example.adts ! faad ! audioconvert ! audioresample ! autoaudiosink
 * ]| Play standalone aac bitstream.
 * </refsect2>
 */

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

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

#include "gstfaad.h"

GST_DEBUG_CATEGORY_STATIC (faad_debug);
#define GST_CAT_DEFAULT faad_debug

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/mpeg, " "mpegversion = (int) 2; "
        "audio/mpeg, mpegversion = (int) 4, stream-format = (string) { raw, adts }")
    );

#define STATIC_RAW_CAPS(format) \
  "audio/x-raw, " \
    "format = (string) "GST_AUDIO_NE(format)", " \
    "layout = (string) interleaved, " \
    "rate = (int) [ 8000, 96000 ], " \
    "channels = (int) [ 1, 8 ]"

/*
 * All except 16-bit integer are disabled until someone fixes FAAD.
 * FAAD allocates approximately 8*1024*2 bytes bytes, which is enough
 * for 1 frame (1024 samples) of 6 channel (5.1) 16-bit integer 16bpp
 * audio, but not for any other. You'll get random segfaults, crashes
 * and even valgrind goes crazy.
 */

#define STATIC_CAPS \
  STATIC_RAW_CAPS (S16)
#if 0
#define NOTUSED "; " \
STATIC_RAW_CAPS (S24) \
    "; " \
STATIC_RAW_CAPS (S32) \
    "; " \
STATIC_RAW_CAPS (F32) \
    "; " \
STATIC_RAW_CAPS (F64)
#endif

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (STATIC_CAPS)
    );

static void gst_faad_reset (GstFaad * faad);

static gboolean gst_faad_start (GstAudioDecoder * dec);
static gboolean gst_faad_stop (GstAudioDecoder * dec);
static gboolean gst_faad_set_format (GstAudioDecoder * dec, GstCaps * caps);
static gboolean gst_faad_parse (GstAudioDecoder * dec, GstAdapter * adapter,
    gint * offset, gint * length);
static GstFlowReturn gst_faad_handle_frame (GstAudioDecoder * dec,
    GstBuffer * buffer);
static void gst_faad_flush (GstAudioDecoder * dec, gboolean hard);

static gboolean gst_faad_open_decoder (GstFaad * faad);
static void gst_faad_close_decoder (GstFaad * faad);

#define gst_faad_parent_class parent_class
G_DEFINE_TYPE (GstFaad, gst_faad, GST_TYPE_AUDIO_DECODER);

static void
gst_faad_class_init (GstFaadClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);

  gst_element_class_add_static_pad_template (element_class, &src_template);
  gst_element_class_add_static_pad_template (element_class, &sink_template);

  gst_element_class_set_static_metadata (element_class, "AAC audio decoder",
      "Codec/Decoder/Audio",
      "Free MPEG-2/4 AAC decoder",
      "Ronald Bultje <rbultje@ronald.bitfreak.net>");

  base_class->start = GST_DEBUG_FUNCPTR (gst_faad_start);
  base_class->stop = GST_DEBUG_FUNCPTR (gst_faad_stop);
  base_class->set_format = GST_DEBUG_FUNCPTR (gst_faad_set_format);
  base_class->parse = GST_DEBUG_FUNCPTR (gst_faad_parse);
  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_faad_handle_frame);
  base_class->flush = GST_DEBUG_FUNCPTR (gst_faad_flush);

  GST_DEBUG_CATEGORY_INIT (faad_debug, "faad", 0, "AAC decoding");
}

static void
gst_faad_init (GstFaad * faad)
{
  gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
      (faad), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (faad));
  gst_faad_reset (faad);
}

static void
gst_faad_reset_stream_state (GstFaad * faad)
{
  if (faad->handle)
    faacDecPostSeekReset (faad->handle, 0);
}

static void
gst_faad_reset (GstFaad * faad)
{
  faad->samplerate = -1;
  faad->channels = -1;
  faad->init = FALSE;
  faad->packetised = FALSE;
  g_free (faad->channel_positions);
  faad->channel_positions = NULL;
  faad->last_header = 0;

  gst_faad_reset_stream_state (faad);
}

static gboolean
gst_faad_start (GstAudioDecoder * dec)
{
  GstFaad *faad = GST_FAAD (dec);

  GST_DEBUG_OBJECT (dec, "start");
  gst_faad_reset (faad);

  /* call upon legacy upstream byte support (e.g. seeking) */
  gst_audio_decoder_set_estimate_rate (dec, TRUE);
  /* never mind a few errors */
  gst_audio_decoder_set_max_errors (dec, 10);

  return TRUE;
}

static gboolean
gst_faad_stop (GstAudioDecoder * dec)
{
  GstFaad *faad = GST_FAAD (dec);

  GST_DEBUG_OBJECT (dec, "stop");
  gst_faad_reset (faad);
  gst_faad_close_decoder (faad);

  return TRUE;
}

static gint
aac_rate_idx (gint rate)
{
  if (92017 <= rate)
    return 0;
  else if (75132 <= rate)
    return 1;
  else if (55426 <= rate)
    return 2;
  else if (46009 <= rate)
    return 3;
  else if (37566 <= rate)
    return 4;
  else if (27713 <= rate)
    return 5;
  else if (23004 <= rate)
    return 6;
  else if (18783 <= rate)
    return 7;
  else if (13856 <= rate)
    return 8;
  else if (11502 <= rate)
    return 9;
  else if (9391 <= rate)
    return 10;
  else
    return 11;
}

static gboolean
gst_faad_set_format (GstAudioDecoder * dec, GstCaps * caps)
{
  GstFaad *faad = GST_FAAD (dec);
  GstStructure *str = gst_caps_get_structure (caps, 0);
  GstBuffer *buf;
  const GValue *value;
  GstMapInfo map;
  guint8 *cdata;
  gsize csize;

  /* clean up current decoder, rather than trying to reconfigure */
  gst_faad_close_decoder (faad);

  /* Assume raw stream */
  faad->packetised = FALSE;

  if ((value = gst_structure_get_value (str, "codec_data"))) {
    unsigned long samplerate;
    guint8 channels;

    /* We have codec data, means packetised stream */
    faad->packetised = TRUE;

    buf = gst_value_get_buffer (value);
    g_return_val_if_fail (buf != NULL, FALSE);

    gst_buffer_map (buf, &map, GST_MAP_READ);
    cdata = map.data;
    csize = map.size;

    if (csize < 2)
      goto wrong_length;

    GST_DEBUG_OBJECT (faad,
        "codec_data: object_type=%d, sample_rate=%d, channels=%d",
        ((cdata[0] & 0xf8) >> 3),
        (((cdata[0] & 0x07) << 1) | ((cdata[1] & 0x80) >> 7)),
        ((cdata[1] & 0x78) >> 3));

    if (!gst_faad_open_decoder (faad))
      goto open_failed;
    /* someone forgot that char can be unsigned when writing the API */
    if ((gint8) faacDecInit2 (faad->handle, cdata, csize, &samplerate,
            &channels) < 0)
      goto init_failed;

    if (channels != ((cdata[1] & 0x78) >> 3)) {
      /* https://bugs.launchpad.net/ubuntu/+source/faad2/+bug/290259 */
      GST_WARNING_OBJECT (faad,
          "buggy faad version, wrong nr of channels %d instead of %d", channels,
          ((cdata[1] & 0x78) >> 3));
    }

    GST_DEBUG_OBJECT (faad, "codec_data init: channels=%u, rate=%u", channels,
        (guint32) samplerate);

    /* not updating these here, so they are updated in the
     * chain function, and new caps are created etc. */
    faad->samplerate = 0;
    faad->channels = 0;

    faad->init = TRUE;
    gst_buffer_unmap (buf, &map);
  } else if ((value = gst_structure_get_value (str, "framed")) &&
      g_value_get_boolean (value) == TRUE) {
    faad->packetised = TRUE;
    faad->init = FALSE;
    GST_DEBUG_OBJECT (faad, "we have packetized audio");
  } else {
    faad->init = FALSE;
  }

  faad->fake_codec_data[0] = 0;
  faad->fake_codec_data[1] = 0;

  if (faad->packetised && !faad->init) {
    gint rate, channels;

    if (gst_structure_get_int (str, "rate", &rate) &&
        gst_structure_get_int (str, "channels", &channels)) {
      gint rate_idx, profile;

      profile = 3;              /* 0=MAIN, 1=LC, 2=SSR, 3=LTP */
      rate_idx = aac_rate_idx (rate);

      faad->fake_codec_data[0] = ((profile + 1) << 3) | ((rate_idx & 0xE) >> 1);
      faad->fake_codec_data[1] = ((rate_idx & 0x1) << 7) | (channels << 3);
      GST_LOG_OBJECT (faad, "created fake codec data (%u,%u): 0x%x 0x%x", rate,
          channels, (int) faad->fake_codec_data[0],
          (int) faad->fake_codec_data[1]);
    }
  }

  return TRUE;

  /* ERRORS */
wrong_length:
  {
    GST_DEBUG_OBJECT (faad, "codec_data less than 2 bytes long");
    gst_buffer_unmap (buf, &map);
    return FALSE;
  }
open_failed:
  {
    GST_DEBUG_OBJECT (faad, "failed to create decoder");
    gst_buffer_unmap (buf, &map);
    return FALSE;
  }
init_failed:
  {
    GST_DEBUG_OBJECT (faad, "faacDecInit2() failed");
    gst_buffer_unmap (buf, &map);
    return FALSE;
  }
}

static gboolean
gst_faad_chanpos_to_gst (GstFaad * faad, guchar * fpos,
    GstAudioChannelPosition * pos, guint num)
{
  guint n;
  gboolean unknown_channel = FALSE;

  /* special handling for the common cases for mono and stereo */
  if (num == 1 && fpos[0] == FRONT_CHANNEL_CENTER) {
    GST_DEBUG_OBJECT (faad, "mono common case; won't set channel positions");
    pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
    return TRUE;
  } else if (num == 2 && fpos[0] == FRONT_CHANNEL_LEFT
      && fpos[1] == FRONT_CHANNEL_RIGHT) {
    GST_DEBUG_OBJECT (faad, "stereo common case; won't set channel positions");
    pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
    pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
    return TRUE;
  }

  for (n = 0; n < num; n++) {
    GST_DEBUG_OBJECT (faad, "faad channel %d as %d", n, fpos[n]);
    switch (fpos[n]) {
      case FRONT_CHANNEL_LEFT:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
        break;
      case FRONT_CHANNEL_RIGHT:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
        break;
      case FRONT_CHANNEL_CENTER:
        /* argh, mono = center */
        if (num == 1)
          pos[n] = GST_AUDIO_CHANNEL_POSITION_MONO;
        else
          pos[n] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
        break;
      case SIDE_CHANNEL_LEFT:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
        break;
      case SIDE_CHANNEL_RIGHT:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
        break;
      case BACK_CHANNEL_LEFT:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
        break;
      case BACK_CHANNEL_RIGHT:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
        break;
      case BACK_CHANNEL_CENTER:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
        break;
      case LFE_CHANNEL:
        pos[n] = GST_AUDIO_CHANNEL_POSITION_LFE1;
        break;
      default:
        GST_DEBUG_OBJECT (faad, "unknown channel %d at %d", fpos[n], n);
        unknown_channel = TRUE;
        break;
    }
  }
  if (unknown_channel) {
    switch (num) {
      case 1:{
        GST_DEBUG_OBJECT (faad,
            "FAAD reports unknown 1 channel mapping. Forcing to mono");
        pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
        break;
      }
      case 2:{
        GST_DEBUG_OBJECT (faad,
            "FAAD reports unknown 2 channel mapping. Forcing to stereo");
        pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
        pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
        break;
      }
      default:{
        GST_WARNING_OBJECT (faad,
            "Unsupported FAAD channel position 0x%x encountered", fpos[n]);
        return FALSE;
      }
    }
  }

  return TRUE;
}

static gboolean
gst_faad_update_caps (GstFaad * faad, faacDecFrameInfo * info)
{
  gboolean ret;
  gboolean fmt_change = FALSE;
  GstAudioInfo ainfo;
  gint i;
  GstAudioChannelPosition position[6];

  /* see if we need to renegotiate */
  if (info->samplerate != faad->samplerate ||
      info->channels != faad->channels || !faad->channel_positions) {
    fmt_change = TRUE;
  } else {
    for (i = 0; i < info->channels; i++) {
      if (info->channel_position[i] != faad->channel_positions[i]) {
        fmt_change = TRUE;
        break;
      }
    }
  }

  if (G_LIKELY (gst_pad_has_current_caps (GST_AUDIO_DECODER_SRC_PAD (faad))
          && !fmt_change))
    return TRUE;


  /* store new negotiation information */
  faad->samplerate = info->samplerate;
  faad->channels = info->channels;
  g_free (faad->channel_positions);
  faad->channel_positions = g_memdup (info->channel_position, faad->channels);

  faad->bps = 16 / 8;

  if (!gst_faad_chanpos_to_gst (faad, faad->channel_positions,
          faad->aac_positions, faad->channels)) {
    GST_DEBUG_OBJECT (faad, "Could not map channel positions");
    return FALSE;
  }

  memcpy (position, faad->aac_positions, sizeof (position));
  gst_audio_channel_positions_to_valid_order (position, faad->channels);
  memcpy (faad->gst_positions, position,
      faad->channels * sizeof (GstAudioChannelPosition));

  /* get the remap table */
  memset (faad->reorder_map, 0, sizeof (faad->reorder_map));
  faad->need_reorder = FALSE;
  if (gst_audio_get_channel_reorder_map (faad->channels, faad->aac_positions,
          faad->gst_positions, faad->reorder_map)) {
    for (i = 0; i < faad->channels; i++) {
      GST_DEBUG_OBJECT (faad, "remap %d -> %d", i, faad->reorder_map[i]);
      if (faad->reorder_map[i] != i) {
        faad->need_reorder = TRUE;
      }
    }
  }

  /* FIXME: Use the GstAudioInfo of GstAudioDecoder for all of this */
  gst_audio_info_init (&ainfo);
  gst_audio_info_set_format (&ainfo, GST_AUDIO_FORMAT_S16, faad->samplerate,
      faad->channels, position);

  ret = gst_audio_decoder_set_output_format (GST_AUDIO_DECODER (faad), &ainfo);

  return ret;
}

/*
 * Find syncpoint in ADTS/ADIF stream. Doesn't work for raw,
 * packetized streams. Be careful when calling.
 * Returns FALSE on no-sync, fills offset/length if one/two
 * syncpoints are found, only returns TRUE when it finds two
 * subsequent syncpoints (similar to mp3 typefinding in
 * gst/typefind/) for ADTS because 12 bits isn't very reliable.
 */
static gboolean
gst_faad_sync (GstFaad * faad, const guint8 * data, guint size, gboolean next,
    gint * off, gint * length)
{
  guint n = 0;
  gint snc;
  gboolean ret = FALSE;
  guint len = 0;

  GST_LOG_OBJECT (faad, "Finding syncpoint");

  /* check for too small a buffer */
  if (size < 3)
    goto exit;

  for (n = 0; n < size - 3; n++) {
    snc = GST_READ_UINT16_BE (&data[n]);
    if ((snc & 0xfff6) == 0xfff0) {
      /* we have an ADTS syncpoint. Parse length and find
       * next syncpoint. */
      GST_LOG_OBJECT (faad,
          "Found one ADTS syncpoint at offset 0x%x, tracing next...", n);

      if (size - n < 5) {
        GST_LOG_OBJECT (faad, "Not enough data to parse ADTS header");
        break;
      }

      len = ((data[n + 3] & 0x03) << 11) |
          (data[n + 4] << 3) | ((data[n + 5] & 0xe0) >> 5);
      if (n + len + 2 >= size) {
        GST_LOG_OBJECT (faad, "Frame size %d, next frame is not within reach",
            len);
        if (next) {
          break;
        } else if (n + len <= size) {
          GST_LOG_OBJECT (faad, "but have complete frame and no next frame; "
              "accept ADTS syncpoint at offset 0x%x (framelen %u)", n, len);
          ret = TRUE;
          break;
        }
      }

      snc = GST_READ_UINT16_BE (&data[n + len]);
      if ((snc & 0xfff6) == 0xfff0) {
        GST_LOG_OBJECT (faad,
            "Found ADTS syncpoint at offset 0x%x (framelen %u)", n, len);
        ret = TRUE;
        break;
      }

      GST_LOG_OBJECT (faad, "No next frame found... (should be at 0x%x)",
          n + len);
    } else if (!memcmp (&data[n], "ADIF", 4)) {
      /* we have an ADIF syncpoint. 4 bytes is enough. */
      GST_LOG_OBJECT (faad, "Found ADIF syncpoint at offset 0x%x", n);
      ret = TRUE;
      break;
    }
  }

exit:

  *off = n;

  if (ret) {
    *length = len;
  } else {
    GST_LOG_OBJECT (faad, "Found no syncpoint");
  }

  return ret;
}

static gboolean
looks_like_valid_header (guint8 * input_data, guint input_size)
{
  if (input_size < 4)
    return FALSE;

  if (input_data[0] == 'A'
      && input_data[1] == 'D' && input_data[2] == 'I' && input_data[3] == 'F')
    /* ADIF type header */
    return TRUE;

  if (input_data[0] == 0xff && (input_data[1] >> 4) == 0xf)
    /* ADTS type header */
    return TRUE;

  return FALSE;
}

static GstFlowReturn
gst_faad_parse (GstAudioDecoder * dec, GstAdapter * adapter,
    gint * offset, gint * length)
{
  GstFaad *faad;
  const guint8 *data;
  guint size;
  gboolean sync, eos;

  faad = GST_FAAD (dec);

  size = gst_adapter_available (adapter);
  g_return_val_if_fail (size > 0, GST_FLOW_ERROR);

  gst_audio_decoder_get_parse_state (dec, &sync, &eos);

  if (faad->packetised) {
    *offset = 0;
    *length = size;
    return GST_FLOW_OK;
  } else {
    gboolean ret;

    data = gst_adapter_map (adapter, size);
    ret = gst_faad_sync (faad, data, size, !eos, offset, length);
    gst_adapter_unmap (adapter);

    return (ret ? GST_FLOW_OK : GST_FLOW_EOS);
  }
}

static GstFlowReturn
gst_faad_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
{
  GstFaad *faad;
  GstFlowReturn ret = GST_FLOW_OK;
  GstMapInfo map;
  gsize input_size;
  guchar *input_data;
  GstBuffer *outbuf;
  faacDecFrameInfo info;
  void *out;

  faad = GST_FAAD (dec);

  /* no fancy draining */
  if (G_UNLIKELY (!buffer))
    return GST_FLOW_OK;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  input_data = map.data;
  input_size = map.size;

init:
  /* init if not already done during capsnego */
  if (!faad->init) {
    unsigned long rate;
    guint8 ch;

    GST_DEBUG_OBJECT (faad, "initialising ...");
    if (!gst_faad_open_decoder (faad))
      goto open_failed;
    /* We check if the first data looks like it might plausibly contain
     * appropriate initialisation info... if not, we use our fake_codec_data
     */
    if (looks_like_valid_header (input_data, input_size) || !faad->packetised) {
      if (faacDecInit (faad->handle, input_data, input_size, &rate, &ch) < 0)
        goto init_failed;

      GST_DEBUG_OBJECT (faad, "faacDecInit() ok: rate=%u,channels=%u",
          (guint32) rate, ch);
    } else {
      if ((gint8) faacDecInit2 (faad->handle, faad->fake_codec_data, 2,
              &rate, &ch) < 0) {
        goto init2_failed;
      }
      GST_DEBUG_OBJECT (faad, "faacDecInit2() ok: rate=%u,channels=%u",
          (guint32) rate, ch);
    }

    faad->init = TRUE;

    /* make sure we create new caps below */
    faad->samplerate = 0;
    faad->channels = 0;
  }

  /* decode cycle */
  info.error = 0;

  do {
    GstMapInfo omap;

    if (!faad->packetised) {
      /* faad only really parses ADTS header at Init time, not when decoding,
       * so monitor for changes and kick faad when needed */
      if (GST_READ_UINT32_BE (input_data) >> 4 != faad->last_header >> 4) {
        GST_DEBUG_OBJECT (faad, "ADTS header changed, forcing Init");
        faad->last_header = GST_READ_UINT32_BE (input_data);
        /* kick hard */
        gst_faad_close_decoder (faad);
        faad->init = FALSE;
        goto init;
      }
    }

    out = faacDecDecode (faad->handle, &info, input_data, input_size);

    gst_buffer_unmap (buffer, &map);
    buffer = NULL;

    if (info.error > 0) {
      /* give up on frame and bail out */
      gst_audio_decoder_finish_frame (dec, NULL, 1);
      goto decode_failed;
    }

    GST_LOG_OBJECT (faad, "%d bytes consumed, %d samples decoded",
        (guint) info.bytesconsumed, (guint) info.samples);

    if (out && info.samples > 0) {
      guint channels, samples;

      if (!gst_faad_update_caps (faad, &info))
        goto negotiation_failed;

      /* C's lovely propensity for int overflow.. */
      if (info.samples > G_MAXUINT / faad->bps)
        goto sample_overflow;

      channels = faad->channels;
      /* note: info.samples is total samples, not per channel */
      samples = info.samples / channels;

      /* FIXME, add bufferpool and allocator support to the base class */
      outbuf = gst_buffer_new_allocate (NULL, info.samples * faad->bps, NULL);

      gst_buffer_map (outbuf, &omap, GST_MAP_READWRITE);
      if (faad->need_reorder) {
        gint16 *dest, *src, i, j;

        dest = (gint16 *) omap.data;
        src = (gint16 *) out;

        for (i = 0; i < samples; i++) {
          for (j = 0; j < channels; j++) {
            dest[faad->reorder_map[j]] = *src++;
          }
          dest += channels;
        }
      } else {
        memcpy (omap.data, out, omap.size);
      }
      gst_buffer_unmap (outbuf, &omap);

      ret = gst_audio_decoder_finish_frame (dec, outbuf, 1);
    }
  } while (FALSE);

out:
  if (buffer)
    gst_buffer_unmap (buffer, &map);

  return ret;

/* ERRORS */
open_failed:
  {
    GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
        ("Failed to open decoder"));
    ret = GST_FLOW_ERROR;
    goto out;
  }
init_failed:
  {
    GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
        ("Failed to init decoder from stream"));
    ret = GST_FLOW_ERROR;
    goto out;
  }
init2_failed:
  {
    GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
        ("%s() failed", (faad->handle) ? "faacDecInit2" : "faacDecOpen"));
    ret = GST_FLOW_ERROR;
    goto out;
  }
decode_failed:
  {
    GST_AUDIO_DECODER_ERROR (faad, 1, STREAM, DECODE, (NULL),
        ("decoding error: %s", faacDecGetErrorMessage (info.error)), ret);
    goto out;
  }
negotiation_failed:
  {
    GST_ELEMENT_ERROR (faad, CORE, NEGOTIATION, (NULL),
        ("Setting caps on source pad failed"));
    ret = GST_FLOW_ERROR;
    goto out;
  }
sample_overflow:
  {
    GST_ELEMENT_ERROR (faad, STREAM, DECODE, (NULL),
        ("Output buffer too large"));
    ret = GST_FLOW_ERROR;
    goto out;
  }
}

static void
gst_faad_flush (GstAudioDecoder * dec, gboolean hard)
{
  gst_faad_reset_stream_state (GST_FAAD (dec));
}

static gboolean
gst_faad_open_decoder (GstFaad * faad)
{
  faacDecConfiguration *conf;

  faad->handle = faacDecOpen ();

  if (faad->handle == NULL) {
    GST_WARNING_OBJECT (faad, "faacDecOpen() failed");
    return FALSE;
  }

  conf = faacDecGetCurrentConfiguration (faad->handle);
  conf->defObjectType = LC;
  conf->dontUpSampleImplicitSBR = 1;
  conf->outputFormat = FAAD_FMT_16BIT;

  if (faacDecSetConfiguration (faad->handle, conf) == 0) {
    GST_WARNING_OBJECT (faad, "faacDecSetConfiguration() failed");
    return FALSE;
  }

  return TRUE;
}

static void
gst_faad_close_decoder (GstFaad * faad)
{
  if (faad->handle) {
    faacDecClose (faad->handle);
    faad->handle = NULL;
  }
}

static gboolean
plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "faad", GST_RANK_SECONDARY,
      GST_TYPE_FAAD);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    faad,
    "Free AAC Decoder (FAAD)",
    plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
