/* GStreamer
 * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) 2005 Edgard Lima <edgard.lima@indt.org.br>
 * Copyright (C) 2005 Zeeshan Ali <zeenix@gmail.com>
 * Copyright (C) 2008 Axis Communications <dev-gstreamer@axis.com>
 *
 * 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.
 */

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gst/rtp/gstrtpbuffer.h>
#include <gst/audio/audio.h>

#include "gstrtpg726depay.h"
#include "gstrtputils.h"

GST_DEBUG_CATEGORY_STATIC (rtpg726depay_debug);
#define GST_CAT_DEFAULT (rtpg726depay_debug)

#define DEFAULT_BIT_RATE 32000
#define DEFAULT_BLOCK_ALIGN 4
#define SAMPLE_RATE 8000
#define LAYOUT_G726 "g726"

/* RtpG726Depay signals and args */
enum
{
  /* FILL ME */
  LAST_SIGNAL
};

#define DEFAULT_FORCE_AAL2	TRUE

enum
{
  PROP_0,
  PROP_FORCE_AAL2
};

static GstStaticPadTemplate gst_rtp_g726_depay_sink_template =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "encoding-name = (string) { \"G726\", \"G726-16\", \"G726-24\", \"G726-32\", \"G726-40\", "
        "\"AAL2-G726-16\", \"AAL2-G726-24\", \"AAL2-G726-32\", \"AAL2-G726-40\" }, "
        "clock-rate = (int) 8000;")
    );

static GstStaticPadTemplate gst_rtp_g726_depay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-adpcm, "
        "channels = (int) 1, "
        "rate = (int) 8000, "
        "bitrate = (int) { 16000, 24000, 32000, 40000 }, "
        "block_align = (int) { 2, 3, 4, 5 }, " "layout = (string) \"g726\"")
    );

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

static GstBuffer *gst_rtp_g726_depay_process (GstRTPBaseDepayload * depayload,
    GstRTPBuffer * rtp);
static gboolean gst_rtp_g726_depay_setcaps (GstRTPBaseDepayload * depayload,
    GstCaps * caps);

#define gst_rtp_g726_depay_parent_class parent_class
G_DEFINE_TYPE (GstRtpG726Depay, gst_rtp_g726_depay,
    GST_TYPE_RTP_BASE_DEPAYLOAD);

static void
gst_rtp_g726_depay_class_init (GstRtpG726DepayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;

  GST_DEBUG_CATEGORY_INIT (rtpg726depay_debug, "rtpg726depay", 0,
      "G.726 RTP Depayloader");

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;

  gobject_class->set_property = gst_rtp_g726_depay_set_property;
  gobject_class->get_property = gst_rtp_g726_depay_get_property;

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_FORCE_AAL2,
      g_param_spec_boolean ("force-aal2", "Force AAL2",
          "Force AAL2 decoding for compatibility with bad payloaders",
          DEFAULT_FORCE_AAL2, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_g726_depay_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_g726_depay_sink_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP G.726 depayloader", "Codec/Depayloader/Network/RTP",
      "Extracts G.726 audio from RTP packets",
      "Axis Communications <dev-gstreamer@axis.com>");

  gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_g726_depay_process;
  gstrtpbasedepayload_class->set_caps = gst_rtp_g726_depay_setcaps;
}

static void
gst_rtp_g726_depay_init (GstRtpG726Depay * rtpG726depay)
{
  GstRTPBaseDepayload *depayload;

  depayload = GST_RTP_BASE_DEPAYLOAD (rtpG726depay);

  gst_pad_use_fixed_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (depayload));

  rtpG726depay->force_aal2 = DEFAULT_FORCE_AAL2;
}

static gboolean
gst_rtp_g726_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
  GstCaps *srccaps;
  GstStructure *structure;
  gboolean ret;
  gint clock_rate;
  const gchar *encoding_name;
  GstRtpG726Depay *depay;

  depay = GST_RTP_G726_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    clock_rate = 8000;          /* default */
  depayload->clock_rate = clock_rate;

  depay->aal2 = FALSE;
  encoding_name = gst_structure_get_string (structure, "encoding-name");
  if (encoding_name == NULL || g_ascii_strcasecmp (encoding_name, "G726") == 0) {
    depay->bitrate = DEFAULT_BIT_RATE;
    depay->block_align = DEFAULT_BLOCK_ALIGN;
  } else {
    if (g_str_has_prefix (encoding_name, "AAL2-")) {
      depay->aal2 = TRUE;
      encoding_name += 5;
    }
    if (g_ascii_strcasecmp (encoding_name, "G726-16") == 0) {
      depay->bitrate = 16000;
      depay->block_align = 2;
    } else if (g_ascii_strcasecmp (encoding_name, "G726-24") == 0) {
      depay->bitrate = 24000;
      depay->block_align = 3;
    } else if (g_ascii_strcasecmp (encoding_name, "G726-32") == 0) {
      depay->bitrate = 32000;
      depay->block_align = 4;
    } else if (g_ascii_strcasecmp (encoding_name, "G726-40") == 0) {
      depay->bitrate = 40000;
      depay->block_align = 5;
    } else
      goto unknown_encoding;
  }

  GST_DEBUG ("RTP G.726 depayloader, bitrate set to %d\n", depay->bitrate);

  srccaps = gst_caps_new_simple ("audio/x-adpcm",
      "channels", G_TYPE_INT, 1,
      "rate", G_TYPE_INT, clock_rate,
      "bitrate", G_TYPE_INT, depay->bitrate,
      "block_align", G_TYPE_INT, depay->block_align,
      "layout", G_TYPE_STRING, LAYOUT_G726, NULL);

  ret = gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (depayload), srccaps);
  gst_caps_unref (srccaps);

  return ret;

  /* ERRORS */
unknown_encoding:
  {
    GST_WARNING ("Could not determine bitrate from encoding-name (%s)",
        encoding_name);
    return FALSE;
  }
}


static GstBuffer *
gst_rtp_g726_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
{
  GstRtpG726Depay *depay;
  GstBuffer *outbuf = NULL;
  gboolean marker;

  depay = GST_RTP_G726_DEPAY (depayload);

  marker = gst_rtp_buffer_get_marker (rtp);

  GST_DEBUG ("process : got %" G_GSIZE_FORMAT " bytes, mark %d ts %u seqn %d",
      gst_buffer_get_size (rtp->buffer), marker,
      gst_rtp_buffer_get_timestamp (rtp), gst_rtp_buffer_get_seq (rtp));

  if (depay->aal2 || depay->force_aal2) {
    /* AAL2, we can just copy the bytes */
    outbuf = gst_rtp_buffer_get_payload_buffer (rtp);
    if (!outbuf)
      goto bad_len;
    gst_rtp_drop_meta (GST_ELEMENT_CAST (depay), outbuf,
        g_quark_from_static_string (GST_META_TAG_AUDIO_STR));
  } else {
    guint8 *in, *out, tmp;
    guint len;
    GstMapInfo map;

    in = gst_rtp_buffer_get_payload (rtp);
    len = gst_rtp_buffer_get_payload_len (rtp);

    outbuf = gst_rtp_buffer_get_payload_buffer (rtp);
    if (!outbuf)
      goto bad_len;
    outbuf = gst_buffer_make_writable (outbuf);

    gst_rtp_drop_meta (GST_ELEMENT_CAST (depay), outbuf,
        g_quark_from_static_string (GST_META_TAG_AUDIO_STR));

    gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
    out = map.data;

    /* we need to reshuffle the bytes, input is always of the form
     * A B C D ... with the number of bits depending on the bitrate. */
    switch (depay->bitrate) {
      case 16000:
      {
        /*  0               
         *  0 1 2 3 4 5 6 7 
         * +-+-+-+-+-+-+-+-+-
         * |D D|C C|B B|A A| ...
         * |0 1|0 1|0 1|0 1|
         * +-+-+-+-+-+-+-+-+-
         */
        while (len > 0) {
          tmp = *in++;
          *out++ = ((tmp & 0xc0) >> 6) |
              ((tmp & 0x30) >> 2) | ((tmp & 0x0c) << 2) | ((tmp & 0x03) << 6);
          len--;
        }
        break;
      }
      case 24000:
      {
        /*  0                   1                   2
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         * |C C|B B B|A A A|F|E E E|D D D|C|H H H|G G G|F F| ...
         * |1 2|0 1 2|0 1 2|2|0 1 2|0 1 2|0|0 1 2|0 1 2|0 1|
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         */
        while (len > 2) {
          tmp = *in++;
          *out++ = ((tmp & 0xe0) >> 5) |
              ((tmp & 0x1c) << 1) | ((tmp & 0x03) << 6);
          tmp = *in++;
          *out++ = ((tmp & 0x80) >> 7) |
              ((tmp & 0x70) >> 3) | ((tmp & 0x0e) << 4) | ((tmp & 0x01) << 7);
          tmp = *in++;
          *out++ = ((tmp & 0xc0) >> 6) |
              ((tmp & 0x38) >> 1) | ((tmp & 0x07) << 5);
          len -= 3;
        }
        break;
      }
      case 32000:
      {
        /*  0                   1
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         * |B B B B|A A A A|D D D D|C C C C| ...
         * |0 1 2 3|0 1 2 3|0 1 2 3|0 1 2 3|
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         */
        while (len > 0) {
          tmp = *in++;
          *out++ = ((tmp & 0xf0) >> 4) | ((tmp & 0x0f) << 4);
          len--;
        }
        break;
      }
      case 40000:
      {
        /*  0                   1                   2                   3                   4
         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         * |B B B|A A A A A|D|C C C C C|B B|E E E E|D D D D|G G|F F F F F|E|H H H H H|G G G|
         * |2 3 4|0 1 2 3 4|4|0 1 2 3 4|0 1|1 2 3 4|0 1 2 3|3 4|0 1 2 3 4|0|0 1 2 3 4|0 1 2|   
         * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
         */
        while (len > 4) {
          tmp = *in++;
          *out++ = ((tmp & 0xf8) >> 3) | ((tmp & 0x07) << 5);
          tmp = *in++;
          *out++ = ((tmp & 0xc0) >> 6) |
              ((tmp & 0x3e) << 1) | ((tmp & 0x01) << 7);
          tmp = *in++;
          *out++ = ((tmp & 0xf0) >> 4) | ((tmp & 0x0f) << 4);
          tmp = *in++;
          *out++ = ((tmp & 0x80) >> 7) |
              ((tmp & 0x7c) >> 1) | ((tmp & 0x03) << 6);
          tmp = *in++;
          *out++ = ((tmp & 0xe0) >> 5) | ((tmp & 0x1f) << 3);
          len -= 5;
        }
        break;
      }
    }
    gst_buffer_unmap (outbuf, &map);
  }

  if (marker) {
    /* mark start of talkspurt with RESYNC */
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_RESYNC);
  }

  return outbuf;

bad_len:
  {
    return NULL;
  }
}

static void
gst_rtp_g726_depay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpG726Depay *rtpg726depay;

  rtpg726depay = GST_RTP_G726_DEPAY (object);

  switch (prop_id) {
    case PROP_FORCE_AAL2:
      rtpg726depay->force_aal2 = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_g726_depay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpG726Depay *rtpg726depay;

  rtpg726depay = GST_RTP_G726_DEPAY (object);

  switch (prop_id) {
    case PROP_FORCE_AAL2:
      g_value_set_boolean (value, rtpg726depay->force_aal2);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

gboolean
gst_rtp_g726_depay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpg726depay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_G726_DEPAY);
}
