/* GStreamer Adaptive Multi-Rate Narrow-Band (AMR-NB) plugin
 * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.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-amrwbdec
 * @see_also: #GstAmrwbEnc
 *
 * AMR wideband decoder based on the 
 * <ulink url="http://sourceforge.net/projects/opencore-amr">opencore codec implementation</ulink>.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=abc.amr ! amrparse ! amrwbdec ! audioconvert ! audioresample ! autoaudiosink
 * ]|
 * </refsect2>
 */

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

#include <gst/audio/audio.h>

#include "amrwbdec.h"

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/AMR-WB, "
        "rate = (int) 16000, " "channels = (int) 1")
    );

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) " GST_AUDIO_NE (S16) ", "
        "layout = (string) interleaved, "
        "rate = (int) 16000, " "channels = (int) 1")
    );

GST_DEBUG_CATEGORY_STATIC (gst_amrwbdec_debug);
#define GST_CAT_DEFAULT gst_amrwbdec_debug

#define L_FRAME16k      320     /* Frame size at 16kHz  */

static const unsigned char block_size[16] =
    { 18, 24, 33, 37, 41, 47, 51, 59, 61,
  6, 0, 0, 0, 0, 1, 1
};

static gboolean gst_amrwbdec_start (GstAudioDecoder * dec);
static gboolean gst_amrwbdec_stop (GstAudioDecoder * dec);
static gboolean gst_amrwbdec_set_format (GstAudioDecoder * dec, GstCaps * caps);
static GstFlowReturn gst_amrwbdec_parse (GstAudioDecoder * dec,
    GstAdapter * adapter, gint * offset, gint * length);
static GstFlowReturn gst_amrwbdec_handle_frame (GstAudioDecoder * dec,
    GstBuffer * buffer);

#define gst_amrwbdec_parent_class parent_class
G_DEFINE_TYPE (GstAmrwbDec, gst_amrwbdec, GST_TYPE_AUDIO_DECODER);

static void
gst_amrwbdec_class_init (GstAmrwbDecClass * klass)
{
  GstAudioDecoderClass *base_class = GST_AUDIO_DECODER_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  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, "AMR-WB audio decoder",
      "Codec/Decoder/Audio",
      "Adaptive Multi-Rate Wideband audio decoder",
      "Renato Araujo <renato.filho@indt.org.br>");

  base_class->start = GST_DEBUG_FUNCPTR (gst_amrwbdec_start);
  base_class->stop = GST_DEBUG_FUNCPTR (gst_amrwbdec_stop);
  base_class->set_format = GST_DEBUG_FUNCPTR (gst_amrwbdec_set_format);
  base_class->parse = GST_DEBUG_FUNCPTR (gst_amrwbdec_parse);
  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_amrwbdec_handle_frame);

  GST_DEBUG_CATEGORY_INIT (gst_amrwbdec_debug, "amrwbdec", 0,
      "AMR-WB audio decoder");
}

static void
gst_amrwbdec_init (GstAmrwbDec * amrwbdec)
{
  gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (amrwbdec), TRUE);
  gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
      (amrwbdec), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (amrwbdec));
}

static gboolean
gst_amrwbdec_start (GstAudioDecoder * dec)
{
  GstAmrwbDec *amrwbdec = GST_AMRWBDEC (dec);

  GST_DEBUG_OBJECT (dec, "start");
  if (!(amrwbdec->handle = D_IF_init ()))
    return FALSE;

  amrwbdec->rate = 0;
  amrwbdec->channels = 0;

  return TRUE;
}

static gboolean
gst_amrwbdec_stop (GstAudioDecoder * dec)
{
  GstAmrwbDec *amrwbdec = GST_AMRWBDEC (dec);

  GST_DEBUG_OBJECT (dec, "stop");
  D_IF_exit (amrwbdec->handle);

  return TRUE;
}

static gboolean
gst_amrwbdec_set_format (GstAudioDecoder * dec, GstCaps * caps)
{
  GstStructure *structure;
  GstAmrwbDec *amrwbdec;
  GstAudioInfo info;

  amrwbdec = GST_AMRWBDEC (dec);

  structure = gst_caps_get_structure (caps, 0);

  /* get channel count */
  gst_structure_get_int (structure, "channels", &amrwbdec->channels);
  gst_structure_get_int (structure, "rate", &amrwbdec->rate);

  /* create reverse caps */
  gst_audio_info_init (&info);
  gst_audio_info_set_format (&info,
      GST_AUDIO_FORMAT_S16, amrwbdec->rate, amrwbdec->channels, NULL);

  gst_audio_decoder_set_output_format (dec, &info);

  return TRUE;
}

static GstFlowReturn
gst_amrwbdec_parse (GstAudioDecoder * dec, GstAdapter * adapter,
    gint * offset, gint * length)
{
  GstAmrwbDec *amrwbdec = GST_AMRWBDEC (dec);
  guint8 header[1];
  guint size;
  gboolean sync, eos;
  gint block, mode;

  size = gst_adapter_available (adapter);
  if (size < 1)
    return GST_FLOW_ERROR;

  gst_audio_decoder_get_parse_state (dec, &sync, &eos);

  /* need to peek data to get the size */
  gst_adapter_copy (adapter, header, 0, 1);
  mode = (header[0] >> 3) & 0x0F;
  block = block_size[mode];

  GST_DEBUG_OBJECT (amrwbdec, "mode %d, block %d", mode, block);

  if (block) {
    if (block > size)
      return GST_FLOW_EOS;
    *offset = 0;
    *length = block;
  } else {
    /* no frame yet, skip one byte */
    GST_LOG_OBJECT (amrwbdec, "skipping byte");
    *offset = 1;
    return GST_FLOW_EOS;
  }

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_amrwbdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer)
{
  GstAmrwbDec *amrwbdec;
  GstBuffer *out;
  GstMapInfo inmap, outmap;

  amrwbdec = GST_AMRWBDEC (dec);

  /* no fancy flushing */
  if (!buffer || !gst_buffer_get_size (buffer))
    return GST_FLOW_OK;

  /* the library seems to write into the source data, hence the copy. */
  /* should be no problem */
  gst_buffer_map (buffer, &inmap, GST_MAP_READ);

  /* get output */
  out = gst_buffer_new_and_alloc (sizeof (gint16) * L_FRAME16k);
  gst_buffer_map (out, &outmap, GST_MAP_WRITE);

  /* decode */
  D_IF_decode (amrwbdec->handle, (unsigned char *) inmap.data,
      (short int *) outmap.data, _good_frame);

  gst_buffer_unmap (out, &outmap);
  gst_buffer_unmap (buffer, &inmap);

  /* send out */
  return gst_audio_decoder_finish_frame (dec, out, 1);
}
