/*
 * gstrtpvp8pay.c - Source for GstRtpVP8Pay
 * Copyright (C) 2011 Sjoerd Simons <sjoerd@luon.net>
 * Copyright (C) 2011 Collabora Ltd.
 *   Contact: Youness Alaoui <youness.alaoui@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser 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/base/gstbitreader.h>
#include <gst/rtp/gstrtppayloads.h>
#include <gst/rtp/gstrtpbuffer.h>
#include <gst/video/video.h>
#include "dboolhuff.h"
#include "gstrtpvp8pay.h"
#include "gstrtputils.h"

GST_DEBUG_CATEGORY_STATIC (gst_rtp_vp8_pay_debug);
#define GST_CAT_DEFAULT gst_rtp_vp8_pay_debug

#define DEFAULT_PICTURE_ID_MODE VP8_PAY_NO_PICTURE_ID

enum
{
  PROP_0,
  PROP_PICTURE_ID_MODE
};

#define GST_TYPE_RTP_VP8_PAY_PICTURE_ID_MODE (gst_rtp_vp8_pay_picture_id_mode_get_type())
static GType
gst_rtp_vp8_pay_picture_id_mode_get_type (void)
{
  static GType mode_type = 0;
  static const GEnumValue modes[] = {
    {VP8_PAY_NO_PICTURE_ID, "No Picture ID", "none"},
    {VP8_PAY_PICTURE_ID_7BITS, "7-bit Picture ID", "7-bit"},
    {VP8_PAY_PICTURE_ID_15BITS, "15-bit Picture ID", "15-bit"},
    {0, NULL, NULL},
  };

  if (!mode_type) {
    mode_type = g_enum_register_static ("GstVP8RTPPayMode", modes);
  }
  return mode_type;
}

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

static GstFlowReturn gst_rtp_vp8_pay_handle_buffer (GstRTPBasePayload * payload,
    GstBuffer * buffer);
static gboolean gst_rtp_vp8_pay_sink_event (GstRTPBasePayload * payload,
    GstEvent * event);
static gboolean gst_rtp_vp8_pay_set_caps (GstRTPBasePayload * payload,
    GstCaps * caps);

G_DEFINE_TYPE (GstRtpVP8Pay, gst_rtp_vp8_pay, GST_TYPE_RTP_BASE_PAYLOAD);

static GstStaticPadTemplate gst_rtp_vp8_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ","
        "clock-rate = (int) 90000, encoding-name = (string) { \"VP8\", \"VP8-DRAFT-IETF-01\" }"));

static GstStaticPadTemplate gst_rtp_vp8_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-vp8"));

static void
gst_rtp_vp8_pay_init (GstRtpVP8Pay * obj)
{
  obj->picture_id_mode = DEFAULT_PICTURE_ID_MODE;
  if (obj->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS)
    obj->picture_id = g_random_int_range (0, G_MAXUINT8) & 0x7F;
  else if (obj->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS)
    obj->picture_id = g_random_int_range (0, G_MAXUINT16) & 0x7FFF;
}

static void
gst_rtp_vp8_pay_class_init (GstRtpVP8PayClass * gst_rtp_vp8_pay_class)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (gst_rtp_vp8_pay_class);
  GstElementClass *element_class = GST_ELEMENT_CLASS (gst_rtp_vp8_pay_class);
  GstRTPBasePayloadClass *pay_class =
      GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_vp8_pay_class);

  gobject_class->set_property = gst_rtp_vp8_pay_set_property;
  gobject_class->get_property = gst_rtp_vp8_pay_get_property;

  g_object_class_install_property (gobject_class, PROP_PICTURE_ID_MODE,
      g_param_spec_enum ("picture-id-mode", "Picture ID Mode",
          "The picture ID mode for payloading",
          GST_TYPE_RTP_VP8_PAY_PICTURE_ID_MODE, DEFAULT_PICTURE_ID_MODE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_rtp_vp8_pay_sink_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_rtp_vp8_pay_src_template));

  gst_element_class_set_static_metadata (element_class, "RTP VP8 payloader",
      "Codec/Payloader/Network/RTP",
      "Puts VP8 video in RTP packets", "Sjoerd Simons <sjoerd@luon.net>");

  pay_class->handle_buffer = gst_rtp_vp8_pay_handle_buffer;
  pay_class->sink_event = gst_rtp_vp8_pay_sink_event;
  pay_class->set_caps = gst_rtp_vp8_pay_set_caps;

  GST_DEBUG_CATEGORY_INIT (gst_rtp_vp8_pay_debug, "rtpvp8pay", 0,
      "VP8 Video RTP Payloader");
}

static void
gst_rtp_vp8_pay_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstRtpVP8Pay *rtpvp8pay = GST_RTP_VP8_PAY (object);

  switch (prop_id) {
    case PROP_PICTURE_ID_MODE:
      rtpvp8pay->picture_id_mode = g_value_get_enum (value);
      if (rtpvp8pay->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS)
        rtpvp8pay->picture_id = g_random_int_range (0, G_MAXUINT8) & 0x7F;
      else if (rtpvp8pay->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS)
        rtpvp8pay->picture_id = g_random_int_range (0, G_MAXUINT16) & 0x7FFF;
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_vp8_pay_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstRtpVP8Pay *rtpvp8pay = GST_RTP_VP8_PAY (object);

  switch (prop_id) {
    case PROP_PICTURE_ID_MODE:
      g_value_set_enum (value, rtpvp8pay->picture_id_mode);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_rtp_vp8_pay_parse_frame (GstRtpVP8Pay * self, GstBuffer * buffer,
    gsize buffer_size)
{
  GstMapInfo map = GST_MAP_INFO_INIT;
  GstBitReader reader;
  guint8 *data;
  gsize size;
  int i;
  gboolean keyframe;
  guint32 partition0_size;
  guint8 version;
  guint8 tmp8 = 0;
  guint8 partitions;
  guint offset;
  BOOL_DECODER bc;
  guint8 *pdata;

  if (G_UNLIKELY (buffer_size < 3))
    goto error;

  if (!gst_buffer_map (buffer, &map, GST_MAP_READ) || !map.data)
    goto error;

  data = map.data;
  size = map.size;

  gst_bit_reader_init (&reader, data, size);

  self->is_keyframe = keyframe = ((data[0] & 0x1) == 0);
  version = (data[0] >> 1) & 0x7;

  if (G_UNLIKELY (version > 3)) {
    GST_ERROR_OBJECT (self, "Unknown VP8 version %u", version);
    goto error;
  }

  /* keyframe, version and show_frame use 5 bits */
  partition0_size = data[2] << 11 | data[1] << 3 | (data[0] >> 5);

  /* Include the uncompressed data blob in the first partition */
  offset = keyframe ? 10 : 3;
  partition0_size += offset;

  if (!gst_bit_reader_skip (&reader, 24))
    goto error;

  if (keyframe) {
    /* check start tag: 0x9d 0x01 0x2a */
    if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp8, 8) || tmp8 != 0x9d)
      goto error;

    if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp8, 8) || tmp8 != 0x01)
      goto error;

    if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp8, 8) || tmp8 != 0x2a)
      goto error;

    /* Skip horizontal size code (16 bits) vertical size code (16 bits) */
    if (!gst_bit_reader_skip (&reader, 32))
      goto error;
  }

  offset = keyframe ? 10 : 3;
  vp8dx_start_decode (&bc, data + offset, size - offset);

  if (keyframe) {
    /* color space (1 bit) and clamping type (1 bit) */
    vp8dx_decode_bool (&bc, 0x80);
    vp8dx_decode_bool (&bc, 0x80);
  }

  /* segmentation_enabled */
  if (vp8dx_decode_bool (&bc, 0x80)) {
    guint8 update_mb_segmentation_map = vp8dx_decode_bool (&bc, 0x80);
    guint8 update_segment_feature_data = vp8dx_decode_bool (&bc, 0x80);

    if (update_segment_feature_data) {
      /* skip segment feature mode */
      vp8dx_decode_bool (&bc, 0x80);

      /* quantizer update */
      for (i = 0; i < 4; i++) {
        /* skip flagged quantizer value (7 bits) and sign (1 bit) */
        if (vp8dx_decode_bool (&bc, 0x80))
          vp8_decode_value (&bc, 8);
      }

      /* loop filter update */
      for (i = 0; i < 4; i++) {
        /* skip flagged lf update value (6 bits) and sign (1 bit) */
        if (vp8dx_decode_bool (&bc, 0x80))
          vp8_decode_value (&bc, 7);
      }
    }

    if (update_mb_segmentation_map) {
      /* segment prob update */
      for (i = 0; i < 3; i++) {
        /* skip flagged segment prob */
        if (vp8dx_decode_bool (&bc, 0x80))
          vp8_decode_value (&bc, 8);
      }
    }
  }

  /* skip filter type (1 bit), loop filter level (6 bits) and
   * sharpness level (3 bits) */
  vp8_decode_value (&bc, 1);
  vp8_decode_value (&bc, 6);
  vp8_decode_value (&bc, 3);

  /* loop_filter_adj_enabled */
  if (vp8dx_decode_bool (&bc, 0x80)) {

    /* delta update */
    if (vp8dx_decode_bool (&bc, 0x80)) {

      for (i = 0; i < 8; i++) {
        /* 8 updates, 1 bit indicate whether there is one and if follow by a
         * 7 bit update */
        if (vp8dx_decode_bool (&bc, 0x80))
          vp8_decode_value (&bc, 7);
      }
    }
  }

  if (vp8dx_bool_error (&bc))
    goto error;

  tmp8 = vp8_decode_value (&bc, 2);

  partitions = 1 << tmp8;

  /* Check if things are still sensible */
  if (partition0_size + (partitions - 1) * 3 >= size)
    goto error;

  /* partition data is right after the mode partition */
  pdata = data + partition0_size;

  /* Set up mapping */
  self->n_partitions = partitions + 1;
  self->partition_offset[0] = 0;
  self->partition_size[0] = partition0_size + (partitions - 1) * 3;

  self->partition_offset[1] = self->partition_size[0];
  for (i = 1; i < partitions; i++) {
    guint psize = (pdata[2] << 16 | pdata[1] << 8 | pdata[0]);

    pdata += 3;
    self->partition_size[i] = psize;
    self->partition_offset[i + 1] = self->partition_offset[i] + psize;
  }

  /* Check that our partition offsets and sizes don't go outsize the buffer
   * size. */
  if (self->partition_offset[i] >= size)
    goto error;

  self->partition_size[i] = size - self->partition_offset[i];

  self->partition_offset[i + 1] = size;

  gst_buffer_unmap (buffer, &map);
  return TRUE;

error:
  GST_DEBUG ("Failed to parse frame");
  if (map.memory != NULL) {
    gst_buffer_unmap (buffer, &map);
  }
  return FALSE;
}

static guint
gst_rtp_vp8_offset_to_partition (GstRtpVP8Pay * self, guint offset)
{
  int i;

  for (i = 1; i < self->n_partitions; i++) {
    if (offset < self->partition_offset[i])
      return i - 1;
  }

  return i - 1;
}

static gsize
gst_rtp_vp8_calc_header_len (GstRtpVP8Pay * self)
{
  switch (self->picture_id_mode) {
    case VP8_PAY_PICTURE_ID_7BITS:
      return 3;
    case VP8_PAY_PICTURE_ID_15BITS:
      return 4;
    case VP8_PAY_NO_PICTURE_ID:
    default:
      return 1;
  }
}

/* When growing the vp8 header keep max payload len calculation in sync */
static GstBuffer *
gst_rtp_vp8_create_header_buffer (GstRtpVP8Pay * self, guint8 partid,
    gboolean start, gboolean mark, GstBuffer * in)
{
  GstBuffer *out;
  guint8 *p;
  GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;

  out = gst_rtp_buffer_new_allocate (gst_rtp_vp8_calc_header_len (self), 0, 0);
  gst_rtp_buffer_map (out, GST_MAP_READWRITE, &rtpbuffer);
  p = gst_rtp_buffer_get_payload (&rtpbuffer);
  /* X=0,R=0,N=0,S=start,PartID=partid */
  p[0] = (start << 4) | partid;
  if (self->picture_id_mode != VP8_PAY_NO_PICTURE_ID) {
    /* Enable X=1 */
    p[0] |= 0x80;
    /* X: I=1,L=0,T=0,K=0,RSV=0 */
    p[1] = 0x80;
    if (self->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS) {
      /* I: 7 bit picture_id */
      p[2] = self->picture_id & 0x7F;
    } else {
      /* I: 15 bit picture_id */
      p[2] = 0x80 | ((self->picture_id & 0x7FFF) >> 8);
      p[3] = self->picture_id & 0xFF;
    }
  }

  gst_rtp_buffer_set_marker (&rtpbuffer, mark);

  gst_rtp_buffer_unmap (&rtpbuffer);

  GST_BUFFER_DURATION (out) = GST_BUFFER_DURATION (in);
  GST_BUFFER_PTS (out) = GST_BUFFER_PTS (in);

  return out;
}

static guint
gst_rtp_vp8_payload_next (GstRtpVP8Pay * self, GstBufferList * list,
    guint offset, GstBuffer * buffer, gsize buffer_size, gsize max_payload_len)
{
  guint partition;
  GstBuffer *header;
  GstBuffer *sub;
  GstBuffer *out;
  gboolean mark;
  gsize remaining;
  gsize available;

  remaining = buffer_size - offset;
  available = max_payload_len;
  if (available > remaining)
    available = remaining;

  partition = gst_rtp_vp8_offset_to_partition (self, offset);
  g_assert (partition < self->n_partitions);

  mark = (remaining == available);
  /* whole set of partitions, payload them and done */
  header = gst_rtp_vp8_create_header_buffer (self, partition,
      offset == self->partition_offset[partition], mark, buffer);
  sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, available);

  gst_rtp_copy_meta (GST_ELEMENT_CAST (self), header, buffer,
      g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
  out = gst_buffer_append (header, sub);

  gst_buffer_list_insert (list, -1, out);

  return available;
}


static GstFlowReturn
gst_rtp_vp8_pay_handle_buffer (GstRTPBasePayload * payload, GstBuffer * buffer)
{
  GstRtpVP8Pay *self = GST_RTP_VP8_PAY (payload);
  GstFlowReturn ret;
  GstBufferList *list;
  gsize size, max_paylen;
  guint offset, mtu, vp8_hdr_len;

  size = gst_buffer_get_size (buffer);

  if (G_UNLIKELY (!gst_rtp_vp8_pay_parse_frame (self, buffer, size))) {
    GST_ELEMENT_ERROR (self, STREAM, ENCODE, (NULL),
        ("Failed to parse VP8 frame"));
    return GST_FLOW_ERROR;
  }

  mtu = GST_RTP_BASE_PAYLOAD_MTU (payload);
  vp8_hdr_len = gst_rtp_vp8_calc_header_len (self);
  max_paylen = gst_rtp_buffer_calc_payload_len (mtu - vp8_hdr_len, 0, 0);

  list = gst_buffer_list_new_sized ((size / max_paylen) + 1);

  offset = 0;
  while (offset < size) {
    offset +=
        gst_rtp_vp8_payload_next (self, list, offset, buffer, size, max_paylen);
  }

  ret = gst_rtp_base_payload_push_list (payload, list);

  /* Incremenent and wrap the picture id if it overflows */
  if ((self->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS &&
          ++self->picture_id >= 0x80) ||
      (self->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS &&
          ++self->picture_id >= 0x8000))
    self->picture_id = 0;

  gst_buffer_unref (buffer);

  return ret;
}

static gboolean
gst_rtp_vp8_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
{
  GstRtpVP8Pay *self = GST_RTP_VP8_PAY (payload);

  if (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START) {
    if (self->picture_id_mode == VP8_PAY_PICTURE_ID_7BITS)
      self->picture_id = g_random_int_range (0, G_MAXUINT8) & 0x7F;
    else if (self->picture_id_mode == VP8_PAY_PICTURE_ID_15BITS)
      self->picture_id = g_random_int_range (0, G_MAXUINT16) & 0x7FFF;
  }

  return GST_RTP_BASE_PAYLOAD_CLASS (gst_rtp_vp8_pay_parent_class)->sink_event
      (payload, event);
}

static gboolean
gst_rtp_vp8_pay_set_caps (GstRTPBasePayload * payload, GstCaps * caps)
{
  GstCaps *src_caps;
  GstStructure *s;
  char *encoding_name;

  src_caps = gst_pad_get_allowed_caps (GST_RTP_BASE_PAYLOAD_SRCPAD (payload));
  if (src_caps) {
    src_caps = gst_caps_make_writable (src_caps);
    src_caps = gst_caps_truncate (src_caps);
    s = gst_caps_get_structure (src_caps, 0);
    gst_structure_fixate_field_string (s, "encoding-name", "VP8");
    encoding_name = g_strdup (gst_structure_get_string (s, "encoding-name"));
    gst_caps_unref (src_caps);
  } else {
    encoding_name = g_strdup ("VP8-DRAFT-IETF-01");
  }

  gst_rtp_base_payload_set_options (payload, "video", TRUE,
      encoding_name, 90000);
  g_free (encoding_name);
  return gst_rtp_base_payload_set_outcaps (payload, NULL);
}

gboolean
gst_rtp_vp8_pay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpvp8pay",
      GST_RANK_MARGINAL, GST_TYPE_RTP_VP8_PAY);
}
