/* GStreamer
 * Copyright (C) <2010> Wim Taymans <wim.taymans@gmail.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 <string.h>

#include <gst/audio/audio.h>
#include <gst/rtp/gstrtpbuffer.h>

#include "gstrtpg722pay.h"
#include "gstrtpchannels.h"

GST_DEBUG_CATEGORY_STATIC (rtpg722pay_debug);
#define GST_CAT_DEFAULT (rtpg722pay_debug)

static GstStaticPadTemplate gst_rtp_g722_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/G722, " "rate = (int) 16000, " "channels = (int) 1")
    );

static GstStaticPadTemplate gst_rtp_g722_pay_src_template =
    GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "encoding-name = (string) \"G722\", "
        "payload = (int) " GST_RTP_PAYLOAD_G722_STRING ", "
        "clock-rate = (int) 8000; "
        "application/x-rtp, "
        "media = (string) \"audio\", "
        "encoding-name = (string) \"G722\", "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
        "clock-rate = (int) 8000")
    );

static gboolean gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload,
    GstCaps * caps);
static GstCaps *gst_rtp_g722_pay_getcaps (GstRTPBasePayload * rtppayload,
    GstPad * pad, GstCaps * filter);

#define gst_rtp_g722_pay_parent_class parent_class
G_DEFINE_TYPE (GstRtpG722Pay, gst_rtp_g722_pay,
    GST_TYPE_RTP_BASE_AUDIO_PAYLOAD);

static void
gst_rtp_g722_pay_class_init (GstRtpG722PayClass * klass)
{
  GstElementClass *gstelement_class;
  GstRTPBasePayloadClass *gstrtpbasepayload_class;

  GST_DEBUG_CATEGORY_INIT (rtpg722pay_debug, "rtpg722pay", 0,
      "G722 RTP Payloader");

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

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_g722_pay_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_g722_pay_sink_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP audio payloader", "Codec/Payloader/Network/RTP",
      "Payload-encode Raw audio into RTP packets (RFC 3551)",
      "Wim Taymans <wim.taymans@gmail.com>");

  gstrtpbasepayload_class->set_caps = gst_rtp_g722_pay_setcaps;
  gstrtpbasepayload_class->get_caps = gst_rtp_g722_pay_getcaps;
}

static void
gst_rtp_g722_pay_init (GstRtpG722Pay * rtpg722pay)
{
  GstRTPBaseAudioPayload *rtpbaseaudiopayload;

  rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (rtpg722pay);

  GST_RTP_BASE_PAYLOAD (rtpg722pay)->pt = GST_RTP_PAYLOAD_G722;

  /* tell rtpbaseaudiopayload that this is a sample based codec */
  gst_rtp_base_audio_payload_set_sample_based (rtpbaseaudiopayload);
}

static gboolean
gst_rtp_g722_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
{
  GstRtpG722Pay *rtpg722pay;
  GstStructure *structure;
  gint rate, channels, clock_rate;
  gboolean res;
  gchar *params;
#if 0
  GstAudioChannelPosition *pos;
  const GstRTPChannelOrder *order;
#endif
  GstRTPBaseAudioPayload *rtpbaseaudiopayload;

  rtpbaseaudiopayload = GST_RTP_BASE_AUDIO_PAYLOAD (basepayload);
  rtpg722pay = GST_RTP_G722_PAY (basepayload);

  structure = gst_caps_get_structure (caps, 0);

  /* first parse input caps */
  if (!gst_structure_get_int (structure, "rate", &rate))
    goto no_rate;

  if (!gst_structure_get_int (structure, "channels", &channels))
    goto no_channels;

  /* FIXME: Do something with the channel positions */
#if 0
  /* get the channel order */
  pos = gst_audio_get_channel_positions (structure);
  if (pos)
    order = gst_rtp_channels_get_by_pos (channels, pos);
  else
    order = NULL;
#endif

  /* Clock rate is always 8000 Hz for G722 according to
   * RFC 3551 although the sampling rate is 16000 Hz */
  clock_rate = 8000;

  gst_rtp_base_payload_set_options (basepayload, "audio",
      basepayload->pt != GST_RTP_PAYLOAD_G722, "G722", clock_rate);
  params = g_strdup_printf ("%d", channels);

#if 0
  if (!order && channels > 2) {
    GST_ELEMENT_WARNING (rtpg722pay, STREAM, DECODE,
        (NULL), ("Unknown channel order for %d channels", channels));
  }

  if (order && order->name) {
    res = gst_rtp_base_payload_set_outcaps (basepayload,
        "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT,
        channels, "channel-order", G_TYPE_STRING, order->name, NULL);
  } else {
#endif
    res = gst_rtp_base_payload_set_outcaps (basepayload,
        "encoding-params", G_TYPE_STRING, params, "channels", G_TYPE_INT,
        channels, NULL);
#if 0
  }
#endif

  g_free (params);
#if 0
  g_free (pos);
#endif

  rtpg722pay->rate = rate;
  rtpg722pay->channels = channels;

  /* bits-per-sample is 4 * channels for G722, but as the RTP clock runs at
   * half speed (8 instead of 16 khz), pretend it's 8 bits per sample
   * channels. */
  gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload,
      8 * rtpg722pay->channels);

  return res;

  /* ERRORS */
no_rate:
  {
    GST_DEBUG_OBJECT (rtpg722pay, "no rate given");
    return FALSE;
  }
no_channels:
  {
    GST_DEBUG_OBJECT (rtpg722pay, "no channels given");
    return FALSE;
  }
}

static GstCaps *
gst_rtp_g722_pay_getcaps (GstRTPBasePayload * rtppayload, GstPad * pad,
    GstCaps * filter)
{
  GstCaps *otherpadcaps;
  GstCaps *caps;

  otherpadcaps = gst_pad_get_allowed_caps (rtppayload->srcpad);
  caps = gst_pad_get_pad_template_caps (pad);

  if (otherpadcaps) {
    if (!gst_caps_is_empty (otherpadcaps)) {
      caps = gst_caps_make_writable (caps);
      gst_caps_set_simple (caps, "channels", G_TYPE_INT, 1, NULL);
      gst_caps_set_simple (caps, "rate", G_TYPE_INT, 16000, NULL);
    }
    gst_caps_unref (otherpadcaps);
  }

  if (filter) {
    GstCaps *tmp;

    GST_DEBUG_OBJECT (rtppayload, "Intersect %" GST_PTR_FORMAT " and filter %"
        GST_PTR_FORMAT, caps, filter);
    tmp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
    caps = tmp;
  }

  return caps;
}

gboolean
gst_rtp_g722_pay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpg722pay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_G722_PAY);
}
