/* GStreamer
 * Copyright (C) <2006> 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/rtp/gstrtpbuffer.h>
#include <gst/video/video.h>

#include "fnv1hash.h"
#include "gstrtptheorapay.h"
#include "gstrtputils.h"

#define THEORA_ID_LEN	42

GST_DEBUG_CATEGORY_STATIC (rtptheorapay_debug);
#define GST_CAT_DEFAULT (rtptheorapay_debug)

/* references:
 * http://svn.xiph.org/trunk/theora/doc/draft-ietf-avt-rtp-theora-01.txt
 */

static GstStaticPadTemplate gst_rtp_theora_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"video\", "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
        "clock-rate = (int) 90000, " "encoding-name = (string) \"THEORA\""
        /* All required parameters
         *
         * "sampling = (string) { "YCbCr-4:2:0", "YCbCr-4:2:2", "YCbCr-4:4:4" } "
         * "width = (string) [1, 1048561] (multiples of 16) "
         * "height = (string) [1, 1048561] (multiples of 16) "
         * "configuration = (string) ANY"
         */
        /* All optional parameters
         *
         * "configuration-uri ="
         * "delivery-method = (string) { inline, in_band, out_band/<specific_name> } "
         */
    )
    );

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

#define DEFAULT_CONFIG_INTERVAL 0

enum
{
  PROP_0,
  PROP_CONFIG_INTERVAL
};

#define gst_rtp_theora_pay_parent_class parent_class
G_DEFINE_TYPE (GstRtpTheoraPay, gst_rtp_theora_pay, GST_TYPE_RTP_BASE_PAYLOAD);

static gboolean gst_rtp_theora_pay_setcaps (GstRTPBasePayload * basepayload,
    GstCaps * caps);
static GstStateChangeReturn gst_rtp_theora_pay_change_state (GstElement *
    element, GstStateChange transition);
static GstFlowReturn gst_rtp_theora_pay_handle_buffer (GstRTPBasePayload * pad,
    GstBuffer * buffer);
static gboolean gst_rtp_theora_pay_sink_event (GstRTPBasePayload * payload,
    GstEvent * event);

static gboolean gst_rtp_theora_pay_parse_id (GstRTPBasePayload * basepayload,
    guint8 * data, guint size);
static gboolean gst_rtp_theora_pay_finish_headers (GstRTPBasePayload *
    basepayload);

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

static void
gst_rtp_theora_pay_class_init (GstRtpTheoraPayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBasePayloadClass *gstrtpbasepayload_class;

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

  gstelement_class->change_state = gst_rtp_theora_pay_change_state;

  gstrtpbasepayload_class->set_caps = gst_rtp_theora_pay_setcaps;
  gstrtpbasepayload_class->handle_buffer = gst_rtp_theora_pay_handle_buffer;
  gstrtpbasepayload_class->sink_event = gst_rtp_theora_pay_sink_event;

  gobject_class->set_property = gst_rtp_theora_pay_set_property;
  gobject_class->get_property = gst_rtp_theora_pay_get_property;

  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_theora_pay_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &gst_rtp_theora_pay_sink_template);

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP Theora payloader", "Codec/Payloader/Network/RTP",
      "Payload-encode Theora video into RTP packets (draft-01 RFC XXXX)",
      "Wim Taymans <wim.taymans@gmail.com>");

  GST_DEBUG_CATEGORY_INIT (rtptheorapay_debug, "rtptheorapay", 0,
      "Theora RTP Payloader");

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CONFIG_INTERVAL,
      g_param_spec_uint ("config-interval", "Config Send Interval",
          "Send Config Insertion Interval in seconds (configuration headers "
          "will be multiplexed in the data stream when detected.) (0 = disabled)",
          0, 3600, DEFAULT_CONFIG_INTERVAL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );
}

static void
gst_rtp_theora_pay_init (GstRtpTheoraPay * rtptheorapay)
{
  rtptheorapay->last_config = GST_CLOCK_TIME_NONE;
}

static void
gst_rtp_theora_pay_clear_packet (GstRtpTheoraPay * rtptheorapay)
{
  if (rtptheorapay->packet)
    gst_buffer_unref (rtptheorapay->packet);
  rtptheorapay->packet = NULL;
  g_list_free_full (rtptheorapay->packet_buffers,
      (GDestroyNotify) gst_buffer_unref);
  rtptheorapay->packet_buffers = NULL;
}

static void
gst_rtp_theora_pay_cleanup (GstRtpTheoraPay * rtptheorapay)
{
  gst_rtp_theora_pay_clear_packet (rtptheorapay);
  g_list_free_full (rtptheorapay->headers, (GDestroyNotify) gst_buffer_unref);
  rtptheorapay->headers = NULL;
  g_free (rtptheorapay->config_data);
  rtptheorapay->config_data = NULL;
  rtptheorapay->last_config = GST_CLOCK_TIME_NONE;
}

static gboolean
gst_rtp_theora_pay_setcaps (GstRTPBasePayload * basepayload, GstCaps * caps)
{
  GstRtpTheoraPay *rtptheorapay;
  GstStructure *s;
  const GValue *array;
  gint asize, i;
  GstBuffer *buf;
  GstMapInfo map;

  rtptheorapay = GST_RTP_THEORA_PAY (basepayload);

  s = gst_caps_get_structure (caps, 0);

  rtptheorapay->need_headers = TRUE;

  if ((array = gst_structure_get_value (s, "streamheader")) == NULL)
    goto done;

  if (G_VALUE_TYPE (array) != GST_TYPE_ARRAY)
    goto done;

  if ((asize = gst_value_array_get_size (array)) < 3)
    goto done;

  for (i = 0; i < asize; i++) {
    const GValue *value;

    value = gst_value_array_get_value (array, i);
    if ((buf = gst_value_get_buffer (value)) == NULL)
      goto null_buffer;

    gst_buffer_map (buf, &map, GST_MAP_READ);
    /* no data packets allowed */
    if (map.size < 1)
      goto invalid_streamheader;

    /* we need packets with id 0x80, 0x81, 0x82 */
    if (map.data[0] != 0x80 + i)
      goto invalid_streamheader;

    if (i == 0) {
      /* identification, we need to parse this in order to get the clock rate. */
      if (G_UNLIKELY (!gst_rtp_theora_pay_parse_id (basepayload, map.data,
                  map.size)))
        goto parse_id_failed;
    }
    GST_DEBUG_OBJECT (rtptheorapay, "collecting header %d", i);
    rtptheorapay->headers =
        g_list_append (rtptheorapay->headers, gst_buffer_ref (buf));
    gst_buffer_unmap (buf, &map);
  }
  if (!gst_rtp_theora_pay_finish_headers (basepayload))
    goto finish_failed;

done:
  return TRUE;

  /* ERRORS */
null_buffer:
  {
    GST_WARNING_OBJECT (rtptheorapay, "streamheader with null buffer received");
    return FALSE;
  }
invalid_streamheader:
  {
    GST_WARNING_OBJECT (rtptheorapay, "unable to parse initial header");
    gst_buffer_unmap (buf, &map);
    return FALSE;
  }
parse_id_failed:
  {
    GST_WARNING_OBJECT (rtptheorapay, "unable to parse initial header");
    gst_buffer_unmap (buf, &map);
    return FALSE;
  }
finish_failed:
  {
    GST_WARNING_OBJECT (rtptheorapay, "unable to finish headers");
    return FALSE;
  }
}

static void
gst_rtp_theora_pay_reset_packet (GstRtpTheoraPay * rtptheorapay, guint8 TDT)
{
  guint payload_len;
  GstRTPBuffer rtp = { NULL };

  GST_DEBUG_OBJECT (rtptheorapay, "reset packet");

  rtptheorapay->payload_pos = 4;
  gst_rtp_buffer_map (rtptheorapay->packet, GST_MAP_READ, &rtp);
  payload_len = gst_rtp_buffer_get_payload_len (&rtp);
  gst_rtp_buffer_unmap (&rtp);
  rtptheorapay->payload_left = payload_len - 4;
  rtptheorapay->payload_duration = 0;
  rtptheorapay->payload_F = 0;
  rtptheorapay->payload_TDT = TDT;
  rtptheorapay->payload_pkts = 0;
}

static void
gst_rtp_theora_pay_init_packet (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
    GstClockTime timestamp)
{
  GST_DEBUG_OBJECT (rtptheorapay, "starting new packet, TDT: %d", TDT);

  gst_rtp_theora_pay_clear_packet (rtptheorapay);

  /* new packet allocate max packet size */
  rtptheorapay->packet =
      gst_rtp_buffer_new_allocate_len (GST_RTP_BASE_PAYLOAD_MTU
      (rtptheorapay), 0, 0);
  gst_rtp_theora_pay_reset_packet (rtptheorapay, TDT);

  GST_BUFFER_PTS (rtptheorapay->packet) = timestamp;
}

static GstFlowReturn
gst_rtp_theora_pay_flush_packet (GstRtpTheoraPay * rtptheorapay)
{
  GstFlowReturn ret;
  guint8 *payload;
  guint hlen;
  GstRTPBuffer rtp = { NULL };
  GList *l;

  /* check for empty packet */
  if (!rtptheorapay->packet || rtptheorapay->payload_pos <= 4)
    return GST_FLOW_OK;

  GST_DEBUG_OBJECT (rtptheorapay, "flushing packet");

  gst_rtp_buffer_map (rtptheorapay->packet, GST_MAP_WRITE, &rtp);

  /* fix header */
  payload = gst_rtp_buffer_get_payload (&rtp);
  /*
   *  0                   1                   2                   3
   *  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
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                     Ident                     | F |TDT|# pkts.|
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   *
   * F: Fragment type (0=none, 1=start, 2=cont, 3=end)
   * TDT: Theora data type (0=theora, 1=config, 2=comment, 3=reserved)
   * pkts: number of packets.
   */
  payload[0] = (rtptheorapay->payload_ident >> 16) & 0xff;
  payload[1] = (rtptheorapay->payload_ident >> 8) & 0xff;
  payload[2] = (rtptheorapay->payload_ident) & 0xff;
  payload[3] = (rtptheorapay->payload_F & 0x3) << 6 |
      (rtptheorapay->payload_TDT & 0x3) << 4 |
      (rtptheorapay->payload_pkts & 0xf);

  gst_rtp_buffer_unmap (&rtp);

  /* shrink the buffer size to the last written byte */
  hlen = gst_rtp_buffer_calc_header_len (0);
  gst_buffer_resize (rtptheorapay->packet, 0, hlen + rtptheorapay->payload_pos);

  GST_BUFFER_DURATION (rtptheorapay->packet) = rtptheorapay->payload_duration;

  for (l = g_list_last (rtptheorapay->packet_buffers); l; l = l->prev) {
    GstBuffer *buf = GST_BUFFER_CAST (l->data);
    gst_rtp_copy_meta (GST_ELEMENT_CAST (rtptheorapay), rtptheorapay->packet,
        buf, g_quark_from_static_string (GST_META_TAG_VIDEO_STR));
    gst_buffer_unref (buf);
  }
  g_list_free (rtptheorapay->packet_buffers);
  rtptheorapay->packet_buffers = NULL;

  /* push, this gives away our ref to the packet, so clear it. */
  ret =
      gst_rtp_base_payload_push (GST_RTP_BASE_PAYLOAD (rtptheorapay),
      rtptheorapay->packet);
  rtptheorapay->packet = NULL;

  return ret;
}

static gboolean
gst_rtp_theora_pay_finish_headers (GstRTPBasePayload * basepayload)
{
  GstRtpTheoraPay *rtptheorapay = GST_RTP_THEORA_PAY (basepayload);
  GList *walk;
  guint length, size, n_headers, configlen, extralen;
  gchar *wstr, *hstr, *configuration;
  guint8 *data, *config;
  guint32 ident;
  gboolean res;
  const gchar *sampling = NULL;

  GST_DEBUG_OBJECT (rtptheorapay, "finish headers");

  if (!rtptheorapay->headers) {
    GST_DEBUG_OBJECT (rtptheorapay, "We need 2 headers but have none");
    goto no_headers;
  }

  /* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                     Number of packed headers                  |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                          Packed header                        |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                          Packed header                        |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                          ....                                 |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   *
   * We only construct a config containing 1 packed header like this:
   *
   *  0                   1                   2                   3
   *  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
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                   Ident                       | length       ..
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ..              | n. of headers |    length1    |    length2   ..
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ..              |             Identification Header            ..
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * .................................................................
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ..              |         Comment Header                       ..
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * .................................................................
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ..                        Comment Header                        |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |                          Setup Header                        ..
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * .................................................................
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * ..                         Setup Header                         |
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   */

  /* we need 4 bytes for the number of headers (which is always 1), 3 bytes for
   * the ident, 2 bytes for length, 1 byte for n. of headers. */
  size = 4 + 3 + 2 + 1;

  /* count the size of the headers first and update the hash */
  length = 0;
  n_headers = 0;
  ident = fnv1_hash_32_new ();
  extralen = 1;
  for (walk = rtptheorapay->headers; walk; walk = g_list_next (walk)) {
    GstBuffer *buf = GST_BUFFER_CAST (walk->data);
    GstMapInfo map;
    guint bsize;

    bsize = gst_buffer_get_size (buf);
    length += bsize;
    n_headers++;

    /* count number of bytes needed for length fields, we don't need this for
     * the last header. */
    if (g_list_next (walk)) {
      do {
        size++;
        extralen++;
        bsize >>= 7;
      } while (bsize);
    }
    /* update hash */
    gst_buffer_map (buf, &map, GST_MAP_READ);
    ident = fnv1_hash_32_update (ident, map.data, map.size);
    gst_buffer_unmap (buf, &map);
  }

  /* packet length is header size + packet length */
  configlen = size + length;
  config = data = g_malloc (configlen);

  /* number of packed headers, we only pack 1 header */
  data[0] = 0;
  data[1] = 0;
  data[2] = 0;
  data[3] = 1;

  ident = fnv1_hash_32_to_24 (ident);
  rtptheorapay->payload_ident = ident;
  GST_DEBUG_OBJECT (rtptheorapay, "ident 0x%08x", ident);

  /* take lower 3 bytes */
  data[4] = (ident >> 16) & 0xff;
  data[5] = (ident >> 8) & 0xff;
  data[6] = ident & 0xff;

  /* store length of all theora headers */
  data[7] = ((length) >> 8) & 0xff;
  data[8] = (length) & 0xff;

  /* store number of headers minus one. */
  data[9] = n_headers - 1;
  data += 10;

  /* store length for each header */
  for (walk = rtptheorapay->headers; walk; walk = g_list_next (walk)) {
    GstBuffer *buf = GST_BUFFER_CAST (walk->data);
    guint bsize, size, temp;
    guint flag;

    /* only need to store the length when it's not the last header */
    if (!g_list_next (walk))
      break;

    bsize = gst_buffer_get_size (buf);

    /* calc size */
    size = 0;
    do {
      size++;
      bsize >>= 7;
    } while (bsize);
    temp = size;

    bsize = gst_buffer_get_size (buf);
    /* write the size backwards */
    flag = 0;
    while (size) {
      size--;
      data[size] = (bsize & 0x7f) | flag;
      bsize >>= 7;
      flag = 0x80;              /* Flag bit on all bytes of the length except the last */
    }
    data += temp;
  }

  /* copy header data */
  for (walk = rtptheorapay->headers; walk; walk = g_list_next (walk)) {
    GstBuffer *buf = GST_BUFFER_CAST (walk->data);

    gst_buffer_extract (buf, 0, data, gst_buffer_get_size (buf));
    data += gst_buffer_get_size (buf);
  }
  rtptheorapay->need_headers = FALSE;

  /* serialize to base64 */
  configuration = g_base64_encode (config, configlen);

  /* store for later re-sending */
  g_free (rtptheorapay->config_data);
  rtptheorapay->config_size = configlen - 4 - 3 - 2;
  rtptheorapay->config_data = g_malloc (rtptheorapay->config_size);
  rtptheorapay->config_extra_len = extralen;
  memcpy (rtptheorapay->config_data, config + 4 + 3 + 2,
      rtptheorapay->config_size);

  g_free (config);

  /* configure payloader settings */
  switch (rtptheorapay->pixel_format) {
    case 2:
      sampling = "YCbCr-4:2:2";
      break;
    case 3:
      sampling = "YCbCr-4:4:4";
      break;
    case 0:
    default:
      sampling = "YCbCr-4:2:0";
      break;
  }


  wstr = g_strdup_printf ("%d", rtptheorapay->width);
  hstr = g_strdup_printf ("%d", rtptheorapay->height);
  gst_rtp_base_payload_set_options (basepayload, "video", TRUE, "THEORA",
      90000);
  res =
      gst_rtp_base_payload_set_outcaps (basepayload, "sampling", G_TYPE_STRING,
      sampling, "width", G_TYPE_STRING, wstr, "height", G_TYPE_STRING,
      hstr, "configuration", G_TYPE_STRING, configuration, "delivery-method",
      G_TYPE_STRING, "inline",
      /* don't set the other defaults 
       */
      NULL);
  g_free (wstr);
  g_free (hstr);
  g_free (configuration);

  return res;

  /* ERRORS */
no_headers:
  {
    GST_DEBUG_OBJECT (rtptheorapay, "finish headers");
    return FALSE;
  }
}

static gboolean
gst_rtp_theora_pay_parse_id (GstRTPBasePayload * basepayload, guint8 * data,
    guint size)
{
  GstRtpTheoraPay *rtptheorapay;
  gint width, height, pixel_format;

  rtptheorapay = GST_RTP_THEORA_PAY (basepayload);

  if (G_UNLIKELY (size < 42))
    goto too_short;

  if (G_UNLIKELY (memcmp (data, "\200theora", 7)))
    goto invalid_start;
  data += 7;

  if (G_UNLIKELY (data[0] != 3))
    goto invalid_version;
  if (G_UNLIKELY (data[1] != 2))
    goto invalid_version;
  data += 3;

  width = GST_READ_UINT16_BE (data) << 4;
  data += 2;
  height = GST_READ_UINT16_BE (data) << 4;
  data += 29;

  pixel_format = (GST_READ_UINT8 (data) >> 3) & 0x03;

  /* store values */
  rtptheorapay->pixel_format = pixel_format;
  rtptheorapay->width = width;
  rtptheorapay->height = height;

  return TRUE;

  /* ERRORS */
too_short:
  {
    GST_ELEMENT_ERROR (basepayload, STREAM, DECODE,
        (NULL),
        ("Identification packet is too short, need at least 42, got %d", size));
    return FALSE;
  }
invalid_start:
  {
    GST_ELEMENT_ERROR (basepayload, STREAM, DECODE,
        (NULL), ("Invalid header start in identification packet"));
    return FALSE;
  }
invalid_version:
  {
    GST_ELEMENT_ERROR (basepayload, STREAM, DECODE,
        (NULL), ("Invalid version"));
    return FALSE;
  }
}

static GstFlowReturn
gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
    GstBuffer * buffer, guint8 * data, guint size, GstClockTime timestamp,
    GstClockTime duration, guint not_in_length)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint newsize;
  guint packet_len;
  GstClockTime newduration;
  gboolean flush;
  guint plen;
  guint8 *ppos, *payload;
  gboolean fragmented;
  GstRTPBuffer rtp = { NULL };

  /* size increases with packet length and 2 bytes size eader. */
  newduration = rtptheorapay->payload_duration;
  if (duration != GST_CLOCK_TIME_NONE)
    newduration += duration;

  newsize = rtptheorapay->payload_pos + 2 + size;
  packet_len = gst_rtp_buffer_calc_packet_len (newsize, 0, 0);

  /* check buffer filled against length and max latency */
  flush = gst_rtp_base_payload_is_filled (GST_RTP_BASE_PAYLOAD (rtptheorapay),
      packet_len, newduration);
  /* we can store up to 15 theora packets in one RTP packet. */
  flush |= (rtptheorapay->payload_pkts == 15);
  /* flush if we have a new TDT */
  if (rtptheorapay->packet)
    flush |= (rtptheorapay->payload_TDT != TDT);
  if (flush)
    ret = gst_rtp_theora_pay_flush_packet (rtptheorapay);

  if (ret != GST_FLOW_OK)
    goto done;

  /* create new packet if we must */
  if (!rtptheorapay->packet) {
    gst_rtp_theora_pay_init_packet (rtptheorapay, TDT, timestamp);
  }

  gst_rtp_buffer_map (rtptheorapay->packet, GST_MAP_WRITE, &rtp);
  payload = gst_rtp_buffer_get_payload (&rtp);
  ppos = payload + rtptheorapay->payload_pos;
  fragmented = FALSE;

  /* put buffer in packet, it either fits completely or needs to be fragmented
   * over multiple RTP packets. */
  do {
    plen = MIN (rtptheorapay->payload_left - 2, size);

    GST_DEBUG_OBJECT (rtptheorapay, "append %u bytes", plen);

    /* data is copied in the payload with a 2 byte length header */
    ppos[0] = ((plen - not_in_length) >> 8) & 0xff;
    ppos[1] = ((plen - not_in_length) & 0xff);
    if (plen)
      memcpy (&ppos[2], data, plen);

    if (buffer) {
      if (!rtptheorapay->packet_buffers
          || rtptheorapay->packet_buffers->data != (gpointer) buffer)
        rtptheorapay->packet_buffers =
            g_list_prepend (rtptheorapay->packet_buffers,
            gst_buffer_ref (buffer));
    } else {
      GList *l;

      for (l = rtptheorapay->headers; l; l = l->next)
        rtptheorapay->packet_buffers =
            g_list_prepend (rtptheorapay->packet_buffers,
            gst_buffer_ref (l->data));
    }

    /* only first (only) configuration cuts length field */
    /* NOTE: spec (if any) is not clear on this ... */
    not_in_length = 0;

    size -= plen;
    data += plen;

    rtptheorapay->payload_pos += plen + 2;
    rtptheorapay->payload_left -= plen + 2;

    if (fragmented) {
      if (size == 0)
        /* last fragment, set F to 0x3. */
        rtptheorapay->payload_F = 0x3;
      else
        /* fragment continues, set F to 0x2. */
        rtptheorapay->payload_F = 0x2;
    } else {
      if (size > 0) {
        /* fragmented packet starts, set F to 0x1, mark ourselves as
         * fragmented. */
        rtptheorapay->payload_F = 0x1;
        fragmented = TRUE;
      }
    }
    if (fragmented) {
      gst_rtp_buffer_unmap (&rtp);
      /* fragmented packets are always flushed and have ptks of 0 */
      rtptheorapay->payload_pkts = 0;
      ret = gst_rtp_theora_pay_flush_packet (rtptheorapay);

      if (size > 0) {
        /* start new packet and get pointers. TDT stays the same. */
        gst_rtp_theora_pay_init_packet (rtptheorapay,
            rtptheorapay->payload_TDT, timestamp);
        gst_rtp_buffer_map (rtptheorapay->packet, GST_MAP_WRITE, &rtp);
        payload = gst_rtp_buffer_get_payload (&rtp);
        ppos = payload + rtptheorapay->payload_pos;
      }
    } else {
      /* unfragmented packet, update stats for next packet, size == 0 and we
       * exit the while loop */
      rtptheorapay->payload_pkts++;
      if (duration != GST_CLOCK_TIME_NONE)
        rtptheorapay->payload_duration += duration;
    }
  } while (size && ret == GST_FLOW_OK);

  if (rtp.buffer)
    gst_rtp_buffer_unmap (&rtp);
done:

  return ret;
}

static GstFlowReturn
gst_rtp_theora_pay_handle_buffer (GstRTPBasePayload * basepayload,
    GstBuffer * buffer)
{
  GstRtpTheoraPay *rtptheorapay;
  GstFlowReturn ret;
  GstMapInfo map;
  gsize size;
  guint8 *data;
  GstClockTime duration, timestamp;
  guint8 TDT;
  gboolean keyframe = FALSE;

  rtptheorapay = GST_RTP_THEORA_PAY (basepayload);

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  data = map.data;
  size = map.size;
  duration = GST_BUFFER_DURATION (buffer);
  timestamp = GST_BUFFER_PTS (buffer);

  GST_DEBUG_OBJECT (rtptheorapay, "size %" G_GSIZE_FORMAT
      ", duration %" GST_TIME_FORMAT, size, GST_TIME_ARGS (duration));

  /* find packet type */
  if (size == 0) {
    TDT = 0;
    keyframe = FALSE;
  } else if (data[0] & 0x80) {
    /* header */
    if (data[0] == 0x80) {
      /* identification, we need to parse this in order to get the clock rate.
       */
      if (G_UNLIKELY (!gst_rtp_theora_pay_parse_id (basepayload, data, size)))
        goto parse_id_failed;
      TDT = 1;
    } else if (data[0] == 0x81) {
      /* comment */
      TDT = 2;
    } else if (data[0] == 0x82) {
      /* setup */
      TDT = 1;
    } else
      goto unknown_header;
  } else {
    /* data */
    TDT = 0;
    keyframe = ((data[0] & 0x40) == 0);
  }

  /* we need to collect the headers and construct a config string from them */
  if (TDT != 0) {
    GST_DEBUG_OBJECT (rtptheorapay, "collecting header, buffer %p", buffer);
    /* append header to the list of headers */
    gst_buffer_unmap (buffer, &map);
    rtptheorapay->headers = g_list_append (rtptheorapay->headers, buffer);
    ret = GST_FLOW_OK;
    goto done;
  } else if (rtptheorapay->headers && rtptheorapay->need_headers) {
    if (!gst_rtp_theora_pay_finish_headers (basepayload))
      goto header_error;
  }

  /* there is a config request, see if we need to insert it */
  if (keyframe && (rtptheorapay->config_interval > 0) &&
      rtptheorapay->config_data) {
    gboolean send_config = FALSE;

    if (rtptheorapay->last_config != -1) {
      guint64 diff;

      GST_LOG_OBJECT (rtptheorapay,
          "now %" GST_TIME_FORMAT ", last VOP-I %" GST_TIME_FORMAT,
          GST_TIME_ARGS (timestamp), GST_TIME_ARGS (rtptheorapay->last_config));

      /* calculate diff between last config in milliseconds */
      if (timestamp > rtptheorapay->last_config) {
        diff = timestamp - rtptheorapay->last_config;
      } else {
        diff = 0;
      }

      GST_DEBUG_OBJECT (rtptheorapay,
          "interval since last config %" GST_TIME_FORMAT, GST_TIME_ARGS (diff));

      /* bigger than interval, queue config */
      /* FIXME should convert timestamps to running time */
      if (GST_TIME_AS_SECONDS (diff) >= rtptheorapay->config_interval) {
        GST_DEBUG_OBJECT (rtptheorapay, "time to send config");
        send_config = TRUE;
      }
    } else {
      /* no known previous config time, send now */
      GST_DEBUG_OBJECT (rtptheorapay, "no previous config time, send now");
      send_config = TRUE;
    }

    if (send_config) {
      /* we need to send config now first */
      /* different TDT type forces flush */
      gst_rtp_theora_pay_payload_buffer (rtptheorapay, 1,
          NULL, rtptheorapay->config_data, rtptheorapay->config_size,
          timestamp, GST_CLOCK_TIME_NONE, rtptheorapay->config_extra_len);

      if (timestamp != -1) {
        rtptheorapay->last_config = timestamp;
      }
    }
  }

  ret =
      gst_rtp_theora_pay_payload_buffer (rtptheorapay, TDT, buffer, data, size,
      timestamp, duration, 0);

  gst_buffer_unmap (buffer, &map);
  gst_buffer_unref (buffer);

done:
  return ret;

  /* ERRORS */
parse_id_failed:
  {
    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }
unknown_header:
  {
    GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
        (NULL), ("Ignoring unknown header received"));
    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
header_error:
  {
    GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
        (NULL), ("Error initializing header config"));
    gst_buffer_unmap (buffer, &map);
    gst_buffer_unref (buffer);
    return GST_FLOW_OK;
  }
}

static gboolean
gst_rtp_theora_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
{
  GstRtpTheoraPay *rtptheorapay = GST_RTP_THEORA_PAY (payload);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_rtp_theora_pay_clear_packet (rtptheorapay);
      break;
    default:
      break;
  }
  /* false to let parent handle event as well */
  return GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload, event);
}

static GstStateChangeReturn
gst_rtp_theora_pay_change_state (GstElement * element,
    GstStateChange transition)
{
  GstRtpTheoraPay *rtptheorapay;

  GstStateChangeReturn ret;

  rtptheorapay = GST_RTP_THEORA_PAY (element);

  switch (transition) {
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_rtp_theora_pay_cleanup (rtptheorapay);
      break;
    default:
      break;
  }
  return ret;
}

static void
gst_rtp_theora_pay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpTheoraPay *rtptheorapay;

  rtptheorapay = GST_RTP_THEORA_PAY (object);

  switch (prop_id) {
    case PROP_CONFIG_INTERVAL:
      rtptheorapay->config_interval = g_value_get_uint (value);
      break;
    default:
      break;
  }
}

static void
gst_rtp_theora_pay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpTheoraPay *rtptheorapay;

  rtptheorapay = GST_RTP_THEORA_PAY (object);

  switch (prop_id) {
    case PROP_CONFIG_INTERVAL:
      g_value_set_uint (value, rtptheorapay->config_interval);
      break;
    default:
      break;
  }
}

gboolean
gst_rtp_theora_pay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtptheorapay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_THEORA_PAY);
}
