/* GStreamer
 * Copyright (C) <2007> Nokia Corporation (contact <stefan.kost@nokia.com>)
 *               <2007> 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 version 2 as published by the Free Software Foundation.
 *
 * 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 <gst/base/gstbitreader.h>
#include <gst/rtp/gstrtpbuffer.h>
#include <gst/audio/audio.h>

#include <string.h>
#include "gstrtpmp4adepay.h"
#include "gstrtputils.h"

GST_DEBUG_CATEGORY_STATIC (rtpmp4adepay_debug);
#define GST_CAT_DEFAULT (rtpmp4adepay_debug)

static GstStaticPadTemplate gst_rtp_mp4a_depay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/mpeg,"
        "mpegversion = (int) 4," "framed = (boolean) true, "
        "stream-format = (string) raw")
    );

static GstStaticPadTemplate gst_rtp_mp4a_depay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"audio\", "
        "clock-rate = (int) [1, MAX ], "
        "encoding-name = (string) \"MP4A-LATM\""
        /* All optional parameters
         *
         * "profile-level-id=[1,MAX]"
         * "config="
         */
    )
    );

#define gst_rtp_mp4a_depay_parent_class parent_class
G_DEFINE_TYPE (GstRtpMP4ADepay, gst_rtp_mp4a_depay,
    GST_TYPE_RTP_BASE_DEPAYLOAD);

static void gst_rtp_mp4a_depay_finalize (GObject * object);

static gboolean gst_rtp_mp4a_depay_setcaps (GstRTPBaseDepayload * depayload,
    GstCaps * caps);
static GstBuffer *gst_rtp_mp4a_depay_process (GstRTPBaseDepayload * depayload,
    GstRTPBuffer * rtp);

static GstStateChangeReturn gst_rtp_mp4a_depay_change_state (GstElement *
    element, GstStateChange transition);


static void
gst_rtp_mp4a_depay_class_init (GstRtpMP4ADepayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;

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

  gobject_class->finalize = gst_rtp_mp4a_depay_finalize;

  gstelement_class->change_state = gst_rtp_mp4a_depay_change_state;

  gstrtpbasedepayload_class->process_rtp_packet = gst_rtp_mp4a_depay_process;
  gstrtpbasedepayload_class->set_caps = gst_rtp_mp4a_depay_setcaps;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_mp4a_depay_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_mp4a_depay_sink_template));

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP MPEG4 audio depayloader", "Codec/Depayloader/Network/RTP",
      "Extracts MPEG4 audio from RTP packets (RFC 3016)",
      "Nokia Corporation (contact <stefan.kost@nokia.com>), "
      "Wim Taymans <wim.taymans@gmail.com>");

  GST_DEBUG_CATEGORY_INIT (rtpmp4adepay_debug, "rtpmp4adepay", 0,
      "MPEG4 audio RTP Depayloader");
}

static void
gst_rtp_mp4a_depay_init (GstRtpMP4ADepay * rtpmp4adepay)
{
  rtpmp4adepay->adapter = gst_adapter_new ();
}

static void
gst_rtp_mp4a_depay_finalize (GObject * object)
{
  GstRtpMP4ADepay *rtpmp4adepay;

  rtpmp4adepay = GST_RTP_MP4A_DEPAY (object);

  g_object_unref (rtpmp4adepay->adapter);
  rtpmp4adepay->adapter = NULL;

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static const guint aac_sample_rates[] = { 96000, 88200, 64000, 48000,
  44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
};

static gboolean
gst_rtp_mp4a_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
  GstStructure *structure;
  GstRtpMP4ADepay *rtpmp4adepay;
  GstCaps *srccaps;
  const gchar *str;
  gint clock_rate;
  gint object_type;
  gint channels = 2;            /* default */
  gboolean res;

  rtpmp4adepay = GST_RTP_MP4A_DEPAY (depayload);

  structure = gst_caps_get_structure (caps, 0);

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

  if (!gst_structure_get_int (structure, "object", &object_type))
    object_type = 2;            /* AAC LC default */

  srccaps = gst_caps_new_simple ("audio/mpeg",
      "mpegversion", G_TYPE_INT, 4,
      "framed", G_TYPE_BOOLEAN, TRUE, "channels", G_TYPE_INT, channels,
      "stream-format", G_TYPE_STRING, "raw", NULL);

  if ((str = gst_structure_get_string (structure, "config"))) {
    GValue v = { 0 };

    g_value_init (&v, GST_TYPE_BUFFER);
    if (gst_value_deserialize (&v, str)) {
      GstBuffer *buffer;
      GstMapInfo map;
      guint8 *data;
      gsize size;
      gint i;
      guint32 rate = 0;
      guint8 obj_type = 0, sr_idx = 0, channels = 0;
      GstBitReader br;

      buffer = gst_value_get_buffer (&v);
      gst_buffer_ref (buffer);
      g_value_unset (&v);

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

      if (size < 2) {
        GST_WARNING_OBJECT (depayload, "config too short (%d < 2)",
            (gint) size);
        goto bad_config;
      }

      /* Parse StreamMuxConfig according to ISO/IEC 14496-3:
       *
       * audioMuxVersion           == 0 (1 bit)
       * allStreamsSameTimeFraming == 1 (1 bit)
       * numSubFrames              == rtpmp4adepay->numSubFrames (6 bits)
       * numProgram                == 0 (4 bits)
       * numLayer                  == 0 (3 bits)
       *
       * We only require audioMuxVersion == 0;
       *
       * The remaining bit of the second byte and the rest of the bits are used
       * for audioSpecificConfig which we need to set in codec_info.
       */
      if ((data[0] & 0x80) != 0x00) {
        GST_WARNING_OBJECT (depayload, "unknown audioMuxVersion 1");
        goto bad_config;
      }

      rtpmp4adepay->numSubFrames = (data[0] & 0x3F);

      GST_LOG_OBJECT (rtpmp4adepay, "numSubFrames %d",
          rtpmp4adepay->numSubFrames);

      /* shift rest of string 15 bits down */
      size -= 2;
      for (i = 0; i < size; i++) {
        data[i] = ((data[i + 1] & 1) << 7) | ((data[i + 2] & 0xfe) >> 1);
      }

      gst_bit_reader_init (&br, data, size);

      /* any object type is fine, we need to copy it to the profile-level-id field. */
      if (!gst_bit_reader_get_bits_uint8 (&br, &obj_type, 5))
        goto bad_config;
      if (obj_type == 0) {
        GST_WARNING_OBJECT (depayload, "invalid object type 0");
        goto bad_config;
      }

      if (!gst_bit_reader_get_bits_uint8 (&br, &sr_idx, 4))
        goto bad_config;
      if (sr_idx >= G_N_ELEMENTS (aac_sample_rates) && sr_idx != 15) {
        GST_WARNING_OBJECT (depayload, "invalid sample rate index %d", sr_idx);
        goto bad_config;
      }
      GST_LOG_OBJECT (rtpmp4adepay, "sample rate index %u", sr_idx);

      if (!gst_bit_reader_get_bits_uint8 (&br, &channels, 4))
        goto bad_config;
      if (channels > 7) {
        GST_WARNING_OBJECT (depayload, "invalid channels %u", (guint) channels);
        goto bad_config;
      }

      /* rtp rate depends on sampling rate of the audio */
      if (sr_idx == 15) {
        /* index of 15 means we get the rate in the next 24 bits */
        if (!gst_bit_reader_get_bits_uint32 (&br, &rate, 24))
          goto bad_config;
      } else if (sr_idx >= G_N_ELEMENTS (aac_sample_rates)) {
        goto bad_config;
      } else {
        /* else use the rate from the table */
        rate = aac_sample_rates[sr_idx];
      }

      rtpmp4adepay->frame_len = 1024;

      switch (obj_type) {
        case 1:
        case 2:
        case 3:
        case 4:
        case 6:
        case 7:
        {
          guint8 frameLenFlag = 0;

          if (gst_bit_reader_get_bits_uint8 (&br, &frameLenFlag, 1))
            if (frameLenFlag)
              rtpmp4adepay->frame_len = 960;
          break;
        }
        default:
          break;
      }

      /* ignore remaining bit, we're only interested in full bytes */
      gst_buffer_resize (buffer, 0, size);
      gst_buffer_unmap (buffer, &map);
      data = NULL;

      gst_caps_set_simple (srccaps,
          "channels", G_TYPE_INT, (gint) channels,
          "rate", G_TYPE_INT, (gint) rate,
          "codec_data", GST_TYPE_BUFFER, buffer, NULL);
    bad_config:
      if (data)
        gst_buffer_unmap (buffer, &map);
      gst_buffer_unref (buffer);
    } else {
      g_warning ("cannot convert config to buffer");
    }
  }
  res = gst_pad_set_caps (depayload->srcpad, srccaps);
  gst_caps_unref (srccaps);

  return res;
}

static GstBuffer *
gst_rtp_mp4a_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
{
  GstRtpMP4ADepay *rtpmp4adepay;
  GstBuffer *outbuf;
  GstMapInfo map;

  rtpmp4adepay = GST_RTP_MP4A_DEPAY (depayload);

  /* flush remaining data on discont */
  if (GST_BUFFER_IS_DISCONT (rtp->buffer)) {
    gst_adapter_clear (rtpmp4adepay->adapter);
  }

  outbuf = gst_rtp_buffer_get_payload_buffer (rtp);

  outbuf = gst_buffer_make_writable (outbuf);
  GST_BUFFER_PTS (outbuf) = GST_BUFFER_PTS (rtp->buffer);
  gst_adapter_push (rtpmp4adepay->adapter, outbuf);

  /* RTP marker bit indicates the last packet of the AudioMuxElement => create
   * and push a buffer */
  if (gst_rtp_buffer_get_marker (rtp)) {
    guint avail;
    guint i;
    guint8 *data;
    guint pos;
    GstClockTime timestamp;

    avail = gst_adapter_available (rtpmp4adepay->adapter);
    timestamp = gst_adapter_prev_pts (rtpmp4adepay->adapter, NULL);

    GST_LOG_OBJECT (rtpmp4adepay, "have marker and %u available", avail);

    outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
    gst_buffer_map (outbuf, &map, GST_MAP_READ);
    data = map.data;
    /* position in data we are at */
    pos = 0;

    /* looping through the number of sub-frames in the audio payload */
    for (i = 0; i <= rtpmp4adepay->numSubFrames; i++) {
      /* determine payload length and set buffer data pointer accordingly */
      guint skip;
      guint data_len;
      GstBuffer *tmp = NULL;

      /* each subframe starts with a variable length encoding */
      data_len = 0;
      for (skip = 0; skip < avail; skip++) {
        data_len += data[skip];
        if (data[skip] != 0xff)
          break;
      }
      skip++;

      /* this can not be possible, we have not enough data or the length
       * decoding failed because we ran out of data. */
      if (skip + data_len > avail)
        goto wrong_size;

      GST_LOG_OBJECT (rtpmp4adepay,
          "subframe %u, header len %u, data len %u, left %u", i, skip, data_len,
          avail);

      /* take data out, skip the header */
      pos += skip;
      tmp = gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, pos, data_len);

      /* skip data too */
      skip += data_len;
      pos += data_len;

      /* update our pointers whith what we consumed */
      data += skip;
      avail -= skip;

      GST_BUFFER_PTS (tmp) = timestamp;
      gst_rtp_drop_meta (GST_ELEMENT_CAST (depayload), tmp,
          g_quark_from_static_string (GST_META_TAG_AUDIO_STR));
      gst_rtp_base_depayload_push (depayload, tmp);

      /* shift ts for next buffers */
      if (rtpmp4adepay->frame_len && timestamp != -1
          && depayload->clock_rate != 0) {
        timestamp +=
            gst_util_uint64_scale_int (rtpmp4adepay->frame_len, GST_SECOND,
            depayload->clock_rate);
      }
    }

    /* just a check that lengths match */
    if (avail) {
      GST_ELEMENT_WARNING (depayload, STREAM, DECODE,
          ("Packet invalid"), ("Not all payload consumed: "
              "possible wrongly encoded packet."));
    }

    gst_buffer_unmap (outbuf, &map);
    gst_buffer_unref (outbuf);
  }
  return NULL;

  /* ERRORS */
wrong_size:
  {
    GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
        ("Packet did not validate"), ("wrong packet size"));
    gst_buffer_unmap (outbuf, &map);
    gst_buffer_unref (outbuf);
    return NULL;
  }
}

static GstStateChangeReturn
gst_rtp_mp4a_depay_change_state (GstElement * element,
    GstStateChange transition)
{
  GstRtpMP4ADepay *rtpmp4adepay;
  GstStateChangeReturn ret;

  rtpmp4adepay = GST_RTP_MP4A_DEPAY (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_adapter_clear (rtpmp4adepay->adapter);
      rtpmp4adepay->frame_len = 0;
      rtpmp4adepay->numSubFrames = 0;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    default:
      break;
  }
  return ret;
}

gboolean
gst_rtp_mp4a_depay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpmp4adepay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_MP4A_DEPAY);
}
