/* GStreamer AAC encoder plugin
 * Copyright (C) 2011 Kan Hu <kan.hu@linaro.org>
 *
 * 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-voaacenc
 *
 * AAC audio encoder based on vo-aacenc library 
 * <ulink url="http://sourceforge.net/projects/opencore-amr/files/vo-aacenc/">vo-aacenc library source file</ulink>.
 * 
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=abc.wav ! wavparse ! audioresample ! audioconvert ! voaacenc ! filesink location=abc.aac
 * ]|
 * </refsect2>
 */

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

#include <string.h>

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

#include "gstvoaacenc.h"

#define VOAAC_ENC_DEFAULT_BITRATE (128000)
#define VOAAC_ENC_DEFAULT_OUTPUTFORMAT (0)      /* RAW */
#define VOAAC_ENC_MPEGVERSION (4)
#define VOAAC_ENC_CODECDATA_LEN (2)
#define VOAAC_ENC_BITS_PER_SAMPLE (16)

enum
{
  PROP_0,
  PROP_BITRATE
};

#define SAMPLE_RATES " 8000, " \
                    "11025, " \
                    "12000, " \
                    "16000, " \
                    "22050, " \
                    "24000, " \
                    "32000, " \
                    "44100, " \
                    "48000, " \
                    "64000, " \
                    "88200, " \
                    "96000"

/* voaacenc only supports 1 or 2 channels */
static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) " GST_AUDIO_NE (S16) ", "
        "layout = (string) interleaved, "
        "rate = (int) { " SAMPLE_RATES " }, " "channels = (int) 1;"
        "audio/x-raw, "
        "format = (string) " GST_AUDIO_NE (S16) ", "
        "layout = (string) interleaved, "
        "rate = (int) { " SAMPLE_RATES " }, " "channels = (int) 2, "
        "channel-mask=(bitmask)0x3")
    );

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/mpeg, "
        "mpegversion = (int) 4, "
        "rate = (int) { " SAMPLE_RATES " }, "
        "channels = (int) [1, 2], "
        "stream-format = (string) { adts, raw }, " "base-profile = (string) lc")
    );

GST_DEBUG_CATEGORY_STATIC (gst_voaacenc_debug);
#define GST_CAT_DEFAULT gst_voaacenc_debug

static gboolean voaacenc_core_init (GstVoAacEnc * voaacenc);
static gboolean voaacenc_core_set_parameter (GstVoAacEnc * voaacenc);
static void voaacenc_core_uninit (GstVoAacEnc * voaacenc);

static gboolean gst_voaacenc_start (GstAudioEncoder * enc);
static gboolean gst_voaacenc_stop (GstAudioEncoder * enc);
static gboolean gst_voaacenc_set_format (GstAudioEncoder * enc,
    GstAudioInfo * info);
static GstFlowReturn gst_voaacenc_handle_frame (GstAudioEncoder * enc,
    GstBuffer * in_buf);

G_DEFINE_TYPE (GstVoAacEnc, gst_voaacenc, GST_TYPE_AUDIO_ENCODER);

static void
gst_voaacenc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstVoAacEnc *self = GST_VOAACENC (object);

  switch (prop_id) {
    case PROP_BITRATE:
      self->bitrate = g_value_get_int (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  return;
}

static void
gst_voaacenc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstVoAacEnc *self = GST_VOAACENC (object);

  switch (prop_id) {
    case PROP_BITRATE:
      g_value_set_int (value, self->bitrate);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
  return;
}

static void
gst_voaacenc_class_init (GstVoAacEncClass * klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstAudioEncoderClass *base_class = GST_AUDIO_ENCODER_CLASS (klass);

  object_class->set_property = GST_DEBUG_FUNCPTR (gst_voaacenc_set_property);
  object_class->get_property = GST_DEBUG_FUNCPTR (gst_voaacenc_get_property);

  base_class->start = GST_DEBUG_FUNCPTR (gst_voaacenc_start);
  base_class->stop = GST_DEBUG_FUNCPTR (gst_voaacenc_stop);
  base_class->set_format = GST_DEBUG_FUNCPTR (gst_voaacenc_set_format);
  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_voaacenc_handle_frame);

  g_object_class_install_property (object_class, PROP_BITRATE,
      g_param_spec_int ("bitrate",
          "Bitrate",
          "Target Audio Bitrate",
          0, G_MAXINT, VOAAC_ENC_DEFAULT_BITRATE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

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

  gst_element_class_set_static_metadata (element_class, "AAC audio encoder",
      "Codec/Encoder/Audio", "AAC audio encoder", "Kan Hu <kan.hu@linaro.org>");

  GST_DEBUG_CATEGORY_INIT (gst_voaacenc_debug, "voaacenc", 0, "voaac encoder");
}

static void
gst_voaacenc_init (GstVoAacEnc * voaacenc)
{
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_ENCODER_SINK_PAD (voaacenc));
  voaacenc->bitrate = VOAAC_ENC_DEFAULT_BITRATE;
  voaacenc->output_format = VOAAC_ENC_DEFAULT_OUTPUTFORMAT;

  /* init rest */
  voaacenc->handle = NULL;
}

static gboolean
gst_voaacenc_start (GstAudioEncoder * enc)
{
  GstVoAacEnc *voaacenc = GST_VOAACENC (enc);

  GST_DEBUG_OBJECT (enc, "start");

  if (voaacenc_core_init (voaacenc) == FALSE)
    return FALSE;

  voaacenc->rate = 0;
  voaacenc->channels = 0;

  return TRUE;
}

static gboolean
gst_voaacenc_stop (GstAudioEncoder * enc)
{
  GstVoAacEnc *voaacenc = GST_VOAACENC (enc);

  GST_DEBUG_OBJECT (enc, "stop");
  voaacenc_core_uninit (voaacenc);

  return TRUE;
}

#define VOAAC_ENC_MAX_CHANNELS 6
/* describe the channels position */
static const GstAudioChannelPosition
    aac_channel_positions[][VOAAC_ENC_MAX_CHANNELS] = {
  {                             /* 1 ch: Mono */
      GST_AUDIO_CHANNEL_POSITION_MONO},
  {                             /* 2 ch: front left + front right (front stereo) */
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
  {                             /* 3 ch: front center + front stereo */
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
      GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT},
  {                             /* 4 ch: front center + front stereo + back center */
        GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER,
        GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT,
        GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT,
      GST_AUDIO_CHANNEL_POSITION_REAR_CENTER},
  {                             /* 5 ch: front center + front stereo + back stereo */
        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},
  {                             /* 6ch: front center + front stereo + back stereo + LFE */
        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}
};

/* check downstream caps to configure format */
static void
gst_voaacenc_negotiate (GstVoAacEnc * voaacenc)
{
  GstCaps *caps;

  caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (voaacenc));

  GST_DEBUG_OBJECT (voaacenc, "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;

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

  if (caps)
    gst_caps_unref (caps);
}

static gint
gst_voaacenc_get_rate_index (gint rate)
{
  static const gint rate_table[] = {
    96000, 88200, 64000, 48000, 44100, 32000,
    24000, 22050, 16000, 12000, 11025, 8000
  };
  gint i;
  for (i = 0; i < G_N_ELEMENTS (rate_table); ++i) {
    if (rate == rate_table[i]) {
      return i;
    }
  }
  return -1;
}

static GstCaps *
gst_voaacenc_create_source_pad_caps (GstVoAacEnc * voaacenc)
{
  GstCaps *caps = NULL;
  gint index;
  GstBuffer *codec_data;
  GstMapInfo map;

  if ((index = gst_voaacenc_get_rate_index (voaacenc->rate)) >= 0) {
    codec_data = gst_buffer_new_and_alloc (VOAAC_ENC_CODECDATA_LEN);
    gst_buffer_map (codec_data, &map, GST_MAP_WRITE);
    /* LC profile only */
    map.data[0] = ((0x02 << 3) | (index >> 1));
    map.data[1] = ((index & 0x01) << 7) | (voaacenc->channels << 3);

    caps = gst_caps_new_simple ("audio/mpeg",
        "mpegversion", G_TYPE_INT, VOAAC_ENC_MPEGVERSION,
        "channels", G_TYPE_INT, voaacenc->channels,
        "rate", G_TYPE_INT, voaacenc->rate, NULL);

    gst_codec_utils_aac_caps_set_level_and_profile (caps, map.data,
        VOAAC_ENC_CODECDATA_LEN);
    gst_buffer_unmap (codec_data, &map);

    if (!voaacenc->output_format) {
      gst_caps_set_simple (caps,
          "stream-format", G_TYPE_STRING, "raw",
          "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
    } else {
      gst_caps_set_simple (caps,
          "stream-format", G_TYPE_STRING, "adts",
          "framed", G_TYPE_BOOLEAN, TRUE, NULL);
    }
    gst_buffer_unref (codec_data);
  }

  return caps;
}

static gboolean
gst_voaacenc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
  gboolean ret = FALSE;
  GstVoAacEnc *voaacenc;
  GstCaps *src_caps;

  voaacenc = GST_VOAACENC (benc);

  /* get channel count */
  voaacenc->channels = GST_AUDIO_INFO_CHANNELS (info);
  voaacenc->rate = GST_AUDIO_INFO_RATE (info);

  /* precalc buffer size as it's constant now */
  voaacenc->inbuf_size = voaacenc->channels * 2 * 1024;

  gst_voaacenc_negotiate (voaacenc);

  /* create reverse caps */
  src_caps = gst_voaacenc_create_source_pad_caps (voaacenc);

  if (src_caps) {
    gst_audio_encoder_set_output_format (GST_AUDIO_ENCODER (voaacenc),
        src_caps);
    gst_caps_unref (src_caps);
    ret = voaacenc_core_set_parameter (voaacenc);
  }

  /* report needs to base class */
  gst_audio_encoder_set_frame_samples_min (benc, 1024);
  gst_audio_encoder_set_frame_samples_max (benc, 1024);
  gst_audio_encoder_set_frame_max (benc, 1);

  return ret;
}

static GstFlowReturn
gst_voaacenc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf)
{
  GstVoAacEnc *voaacenc;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *out;
  VO_AUDIO_OUTPUTINFO output_info = { {0} };
  VO_CODECBUFFER input = { 0 };
  VO_CODECBUFFER output = { 0 };
  GstMapInfo map, omap;
  GstAudioInfo *info = gst_audio_encoder_get_audio_info (benc);

  voaacenc = GST_VOAACENC (benc);

  g_return_val_if_fail (voaacenc->handle, GST_FLOW_NOT_NEGOTIATED);

  /* we don't deal with squeezing remnants, so simply discard those */
  if (G_UNLIKELY (buf == NULL)) {
    GST_DEBUG_OBJECT (benc, "no data");
    goto exit;
  }

  if (memcmp (info->position, aac_channel_positions[info->channels - 1],
          sizeof (GstAudioChannelPosition) * info->channels) != 0) {
    buf = gst_buffer_make_writable (buf);
    gst_audio_buffer_reorder_channels (buf, info->finfo->format,
        info->channels, info->position,
        aac_channel_positions[info->channels - 1]);
  }

  gst_buffer_map (buf, &map, GST_MAP_READ);

  if (G_UNLIKELY (map.size < voaacenc->inbuf_size)) {
    gst_buffer_unmap (buf, &map);
    GST_DEBUG_OBJECT (voaacenc, "discarding trailing data %d", (gint) map.size);
    ret = gst_audio_encoder_finish_frame (benc, NULL, -1);
    goto exit;
  }

  /* max size */
  out = gst_buffer_new_and_alloc (voaacenc->inbuf_size);
  gst_buffer_map (out, &omap, GST_MAP_WRITE);

  output.Buffer = omap.data;
  output.Length = voaacenc->inbuf_size;

  g_assert (map.size == voaacenc->inbuf_size);
  input.Buffer = map.data;
  input.Length = voaacenc->inbuf_size;
  voaacenc->codec_api.SetInputData (voaacenc->handle, &input);

  /* encode */
  if (voaacenc->codec_api.GetOutputData (voaacenc->handle, &output,
          &output_info) != VO_ERR_NONE) {
    gst_buffer_unmap (buf, &map);
    gst_buffer_unmap (out, &omap);
    gst_buffer_unref (out);
    goto encode_failed;
  }

  GST_LOG_OBJECT (voaacenc, "encoded to %lu bytes", output.Length);
  gst_buffer_unmap (buf, &map);
  gst_buffer_unmap (out, &omap);
  gst_buffer_resize (out, 0, output.Length);

  ret = gst_audio_encoder_finish_frame (benc, out, 1024);

exit:
  return ret;

  /* ERRORS */
encode_failed:
  {
    GST_ELEMENT_ERROR (voaacenc, STREAM, ENCODE, (NULL), ("encode failed"));
    ret = GST_FLOW_ERROR;
    goto exit;
  }
}

static VO_U32
voaacenc_core_mem_alloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
{
  if (!pMemInfo)
    return VO_ERR_INVALID_ARG;

  pMemInfo->VBuffer = g_malloc (pMemInfo->Size);
  return 0;
}

static VO_U32
voaacenc_core_mem_free (VO_S32 uID, VO_PTR pMem)
{
  g_free (pMem);
  return 0;
}

static VO_U32
voaacenc_core_mem_set (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)
{
  memset (pBuff, uValue, uSize);
  return 0;
}

static VO_U32
voaacenc_core_mem_copy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
  memcpy (pDest, pSource, uSize);
  return 0;
}

static VO_U32
voaacenc_core_mem_check (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)
{
  return 0;
}

static gboolean
voaacenc_core_init (GstVoAacEnc * voaacenc)
{
  VO_CODEC_INIT_USERDATA user_data = { 0 };
  voGetAACEncAPI (&voaacenc->codec_api);

  voaacenc->mem_operator.Alloc = voaacenc_core_mem_alloc;
  voaacenc->mem_operator.Copy = voaacenc_core_mem_copy;
  voaacenc->mem_operator.Free = voaacenc_core_mem_free;
  voaacenc->mem_operator.Set = voaacenc_core_mem_set;
  voaacenc->mem_operator.Check = voaacenc_core_mem_check;
  user_data.memflag = VO_IMF_USERMEMOPERATOR;
  user_data.memData = &voaacenc->mem_operator;
  voaacenc->codec_api.Init (&voaacenc->handle, VO_AUDIO_CodingAAC, &user_data);

  if (voaacenc->handle == NULL) {
    return FALSE;
  }
  return TRUE;

}

static gboolean
voaacenc_core_set_parameter (GstVoAacEnc * voaacenc)
{
  AACENC_PARAM params = { 0 };
  guint32 ret;

  params.sampleRate = voaacenc->rate;
  params.bitRate = voaacenc->bitrate;
  params.nChannels = voaacenc->channels;
  if (voaacenc->output_format) {
    params.adtsUsed = 1;
  } else {
    params.adtsUsed = 0;
  }

  ret =
      voaacenc->codec_api.SetParam (voaacenc->handle, VO_PID_AAC_ENCPARAM,
      &params);
  if (ret != VO_ERR_NONE) {
    GST_ERROR_OBJECT (voaacenc, "Failed to set encoder parameters");
    return FALSE;
  }
  return TRUE;
}

static void
voaacenc_core_uninit (GstVoAacEnc * voaacenc)
{
  if (voaacenc->handle) {
    voaacenc->codec_api.Uninit (voaacenc->handle);
    voaacenc->handle = NULL;
  }
}
