/*
 * Siren Encoder Gst Element
 *
 *   @author: Youness Alaoui <kakaroto@kakaroto.homelinux.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-sirenenc
 *
 * This encodes audio buffers into the Siren 16 codec (a 16khz extension of
 * G.722.1) that is meant to be compatible with the Microsoft Windows Live
 * Messenger(tm) implementation.
 *
 * Ref: http://www.polycom.com/company/about_us/technology/siren_g7221/index.html
 */

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

#include "gstsirenenc.h"

#include <string.h>

GST_DEBUG_CATEGORY (sirenenc_debug);
#define GST_CAT_DEFAULT (sirenenc_debug)

#define FRAME_DURATION  (20 * GST_MSECOND)

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-siren, " "dct-length = (int) 320"));

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, format = (string) \"S16LE\", "
        "rate = (int) 16000, " "channels = (int) 1"));

static gboolean gst_siren_enc_start (GstAudioEncoder * enc);
static gboolean gst_siren_enc_stop (GstAudioEncoder * enc);
static gboolean gst_siren_enc_set_format (GstAudioEncoder * enc,
    GstAudioInfo * info);
static GstFlowReturn gst_siren_enc_handle_frame (GstAudioEncoder * enc,
    GstBuffer * in_buf);

G_DEFINE_TYPE (GstSirenEnc, gst_siren_enc, GST_TYPE_AUDIO_ENCODER);


static void
gst_siren_enc_class_init (GstSirenEncClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstAudioEncoderClass *base_class = GST_AUDIO_ENCODER_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (sirenenc_debug, "sirenenc", 0, "sirenenc");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&srctemplate));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sinktemplate));

  gst_element_class_set_static_metadata (element_class, "Siren Encoder element",
      "Codec/Encoder/Audio ",
      "Encode 16bit PCM streams into the Siren7 codec",
      "Youness Alaoui <kakaroto@kakaroto.homelinux.net>");

  base_class->start = GST_DEBUG_FUNCPTR (gst_siren_enc_start);
  base_class->stop = GST_DEBUG_FUNCPTR (gst_siren_enc_stop);
  base_class->set_format = GST_DEBUG_FUNCPTR (gst_siren_enc_set_format);
  base_class->handle_frame = GST_DEBUG_FUNCPTR (gst_siren_enc_handle_frame);

  GST_DEBUG ("Class Init done");
}

static void
gst_siren_enc_init (GstSirenEnc * enc)
{
}

static gboolean
gst_siren_enc_start (GstAudioEncoder * enc)
{
  GstSirenEnc *senc = GST_SIREN_ENC (enc);

  GST_DEBUG_OBJECT (enc, "start");

  senc->encoder = Siren7_NewEncoder (16000);

  return TRUE;
}

static gboolean
gst_siren_enc_stop (GstAudioEncoder * enc)
{
  GstSirenEnc *senc = GST_SIREN_ENC (enc);

  GST_DEBUG_OBJECT (senc, "stop");

  Siren7_CloseEncoder (senc->encoder);

  return TRUE;
}

static gboolean
gst_siren_enc_set_format (GstAudioEncoder * benc, GstAudioInfo * info)
{
  gboolean res;
  GstCaps *outcaps;

  outcaps = gst_static_pad_template_get_caps (&srctemplate);
  res = gst_audio_encoder_set_output_format (benc, outcaps);
  gst_caps_unref (outcaps);

  /* report needs to base class */
  gst_audio_encoder_set_frame_samples_min (benc, 320);
  gst_audio_encoder_set_frame_samples_max (benc, 320);
  /* no remainder or flushing please */
  gst_audio_encoder_set_hard_min (benc, TRUE);
  gst_audio_encoder_set_drainable (benc, FALSE);

  return res;
}

static GstFlowReturn
gst_siren_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf)
{
  GstSirenEnc *enc;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *out_buf;
  guint8 *in_data, *out_data;
  guint i, size, num_frames;
  gint out_size;
#ifndef GST_DISABLE_GST_DEBUG
  gint in_size;
#endif
  gint encode_ret;
  GstMapInfo inmap, outmap;

  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);

  enc = GST_SIREN_ENC (benc);

  size = gst_buffer_get_size (buf);

  GST_LOG_OBJECT (enc, "Received buffer of size %d", size);

  g_return_val_if_fail (size > 0, GST_FLOW_ERROR);
  g_return_val_if_fail (size % 640 == 0, GST_FLOW_ERROR);

  /* we need to process 640 input bytes to produce 40 output bytes */
  /* calculate the amount of frames we will handle */
  num_frames = size / 640;

  /* this is the input/output size */
#ifndef GST_DISABLE_GST_DEBUG
  in_size = num_frames * 640;
#endif
  out_size = num_frames * 40;

  GST_LOG_OBJECT (enc, "we have %u frames, %u in, %u out", num_frames, in_size,
      out_size);

  /* get a buffer */
  out_buf = gst_audio_encoder_allocate_output_buffer (benc, out_size);
  if (out_buf == NULL)
    goto alloc_failed;

  /* get the input data for all the frames */
  gst_buffer_map (buf, &inmap, GST_MAP_READ);
  gst_buffer_map (out_buf, &outmap, GST_MAP_READ);
  in_data = inmap.data;
  out_data = outmap.data;

  for (i = 0; i < num_frames; i++) {
    GST_LOG_OBJECT (enc, "Encoding frame %u/%u", i, num_frames);

    /* encode 640 input bytes to 40 output bytes */
    encode_ret = Siren7_EncodeFrame (enc->encoder, in_data, out_data);
    if (encode_ret != 0)
      goto encode_error;

    /* move to next frame */
    out_data += 40;
    in_data += 640;
  }

  gst_buffer_unmap (buf, &inmap);
  gst_buffer_unmap (out_buf, &outmap);

  GST_LOG_OBJECT (enc, "Finished encoding");

  /* we encode all we get, pass it along */
  ret = gst_audio_encoder_finish_frame (benc, out_buf, -1);

done:
  return ret;

  /* ERRORS */
alloc_failed:
  {
    GST_DEBUG_OBJECT (enc, "failed to pad_alloc buffer: %d (%s)", ret,
        gst_flow_get_name (ret));
    goto done;
  }
encode_error:
  {
    GST_ELEMENT_ERROR (enc, STREAM, ENCODE, (NULL),
        ("Error encoding frame: %d", encode_ret));
    ret = GST_FLOW_ERROR;
    gst_buffer_unref (out_buf);
    goto done;
  }
}

gboolean
gst_siren_enc_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "sirenenc",
      GST_RANK_MARGINAL, GST_TYPE_SIREN_ENC);
}
