/*  GStreamer SBC audio decoder
 *
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2013       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 Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser 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-sbdec
 *
 * This element decodes a Bluetooth SBC audio streams to raw integer PCM audio
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 -v filesrc location=audio.sbc ! sbcparse ! sbcdec ! audioconvert ! audioresample ! autoaudiosink
 * ]| Decode a raw SBC file.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>

#include "gstsbcdec.h"

/* FIXME: where does this come from? how is it derived? */
#define BUF_SIZE 8192

GST_DEBUG_CATEGORY_STATIC (sbc_dec_debug);
#define GST_CAT_DEFAULT sbc_dec_debug

#define parent_class gst_sbc_dec_parent_class
G_DEFINE_TYPE (GstSbcDec, gst_sbc_dec, GST_TYPE_AUDIO_DECODER);

static GstStaticPadTemplate sbc_dec_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-sbc, channels = (int) [ 1, 2 ], "
        "rate = (int) { 16000, 32000, 44100, 48000 }, "
        "parsed = (boolean) true"));

static GstStaticPadTemplate sbc_dec_src_factory =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC, GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, format=" GST_AUDIO_NE (S16) ", "
        "rate = (int) { 16000, 32000, 44100, 48000 }, "
        "channels = (int) [ 1, 2 ], layout=interleaved"));

static GstFlowReturn
gst_sbc_dec_handle_frame (GstAudioDecoder * audio_dec, GstBuffer * buf)
{
  GstSbcDec *dec = GST_SBC_DEC (audio_dec);
  GstBuffer *outbuf = NULL;
  GstMapInfo out_map;
  GstMapInfo in_map;
  gsize output_size;
  guint num_frames, i;

  /* no fancy draining */
  if (G_UNLIKELY (buf == NULL))
    return GST_FLOW_OK;

  gst_buffer_map (buf, &in_map, GST_MAP_READ);

  if (G_UNLIKELY (in_map.size == 0))
    goto done;

  /* we assume all frames are of the same size, this is implied by the
   * input caps applying to the whole input buffer, and the parser should
   * also have made sure of that */
  if (G_UNLIKELY (in_map.size % dec->frame_len != 0))
    goto mixed_frames;

  num_frames = in_map.size / dec->frame_len;
  output_size = num_frames * dec->samples_per_frame * sizeof (gint16);

  outbuf = gst_audio_decoder_allocate_output_buffer (audio_dec, output_size);

  if (outbuf == NULL)
    goto no_buffer;

  gst_buffer_map (outbuf, &out_map, GST_MAP_WRITE);

  for (i = 0; i < num_frames; ++i) {
    gssize ret;
    gsize written;

    ret = sbc_decode (&dec->sbc, in_map.data + (i * dec->frame_len),
        dec->frame_len, out_map.data + (i * dec->samples_per_frame * 2),
        dec->samples_per_frame * 2, &written);

    if (ret <= 0 || written != (dec->samples_per_frame * 2)) {
      GST_WARNING_OBJECT (dec, "decoding error, ret = %" G_GSSIZE_FORMAT ", "
          "written = %" G_GSSIZE_FORMAT, ret, written);
      break;
    }
  }

  gst_buffer_unmap (outbuf, &out_map);

  if (i > 0)
    gst_buffer_set_size (outbuf, i * dec->samples_per_frame * 2);
  else
    gst_buffer_replace (&outbuf, NULL);

done:

  gst_buffer_unmap (buf, &in_map);

  return gst_audio_decoder_finish_frame (audio_dec, outbuf, 1);

/* ERRORS */
mixed_frames:
  {
    GST_WARNING_OBJECT (dec, "inconsistent input data/frames, skipping");
    goto done;
  }
no_buffer:
  {
    GST_ERROR_OBJECT (dec, "could not allocate output buffer");
    goto done;
  }
}

static gboolean
gst_sbc_dec_set_format (GstAudioDecoder * audio_dec, GstCaps * caps)
{
  GstSbcDec *dec = GST_SBC_DEC (audio_dec);
  const gchar *channel_mode;
  GstAudioInfo info;
  GstStructure *s;
  gint channels, rate, subbands, blocks, bitpool;

  s = gst_caps_get_structure (caps, 0);
  gst_structure_get_int (s, "channels", &channels);
  gst_structure_get_int (s, "rate", &rate);

  /* save input format */
  channel_mode = gst_structure_get_string (s, "channel-mode");
  if (channel_mode == NULL ||
      !gst_structure_get_int (s, "subbands", &subbands) ||
      !gst_structure_get_int (s, "blocks", &blocks) ||
      !gst_structure_get_int (s, "bitpool", &bitpool))
    return FALSE;

  if (strcmp (channel_mode, "mono") == 0) {
    dec->frame_len = 4 + (subbands * 1) / 2 + ((blocks * 1 * bitpool) + 7) / 8;
  } else if (strcmp (channel_mode, "dual") == 0) {
    dec->frame_len = 4 + (subbands * 2) / 2 + ((blocks * 2 * bitpool) + 7) / 8;
  } else if (strcmp (channel_mode, "stereo") == 0) {
    dec->frame_len = 4 + (subbands * 2) / 2 + ((blocks * bitpool) + 7) / 8;
  } else if (strcmp (channel_mode, "joint") == 0) {
    dec->frame_len = 4 + (subbands * 2) / 2 + ((subbands + blocks * bitpool) + 7) / 8;
  } else {
    return FALSE;
  }

  dec->samples_per_frame = channels * blocks * subbands;

  GST_INFO_OBJECT (dec, "frame len: %" G_GSIZE_FORMAT ", samples per frame "
      "%" G_GSIZE_FORMAT, dec->frame_len, dec->samples_per_frame);

  /* set up output format */
  gst_audio_info_init (&info);
  gst_audio_info_set_format (&info, GST_AUDIO_FORMAT_S16, rate, channels, NULL);
  gst_audio_decoder_set_output_format (audio_dec, &info);

  return TRUE;
}

static gboolean
gst_sbc_dec_start (GstAudioDecoder * dec)
{
  GstSbcDec *sbcdec = GST_SBC_DEC (dec);

  GST_INFO_OBJECT (dec, "Setup subband codec");
  sbc_init (&sbcdec->sbc, 0);

  return TRUE;
}

static gboolean
gst_sbc_dec_stop (GstAudioDecoder * dec)
{
  GstSbcDec *sbcdec = GST_SBC_DEC (dec);

  GST_INFO_OBJECT (sbcdec, "Finish subband codec");
  sbc_finish (&sbcdec->sbc);
  sbcdec->samples_per_frame = 0;
  sbcdec->frame_len = 0;

  return TRUE;
}

static void
gst_sbc_dec_class_init (GstSbcDecClass * klass)
{
  GstAudioDecoderClass *audio_decoder_class = (GstAudioDecoderClass *) klass;
  GstElementClass *element_class = (GstElementClass *) klass;

  audio_decoder_class->start = GST_DEBUG_FUNCPTR (gst_sbc_dec_start);
  audio_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_sbc_dec_stop);
  audio_decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_sbc_dec_set_format);
  audio_decoder_class->handle_frame =
      GST_DEBUG_FUNCPTR (gst_sbc_dec_handle_frame);

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sbc_dec_sink_factory));

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sbc_dec_src_factory));

  gst_element_class_set_static_metadata (element_class,
      "Bluetooth SBC audio decoder", "Codec/Decoder/Audio",
      "Decode an SBC audio stream", "Marcel Holtmann <marcel@holtmann.org>");

  GST_DEBUG_CATEGORY_INIT (sbc_dec_debug, "sbcdec", 0, "SBC decoding element");
}

static void
gst_sbc_dec_init (GstSbcDec * dec)
{
  gst_audio_decoder_set_needs_format (GST_AUDIO_DECODER (dec), TRUE);
  gst_audio_decoder_set_use_default_pad_acceptcaps (GST_AUDIO_DECODER_CAST
      (dec), TRUE);
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_AUDIO_DECODER_SINK_PAD (dec));

  dec->samples_per_frame = 0;
  dec->frame_len = 0;
}
