/* GStreamer FAAC (Free AAC Encoder) plugin
 * Copyright (C) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * Copyright (C) 2009 Mark Nauwelaerts <mnauw@users.sourceforge.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-faac
 * @see_also: faad
 *
 * faac encodes raw audio to AAC (MPEG-4 part 3) streams.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch audiotestsrc wave=sine num-buffers=100 ! audioconvert ! faac ! matroskamux ! filesink location=sine.mkv
 * ]| Encode a sine beep as aac and write to matroska container.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>

#include <gst/audio/audio.h>
#include <gst/pbutils/codec-utils.h>

#include "gstfaac.h"

#define SAMPLE_RATES " 8000, " \
                    "11025, " \
                    "12000, " \
                    "16000, " \
                    "22050, " \
                    "24000, " \
                    "32000, " \
                    "44100, " \
                    "48000, " \
                    "64000, " \
                    "88200, " \
                    "96000"
#define SINK_CAPS \
    "audio/x-raw, "                \
    "format = (string) "GST_AUDIO_NE (S16) ", "  \
    "layout = (string) interleaved, " \
    "rate = (int) {" SAMPLE_RATES "}, "   \
    "channels = (int) [ 1, 6 ] "

/* these don't seem to work? */
#if 0
"audio/x-raw-int, "
    "endianness = (int) BYTE_ORDER, "
    "signed = (boolean) true, "
    "width = (int) 32, "
    "depth = (int) { 24, 32 }, "
    "rate = (int) [ 8000, 96000], "
    "channels = (int) [ 1, 6]; "
    "audio/x-raw-float, "
    "endianness = (int) BYTE_ORDER, "
    "width = (int) 32, "
    "rate = (int) [ 8000, 96000], " "channels = (int) [ 1, 6]"
#endif
#define SRC_CAPS \
    "audio/mpeg, "                     \
    "mpegversion = (int) 4, "   \
    "channels = (int) [ 1, 6 ], "      \
    "rate = (int) {" SAMPLE_RATES "}, "   \
    "stream-format = (string) { adts, raw }, " \
    "base-profile = (string) { main, lc, ssr, ltp }, " \
    "framed = (boolean) true; " \
    "audio/mpeg, "                     \
    "mpegversion = (int) 2, "   \
    "channels = (int) [ 1, 6 ], "      \
    "rate = (int) {" SAMPLE_RATES "}, "   \
    "stream-format = (string) { adts, raw }, " \
    "profile = (string) { main, lc }," \
    "framed = (boolean) true; "
static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (SRC_CAPS));

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (SINK_CAPS));

enum
{
  PROP_0,
  PROP_QUALITY,
  PROP_BITRATE,
  PROP_RATE_CONTROL,
  PROP_PROFILE,
  PROP_TNS,
  PROP_MIDSIDE,
  PROP_SHORTCTL
};

enum
{
  VBR = 1,
  ABR
};

static void gst_faac_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_faac_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static gboolean gst_faac_configure_source_pad (GstFaac * faac,
    GstAudioInfo * info);
static GstCaps *gst_faac_getcaps (GstAudioEncoder * enc, GstCaps * filter);

static gboolean gst_faac_stop (GstAudioEncoder * enc);
static gboolean gst_faac_set_format (GstAudioEncoder * enc,
    GstAudioInfo * info);
static GstFlowReturn gst_faac_handle_frame (GstAudioEncoder * enc,
    GstBuffer * in_buf);

GST_DEBUG_CATEGORY_STATIC (faac_debug);
#define GST_CAT_DEFAULT faac_debug

#define FAAC_DEFAULT_QUALITY      100
#define FAAC_DEFAULT_BITRATE      128 * 1000
#define FAAC_DEFAULT_RATE_CONTROL VBR
#define FAAC_DEFAULT_TNS          FALSE
#define FAAC_DEFAULT_MIDSIDE      TRUE
#define FAAC_DEFAULT_SHORTCTL     SHORTCTL_NORMAL

#define gst_faac_parent_class parent_class
G_DEFINE_TYPE (GstFaac, gst_faac, GST_TYPE_AUDIO_ENCODER);

#define GST_TYPE_FAAC_RATE_CONTROL (gst_faac_brtype_get_type ())
static GType
gst_faac_brtype_get_type (void)
{
  static GType gst_faac_brtype_type = 0;

  if (!gst_faac_brtype_type) {
    static const GEnumValue gst_faac_brtype[] = {
      {VBR, "VBR", "VBR encoding"},
      {ABR, "ABR", "ABR encoding"},
      {0, NULL, NULL},
    };

    gst_faac_brtype_type = g_enum_register_static ("GstFaacBrtype",
        gst_faac_brtype);
  }

  return gst_faac_brtype_type;
}

#define GST_TYPE_FAAC_SHORTCTL (gst_faac_shortctl_get_type ())
static GType
gst_faac_shortctl_get_type (void)
{
  static GType gst_faac_shortctl_type = 0;

  if (!gst_faac_shortctl_type) {
    static const GEnumValue gst_faac_shortctl[] = {
      {SHORTCTL_NORMAL, "SHORTCTL_NORMAL", "Normal block type"},
      {SHORTCTL_NOSHORT, "SHORTCTL_NOSHORT", "No short blocks"},
      {SHORTCTL_NOLONG, "SHORTCTL_NOLONG", "No long blocks"},
      {0, NULL, NULL},
    };

    gst_faac_shortctl_type = g_enum_register_static ("GstFaacShortCtl",
        gst_faac_shortctl);
  }

  return gst_faac_shortctl_type;
}

static void
gst_faac_class_init (GstFaacClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  GstAudioEncoderClass *base_class = GST_AUDIO_ENCODER_CLASS (klass);

  gobject_class->set_property = gst_faac_set_property;
  gobject_class->get_property = gst_faac_get_property;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sink_template));

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

  base_class->stop = GST_DEBUG_FUNCPTR (gst_faac_stop);
  base_class->set_format = GST_DEBUG_FUNCPTR (gst_faac_set_format);
  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_faac_handle_frame);
  base_class->getcaps = GST_DEBUG_FUNCPTR (gst_faac_getcaps);

  /* properties */
  g_object_class_install_property (gobject_class, PROP_QUALITY,
      g_param_spec_int ("quality", "Quality (%)",
          "Variable bitrate (VBR) quantizer quality in %", 1, 1000,
          FAAC_DEFAULT_QUALITY,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_BITRATE,
      g_param_spec_int ("bitrate", "Bitrate (bps)",
          "Average Bitrate (ABR) in bits/sec", 8 * 1000, 320 * 1000,
          FAAC_DEFAULT_BITRATE,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RATE_CONTROL,
      g_param_spec_enum ("rate-control", "Rate Control (ABR/VBR)",
          "Encoding bitrate type (VBR/ABR)", GST_TYPE_FAAC_RATE_CONTROL,
          FAAC_DEFAULT_RATE_CONTROL,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_TNS,
      g_param_spec_boolean ("tns", "TNS", "Use temporal noise shaping",
          FAAC_DEFAULT_TNS,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MIDSIDE,
      g_param_spec_boolean ("midside", "Midside", "Allow mid/side encoding",
          FAAC_DEFAULT_MIDSIDE,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_SHORTCTL,
      g_param_spec_enum ("shortctl", "Block type",
          "Block type encorcing",
          GST_TYPE_FAAC_SHORTCTL, FAAC_DEFAULT_SHORTCTL,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  GST_DEBUG_CATEGORY_INIT (faac_debug, "faac", 0, "AAC encoding");
}

static void
gst_faac_init (GstFaac * faac)
{
}

static void
gst_faac_close_encoder (GstFaac * faac)
{
  if (faac->handle)
    faacEncClose (faac->handle);
  faac->handle = NULL;
}

static gboolean
gst_faac_stop (GstAudioEncoder * enc)
{
  GstFaac *faac = GST_FAAC (enc);

  GST_DEBUG_OBJECT (faac, "stop");
  gst_faac_close_encoder (faac);
  return TRUE;
}

static const GstAudioChannelPosition aac_channel_positions[][8] = {
  {GST_AUDIO_CHANNEL_POSITION_MONO},
  {GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
      },
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
      GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
      GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT},
  {
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
        GST_AUDIO_CHANNEL_POSITION_REAR_LEFT,
        GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT,
      GST_AUDIO_CHANNEL_POSITION_LFE1}
};

static GstCaps *
gst_faac_getcaps (GstAudioEncoder * enc, GstCaps * filter)
{
  static volatile gsize sinkcaps = 0;

  if (g_once_init_enter (&sinkcaps)) {
    GstCaps *tmp = gst_caps_new_empty ();
    GstStructure *s, *t;
    gint i, c;
    static const int rates[] = {
      8000, 11025, 12000, 16000, 22050, 24000,
      32000, 44100, 48000, 64000, 88200, 96000
    };
    GValue rates_arr = { 0, };
    GValue tmp_v = { 0, };

    g_value_init (&rates_arr, GST_TYPE_LIST);
    g_value_init (&tmp_v, G_TYPE_INT);
    for (i = 0; i < G_N_ELEMENTS (rates); i++) {
      g_value_set_int (&tmp_v, rates[i]);
      gst_value_list_append_value (&rates_arr, &tmp_v);
    }
    g_value_unset (&tmp_v);

    s = gst_structure_new ("audio/x-raw",
        "format", G_TYPE_STRING, GST_AUDIO_NE (S16),
        "layout", G_TYPE_STRING, "interleaved", NULL);
    gst_structure_set_value (s, "rate", &rates_arr);

    for (i = 1; i <= 6; i++) {
      guint64 channel_mask = 0;
      t = gst_structure_copy (s);

      gst_structure_set (t, "channels", G_TYPE_INT, i, NULL);
      if (i > 1) {
        for (c = 0; c < i; c++)
          channel_mask |=
              G_GUINT64_CONSTANT (1) << aac_channel_positions[i - 1][c];

        gst_structure_set (t, "channel-mask", GST_TYPE_BITMASK, channel_mask,
            NULL);
      }
      gst_caps_append_structure (tmp, t);
    }
    gst_structure_free (s);
    g_value_unset (&rates_arr);

    GST_DEBUG_OBJECT (enc, "Generated sinkcaps: %" GST_PTR_FORMAT, tmp);

    g_once_init_leave (&sinkcaps, (gsize) tmp);
  }

  return gst_audio_encoder_proxy_getcaps (enc, (GstCaps *) sinkcaps, filter);
}

static gboolean
gst_faac_set_format (GstAudioEncoder * enc, GstAudioInfo * info)
{
  GstFaac *faac = GST_FAAC (enc);
  gint width;
  gulong fmt = 0;
  gboolean result = FALSE;

  /* base class takes care */
  width = GST_AUDIO_INFO_WIDTH (info);

  if (GST_AUDIO_INFO_IS_INTEGER (info)) {
    switch (width) {
      case 16:
        fmt = FAAC_INPUT_16BIT;
        break;
      case 24:
      case 32:
        fmt = FAAC_INPUT_32BIT;
        break;
      default:
        g_return_val_if_reached (FALSE);
    }
  } else {
    fmt = FAAC_INPUT_FLOAT;
  }

  faac->format = fmt;

  /* finish up */
  result = gst_faac_configure_source_pad (faac, info);
  if (!result)
    goto done;

  /* report needs to base class */
  gst_audio_encoder_set_frame_samples_min (enc, faac->samples);
  gst_audio_encoder_set_frame_samples_max (enc, faac->samples);
  gst_audio_encoder_set_frame_max (enc, 1);

done:
  return result;
}

/* check downstream caps to configure format */
static void
gst_faac_negotiate (GstFaac * faac)
{
  GstCaps *caps;

  /* default setup */
  faac->profile = LOW;
  faac->mpegversion = 4;
  faac->outputformat = 0;

  caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (faac));

  GST_DEBUG_OBJECT (faac, "allowed caps: %" GST_PTR_FORMAT, caps);

  if (caps && gst_caps_get_size (caps) > 0) {
    GstStructure *s = gst_caps_get_structure (caps, 0);
    const gchar *str = NULL;
    gint i = 4;

    if ((str = gst_structure_get_string (s, "stream-format"))) {
      if (strcmp (str, "adts") == 0) {
        GST_DEBUG_OBJECT (faac, "use ADTS format for output");
        faac->outputformat = 1;
      } else if (strcmp (str, "raw") == 0) {
        GST_DEBUG_OBJECT (faac, "use RAW format for output");
        faac->outputformat = 0;
      } else {
        GST_DEBUG_OBJECT (faac, "unknown stream-format: %s", str);
        faac->outputformat = 0;
      }
    }

    if ((str = gst_structure_get_string (s, "profile"))) {
      if (strcmp (str, "main") == 0) {
        faac->profile = MAIN;
      } else if (strcmp (str, "lc") == 0) {
        faac->profile = LOW;
      } else if (strcmp (str, "ssr") == 0) {
        faac->profile = SSR;
      } else if (strcmp (str, "ltp") == 0) {
        faac->profile = LTP;
      } else {
        faac->profile = LOW;
      }
    }

    if (!gst_structure_get_int (s, "mpegversion", &i) || i == 4) {
      faac->mpegversion = 4;
    } else {
      faac->mpegversion = 2;
    }
  }

  if (caps)
    gst_caps_unref (caps);
}

static gboolean
gst_faac_open_encoder (GstFaac * faac, GstAudioInfo * info)
{
  faacEncHandle *handle;
  faacEncConfiguration *conf;
  guint maxbitrate;
  gulong samples, bytes;

  g_return_val_if_fail (info->rate != 0 && info->channels != 0, FALSE);

  /* clean up in case of re-configure */
  gst_faac_close_encoder (faac);

  if (!(handle = faacEncOpen (info->rate, info->channels, &samples, &bytes)))
    goto setup_failed;

  /* mind channel count */
  samples /= info->channels;

  /* record */
  faac->handle = handle;
  faac->samples = samples;
  faac->bytes = bytes;

  GST_DEBUG_OBJECT (faac, "faac needs samples %d, output size %d",
      faac->samples, faac->bytes);

  /* we negotiated caps update current configuration */
  conf = faacEncGetCurrentConfiguration (faac->handle);
  conf->mpegVersion = (faac->mpegversion == 4) ? MPEG4 : MPEG2;
  conf->aacObjectType = faac->profile;
  conf->allowMidside = faac->midside;
  conf->useLfe = 0;
  conf->useTns = faac->tns;

  if (faac->brtype == VBR) {
    conf->quantqual = faac->quality;
  } else if (faac->brtype == ABR) {
    conf->bitRate = faac->bitrate / info->channels;
  }

  conf->inputFormat = faac->format;
  conf->outputFormat = faac->outputformat;
  conf->shortctl = faac->shortctl;

  /* check, warn and correct if the max bitrate for the given samplerate is
   * exceeded. Maximum of 6144 bit for a channel */
  maxbitrate =
      (unsigned int) (6144.0 * (double) info->rate / (double) 1024.0 + .5);
  if (conf->bitRate > maxbitrate) {
    GST_ELEMENT_WARNING (faac, RESOURCE, SETTINGS, (NULL),
        ("bitrate %lu exceeds maximum allowed bitrate of %u for samplerate %d. "
            "Setting bitrate to %u", conf->bitRate, maxbitrate,
            info->rate, maxbitrate));
    conf->bitRate = maxbitrate;
  }

  /* default 0 to start with, libfaac chooses based on bitrate */
  conf->bandWidth = 0;

  if (!faacEncSetConfiguration (faac->handle, conf))
    goto setup_failed;

  /* let's see what really happened,
   * note that this may not really match desired rate */
  GST_DEBUG_OBJECT (faac, "average bitrate: %lu kbps",
      (conf->bitRate + 500) / 1000 * info->channels);
  GST_DEBUG_OBJECT (faac, "quantization quality: %ld", conf->quantqual);
  GST_DEBUG_OBJECT (faac, "bandwidth: %d Hz", conf->bandWidth);

  return TRUE;

  /* ERRORS */
setup_failed:
  {
    GST_ELEMENT_ERROR (faac, LIBRARY, SETTINGS, (NULL), (NULL));
    return FALSE;
  }
}

static gboolean
gst_faac_configure_source_pad (GstFaac * faac, GstAudioInfo * info)
{
  GstCaps *srccaps;
  gboolean ret;

  /* negotiate stream format */
  gst_faac_negotiate (faac);

  if (!gst_faac_open_encoder (faac, info))
    goto set_failed;

  /* now create a caps for it all */
  srccaps = gst_caps_new_simple ("audio/mpeg",
      "mpegversion", G_TYPE_INT, faac->mpegversion,
      "channels", G_TYPE_INT, info->channels,
      "rate", G_TYPE_INT, info->rate,
      "stream-format", G_TYPE_STRING, (faac->outputformat ? "adts" : "raw"),
      "framed", G_TYPE_BOOLEAN, TRUE, NULL);

  /* DecoderSpecificInfo is only available for mpegversion=4 */
  if (faac->mpegversion == 4) {
    guint8 *config = NULL;
    gulong config_len = 0;

    /* get the config string */
    GST_DEBUG_OBJECT (faac, "retrieving decoder info");
    faacEncGetDecoderSpecificInfo (faac->handle, &config, &config_len);

    if (!gst_codec_utils_aac_caps_set_level_and_profile (srccaps, config,
            config_len)) {
      free (config);
      gst_caps_unref (srccaps);
      goto invalid_codec_data;
    }

    if (!faac->outputformat) {
      GstBuffer *codec_data;

      /* copy it into a buffer */
      codec_data = gst_buffer_new_and_alloc (config_len);
      gst_buffer_fill (codec_data, 0, config, config_len);

      /* add to caps */
      gst_caps_set_simple (srccaps,
          "codec_data", GST_TYPE_BUFFER, codec_data, NULL);

      gst_buffer_unref (codec_data);
    }

    free (config);
  } else {
    const gchar *profile;

    /* Add least add the profile to the caps */
    switch (faac->profile) {
      case MAIN:
        profile = "main";
        break;
      case LTP:
        profile = "ltp";
        break;
      case SSR:
        profile = "ssr";
        break;
      case LOW:
      default:
        profile = "lc";
        break;
    }
    gst_caps_set_simple (srccaps, "profile", G_TYPE_STRING, profile, NULL);
    /* FIXME: How to get the profile for mpegversion==2? */
  }

  GST_DEBUG_OBJECT (faac, "src pad caps: %" GST_PTR_FORMAT, srccaps);

  ret = gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (faac), srccaps);
  gst_caps_unref (srccaps);

  return ret;

  /* ERROR */
set_failed:
  {
    GST_WARNING_OBJECT (faac, "Faac doesn't support the current configuration");
    return FALSE;
  }
invalid_codec_data:
  {
    GST_ERROR_OBJECT (faac, "Invalid codec data");
    return FALSE;
  }
}

static GstFlowReturn
gst_faac_handle_frame (GstAudioEncoder * enc, GstBuffer * in_buf)
{
  GstFaac *faac = GST_FAAC (enc);
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *out_buf;
  gsize size, ret_size;
  int enc_ret;
  GstMapInfo map, omap;
  guint8 *data;
  GstAudioInfo *info =
      gst_audio_encoder_get_audio_info (GST_AUDIO_ENCODER (faac));

  out_buf = gst_buffer_new_and_alloc (faac->bytes);
  gst_buffer_map (out_buf, &omap, GST_MAP_WRITE);

  if (G_LIKELY (in_buf)) {
    if (memcmp (info->position, aac_channel_positions[info->channels - 1],
            sizeof (GstAudioChannelPosition) * info->channels) != 0) {
      in_buf = gst_buffer_make_writable (in_buf);
      gst_audio_buffer_reorder_channels (in_buf, info->finfo->format,
          info->channels, info->position,
          aac_channel_positions[info->channels - 1]);
    }
    gst_buffer_map (in_buf, &map, GST_MAP_READ);
    data = map.data;
    size = map.size;
  } else {
    data = NULL;
    size = 0;
  }

  if (G_UNLIKELY ((enc_ret = faacEncEncode (faac->handle, (gint32 *) data,
                  size / (info->finfo->width / 8), omap.data, omap.size)) < 0))
    goto encode_failed;
  ret_size = enc_ret;

  if (in_buf)
    gst_buffer_unmap (in_buf, &map);

  GST_LOG_OBJECT (faac, "encoder return: %" G_GSIZE_FORMAT, ret_size);

  if (ret_size > 0) {
    gst_buffer_unmap (out_buf, &omap);
    gst_buffer_resize (out_buf, 0, ret_size);
    ret = gst_audio_encoder_finish_frame (enc, out_buf, faac->samples);
  } else {
    gst_buffer_unmap (out_buf, &omap);
    gst_buffer_unref (out_buf);
    /* re-create encoder after final flush */
    if (!in_buf) {
      GST_DEBUG_OBJECT (faac, "flushed; recreating encoder");
      gst_faac_close_encoder (faac);
      if (!gst_faac_open_encoder (faac, gst_audio_encoder_get_audio_info (enc)))
        ret = GST_FLOW_ERROR;
    }
  }

  return ret;

  /* ERRORS */
encode_failed:
  {
    GST_ELEMENT_ERROR (faac, LIBRARY, ENCODE, (NULL), (NULL));
    if (in_buf)
      gst_buffer_unmap (in_buf, &map);
    gst_buffer_unmap (out_buf, &omap);
    gst_buffer_unref (out_buf);
    return GST_FLOW_ERROR;
  }
}

static void
gst_faac_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstFaac *faac = GST_FAAC (object);

  GST_OBJECT_LOCK (faac);

  switch (prop_id) {
    case PROP_QUALITY:
      faac->quality = g_value_get_int (value);
      break;
    case PROP_BITRATE:
      faac->bitrate = g_value_get_int (value);
      break;
    case PROP_RATE_CONTROL:
      faac->brtype = g_value_get_enum (value);
      break;
    case PROP_TNS:
      faac->tns = g_value_get_boolean (value);
      break;
    case PROP_MIDSIDE:
      faac->midside = g_value_get_boolean (value);
      break;
    case PROP_SHORTCTL:
      faac->shortctl = g_value_get_enum (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (faac);
}

static void
gst_faac_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstFaac *faac = GST_FAAC (object);

  GST_OBJECT_LOCK (faac);

  switch (prop_id) {
    case PROP_QUALITY:
      g_value_set_int (value, faac->quality);
      break;
    case PROP_BITRATE:
      g_value_set_int (value, faac->bitrate);
      break;
    case PROP_RATE_CONTROL:
      g_value_set_enum (value, faac->brtype);
      break;
    case PROP_TNS:
      g_value_set_boolean (value, faac->tns);
      break;
    case PROP_MIDSIDE:
      g_value_set_boolean (value, faac->midside);
      break;
    case PROP_SHORTCTL:
      g_value_set_enum (value, faac->shortctl);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (faac);
}

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

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    faac,
    "Free AAC Encoder (FAAC)",
    plugin_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
