/* 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

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

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

#include "gstrtpg726depay.h"

GST_DEBUG_CATEGORY_STATIC (rtpg726depay_debug);
#define GST_CAT_DEFAULT (rtpg726depay_debug)

#define DEFAULT_BIT_RATE 32000
#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,
  PROP_LAST
};

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 }, "
        "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,
    GstBuffer * buf);
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_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_g726_depay_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&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 = 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;
  } 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;
    } else if (g_ascii_strcasecmp (encoding_name, "G726-24") == 0) {
      depay->bitrate = 24000;
    } else if (g_ascii_strcasecmp (encoding_name, "G726-32") == 0) {
      depay->bitrate = 32000;
    } else if (g_ascii_strcasecmp (encoding_name, "G726-40") == 0) {
      depay->bitrate = 40000;
    } 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,
      "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, GstBuffer * buf)
{
  GstRtpG726Depay *depay;
  GstBuffer *outbuf = NULL;
  gboolean marker;
  GstRTPBuffer rtp = { NULL };

  depay = GST_RTP_G726_DEPAY (depayload);

  gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);

  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 (buf), 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;
  } 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_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 discont */
    GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
  }

  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);
}
