/* GStreamer
 * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
 * Copyright (C) 2005 Edgard Lima <edgard.lima@indt.org.br>
 * Copyright (C) 2005 Nokia Corporation <kai.vehmanen@nokia.com>
 * Copyright (C) 2007,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 <stdlib.h>
#include <string.h>
#include <gst/rtp/gstrtpbuffer.h>

#include "gstrtpg726pay.h"

GST_DEBUG_CATEGORY_STATIC (rtpg726pay_debug);
#define GST_CAT_DEFAULT (rtpg726pay_debug)

#define DEFAULT_FORCE_AAL2      TRUE

enum
{
  PROP_0,
  PROP_FORCE_AAL2
};

static GstStaticPadTemplate gst_rtp_g726_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    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 GstStaticPadTemplate gst_rtp_g726_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
        "clock-rate = (int) 8000, "
        "encoding-name = (string) { \"G726-16\", \"G726-24\", \"G726-32\", \"G726-40\", "
        "    \"AAL2-G726-16\", \"AAL2-G726-24\", \"AAL2-G726-32\", \"AAL2-G726-40\" } ")
    );

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

static gboolean gst_rtp_g726_pay_setcaps (GstRTPBasePayload * payload,
    GstCaps * caps);
static GstFlowReturn gst_rtp_g726_pay_handle_buffer (GstRTPBasePayload *
    payload, GstBuffer * buffer);

#define gst_rtp_g726_pay_parent_class parent_class
G_DEFINE_TYPE (GstRtpG726Pay, gst_rtp_g726_pay,
    GST_TYPE_RTP_BASE_AUDIO_PAYLOAD);

static void
gst_rtp_g726_pay_class_init (GstRtpG726PayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBasePayloadClass *gstrtpbasepayload_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;

  gobject_class->set_property = gst_rtp_g726_pay_set_property;
  gobject_class->get_property = gst_rtp_g726_pay_get_property;

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

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_g726_pay_sink_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_g726_pay_src_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP G.726 payloader", "Codec/Payloader/Network/RTP",
      "Payload-encodes G.726 audio into a RTP packet",
      "Axis Communications <dev-gstreamer@axis.com>");

  gstrtpbasepayload_class->set_caps = gst_rtp_g726_pay_setcaps;
  gstrtpbasepayload_class->handle_buffer = gst_rtp_g726_pay_handle_buffer;

  GST_DEBUG_CATEGORY_INIT (rtpg726pay_debug, "rtpg726pay", 0,
      "G.726 RTP Payloader");
}

static void
gst_rtp_g726_pay_init (GstRtpG726Pay * rtpg726pay)
{
  GstRTPBaseAudioPayload *rtpbaseaudiopayload;

  rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpg726pay);

  GST_RTP_BASE_PAYLOAD (rtpg726pay)->clock_rate = 8000;

  rtpg726pay->force_aal2 = DEFAULT_FORCE_AAL2;

  /* sample based codec */
  gst_rtp_base_audio_payload_set_sample_based (rtpbaseaudiopayload);
}

static gboolean
gst_rtp_g726_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
{
  gchar *encoding_name;
  GstStructure *structure;
  GstRTPBaseAudioPayload *rtpbaseaudiopayload;
  GstRtpG726Pay *pay;
  GstCaps *peercaps;
  gboolean res;

  rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (payload);
  pay = GST_RTP_G726_PAY (payload);

  structure = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (structure, "bitrate", &pay->bitrate))
    pay->bitrate = 32000;

  GST_DEBUG_OBJECT (payload, "using bitrate %d", pay->bitrate);

  pay->aal2 = FALSE;

  /* first see what we can do with the bitrate */
  switch (pay->bitrate) {
    case 16000:
      encoding_name = g_strdup ("G726-16");
      gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload,
          2);
      break;
    case 24000:
      encoding_name = g_strdup ("G726-24");
      gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload,
          3);
      break;
    case 32000:
      encoding_name = g_strdup ("G726-32");
      gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload,
          4);
      break;
    case 40000:
      encoding_name = g_strdup ("G726-40");
      gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload,
          5);
      break;
    default:
      goto invalid_bitrate;
  }

  GST_DEBUG_OBJECT (payload, "selected base encoding %s", encoding_name);

  /* now see if we need to produce AAL2 or not */
  peercaps = gst_pad_peer_query_caps (payload->srcpad, NULL);
  if (peercaps) {
    GstCaps *filter, *intersect;
    gchar *capsstr;

    GST_DEBUG_OBJECT (payload, "have peercaps %" GST_PTR_FORMAT, peercaps);

    capsstr = g_strdup_printf ("application/x-rtp, "
        "media = (string) \"audio\", "
        "clock-rate = (int) 8000, "
        "encoding-name = (string) %s; "
        "application/x-rtp, "
        "media = (string) \"audio\", "
        "clock-rate = (int) 8000, "
        "encoding-name = (string) AAL2-%s", encoding_name, encoding_name);
    filter = gst_caps_from_string (capsstr);
    g_free (capsstr);
    g_free (encoding_name);

    /* intersect to filter */
    intersect = gst_caps_intersect (peercaps, filter);
    gst_caps_unref (peercaps);
    gst_caps_unref (filter);

    GST_DEBUG_OBJECT (payload, "intersected to %" GST_PTR_FORMAT, intersect);

    if (!intersect)
      goto no_format;
    if (gst_caps_is_empty (intersect)) {
      gst_caps_unref (intersect);
      goto no_format;
    }

    structure = gst_caps_get_structure (intersect, 0);

    /* now see what encoding name we settled on, we need to dup because the
     * string goes away when we unref the intersection below. */
    encoding_name =
        g_strdup (gst_structure_get_string (structure, "encoding-name"));

    /* if we managed to negotiate to AAL2, we definatly are going to do AAL2
     * encoding. Else we only encode AAL2 when explicitly set by the
     * property. */
    if (g_str_has_prefix (encoding_name, "AAL2-"))
      pay->aal2 = TRUE;
    else
      pay->aal2 = pay->force_aal2;

    GST_DEBUG_OBJECT (payload, "final encoding %s, AAL2 %d", encoding_name,
        pay->aal2);

    gst_caps_unref (intersect);
  } else {
    /* downstream can do anything but we prefer the better supported non-AAL2 */
    pay->aal2 = pay->force_aal2;
    GST_DEBUG_OBJECT (payload, "no peer caps, AAL2 %d", pay->aal2);
  }

  gst_rtp_base_payload_set_options (payload, "audio", TRUE, encoding_name,
      8000);
  res = gst_rtp_base_payload_set_outcaps (payload, NULL);

  g_free (encoding_name);

  return res;

  /* ERRORS */
invalid_bitrate:
  {
    GST_ERROR_OBJECT (payload, "invalid bitrate %d specified", pay->bitrate);
    return FALSE;
  }
no_format:
  {
    GST_ERROR_OBJECT (payload, "could not negotiate format");
    return FALSE;
  }
}

static GstFlowReturn
gst_rtp_g726_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
{
  GstFlowReturn res;
  GstRtpG726Pay *pay;

  pay = GST_RTP_G726_PAY (payload);

  if (!pay->aal2) {
    GstMapInfo map;
    guint8 *data, tmp;
    gsize size;

    /* for non AAL2, we need to reshuffle the bytes, we can do this in-place
     * when the buffer is writable. */
    buffer = gst_buffer_make_writable (buffer);

    gst_buffer_map (buffer, &map, GST_MAP_READWRITE);
    data = map.data;
    size = map.size;

    GST_LOG_OBJECT (pay, "packing %" G_GSIZE_FORMAT " bytes of data", map.size);

    /* we need to reshuffle the bytes, output is of the form:
     * A B C D .. with the number of bits depending on the bitrate. */
    switch (pay->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 (size > 0) {
          tmp = *data;
          *data++ = ((tmp & 0xc0) >> 6) |
              ((tmp & 0x30) >> 2) | ((tmp & 0x0c) << 2) | ((tmp & 0x03) << 6);
          size--;
        }
        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 (size > 2) {
          tmp = *data;
          *data++ = ((tmp & 0xc0) >> 6) |
              ((tmp & 0x38) >> 1) | ((tmp & 0x07) << 5);
          tmp = *data;
          *data++ = ((tmp & 0x80) >> 7) |
              ((tmp & 0x70) >> 3) | ((tmp & 0x0e) << 4) | ((tmp & 0x01) << 7);
          tmp = *data;
          *data++ = ((tmp & 0xe0) >> 5) |
              ((tmp & 0x1c) >> 2) | ((tmp & 0x03) << 6);
          size -= 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 (size > 0) {
          tmp = *data;
          *data++ = ((tmp & 0xf0) >> 4) | ((tmp & 0x0f) << 4);
          size--;
        }
        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 (size > 4) {
          tmp = *data;
          *data++ = ((tmp & 0xe0) >> 5) | ((tmp & 0x1f) << 3);
          tmp = *data;
          *data++ = ((tmp & 0x80) >> 7) |
              ((tmp & 0x7c) >> 2) | ((tmp & 0x03) << 6);
          tmp = *data;
          *data++ = ((tmp & 0xf0) >> 4) | ((tmp & 0x0f) << 4);
          tmp = *data;
          *data++ = ((tmp & 0xc0) >> 6) |
              ((tmp & 0x3e) << 2) | ((tmp & 0x01) << 7);
          tmp = *data;
          *data++ = ((tmp & 0xf8) >> 3) | ((tmp & 0x07) << 5);
          size -= 5;
        }
        break;
      }
    }
    gst_buffer_unmap (buffer, &map);
  }

  res =
      GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->handle_buffer (payload,
      buffer);

  return res;
}

static void
gst_rtp_g726_pay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpG726Pay *rtpg726pay;

  rtpg726pay = GST_RTP_G726_PAY (object);

  switch (prop_id) {
    case PROP_FORCE_AAL2:
      rtpg726pay->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_pay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpG726Pay *rtpg726pay;

  rtpg726pay = GST_RTP_G726_PAY (object);

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

gboolean
gst_rtp_g726_pay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpg726pay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_G726_PAY);
}
