/* GStreamer
 * Copyright (C) <2005> Philippe Khalaf <burger@speedy.org>
 * Copyright (C) <2006> Wim Taymans <wim@fluendo.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.
 */

/**
 * SECTION:gstrtpbuffer
 * @title: GstRTPBuffer
 * @short_description: Helper methods for dealing with RTP buffers
 * @see_also: #GstRTPBasePayload, #GstRTPBaseDepayload, gstrtcpbuffer
 *
 * The GstRTPBuffer helper functions makes it easy to parse and create regular
 * #GstBuffer objects that contain RTP payloads. These buffers are typically of
 * 'application/x-rtp' #GstCaps.
 *
 */

#include "gstrtpbuffer.h"

#include <stdlib.h>
#include <string.h>

#define GST_RTP_HEADER_LEN 12

/* Note: we use bitfields here to make sure the compiler doesn't add padding
 * between fields on certain architectures; can't assume aligned access either
 */
typedef struct _GstRTPHeader
{
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
  unsigned int csrc_count:4;    /* CSRC count */
  unsigned int extension:1;     /* header extension flag */
  unsigned int padding:1;       /* padding flag */
  unsigned int version:2;       /* protocol version */
  unsigned int payload_type:7;  /* payload type */
  unsigned int marker:1;        /* marker bit */
#elif G_BYTE_ORDER == G_BIG_ENDIAN
  unsigned int version:2;       /* protocol version */
  unsigned int padding:1;       /* padding flag */
  unsigned int extension:1;     /* header extension flag */
  unsigned int csrc_count:4;    /* CSRC count */
  unsigned int marker:1;        /* marker bit */
  unsigned int payload_type:7;  /* payload type */
#else
#error "G_BYTE_ORDER should be big or little endian."
#endif
  unsigned int seq:16;          /* sequence number */
  unsigned int timestamp:32;    /* timestamp */
  unsigned int ssrc:32;         /* synchronization source */
  guint8 csrclist[4];           /* optional CSRC list, 32 bits each */
} GstRTPHeader;

#define GST_RTP_HEADER_VERSION(data)      (((GstRTPHeader *)(data))->version)
#define GST_RTP_HEADER_PADDING(data)      (((GstRTPHeader *)(data))->padding)
#define GST_RTP_HEADER_EXTENSION(data)    (((GstRTPHeader *)(data))->extension)
#define GST_RTP_HEADER_CSRC_COUNT(data)   (((GstRTPHeader *)(data))->csrc_count)
#define GST_RTP_HEADER_MARKER(data)       (((GstRTPHeader *)(data))->marker)
#define GST_RTP_HEADER_PAYLOAD_TYPE(data) (((GstRTPHeader *)(data))->payload_type)
#define GST_RTP_HEADER_SEQ(data)          (((GstRTPHeader *)(data))->seq)
#define GST_RTP_HEADER_TIMESTAMP(data)    (((GstRTPHeader *)(data))->timestamp)
#define GST_RTP_HEADER_SSRC(data)         (((GstRTPHeader *)(data))->ssrc)
#define GST_RTP_HEADER_CSRC_LIST_OFFSET(data,i)        \
    data + G_STRUCT_OFFSET(GstRTPHeader, csrclist) +   \
    ((i) * sizeof(guint32))
#define GST_RTP_HEADER_CSRC_SIZE(data)   (GST_RTP_HEADER_CSRC_COUNT(data) * sizeof (guint32))

/**
 * gst_rtp_buffer_allocate_data:
 * @buffer: a #GstBuffer
 * @payload_len: the length of the payload
 * @pad_len: the amount of padding
 * @csrc_count: the number of CSRC entries
 *
 * Allocate enough data in @buffer to hold an RTP packet with @csrc_count CSRCs,
 * a payload length of @payload_len and padding of @pad_len.
 * @buffer must be writable and all previous memory in @buffer will be freed.
 * If @pad_len is >0, the padding bit will be set. All other RTP header fields
 * will be set to 0/FALSE.
 */
void
gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
    guint8 pad_len, guint8 csrc_count)
{
  GstMapInfo map;
  GstMemory *mem;
  gsize hlen;

  g_return_if_fail (csrc_count <= 15);
  g_return_if_fail (GST_IS_BUFFER (buffer));
  g_return_if_fail (gst_buffer_is_writable (buffer));

  gst_buffer_remove_all_memory (buffer);

  hlen = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32);

  mem = gst_allocator_alloc (NULL, hlen, NULL);

  gst_memory_map (mem, &map, GST_MAP_WRITE);
  /* fill in defaults */
  GST_RTP_HEADER_VERSION (map.data) = GST_RTP_VERSION;
  if (pad_len)
    GST_RTP_HEADER_PADDING (map.data) = TRUE;
  else
    GST_RTP_HEADER_PADDING (map.data) = FALSE;
  GST_RTP_HEADER_EXTENSION (map.data) = FALSE;
  GST_RTP_HEADER_CSRC_COUNT (map.data) = csrc_count;
  memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (map.data, 0), 0,
      csrc_count * sizeof (guint32));
  GST_RTP_HEADER_MARKER (map.data) = FALSE;
  GST_RTP_HEADER_PAYLOAD_TYPE (map.data) = 0;
  GST_RTP_HEADER_SEQ (map.data) = 0;
  GST_RTP_HEADER_TIMESTAMP (map.data) = 0;
  GST_RTP_HEADER_SSRC (map.data) = 0;
  gst_memory_unmap (mem, &map);

  gst_buffer_append_memory (buffer, mem);

  if (payload_len) {
    mem = gst_allocator_alloc (NULL, payload_len, NULL);
    gst_buffer_append_memory (buffer, mem);
  }
  if (pad_len) {
    mem = gst_allocator_alloc (NULL, pad_len, NULL);

    gst_memory_map (mem, &map, GST_MAP_WRITE);
    map.data[pad_len - 1] = pad_len;
    gst_memory_unmap (mem, &map);

    gst_buffer_append_memory (buffer, mem);
  }
}

/**
 * gst_rtp_buffer_new_take_data:
 * @data: (array length=len) (transfer full) (element-type guint8):
 *   data for the new buffer
 * @len: the length of data
 *
 * Create a new buffer and set the data and size of the buffer to @data and @len
 * respectively. @data will be freed when the buffer is unreffed, so this
 * function transfers ownership of @data to the new buffer.
 *
 * Returns: A newly allocated buffer with @data and of size @len.
 */
GstBuffer *
gst_rtp_buffer_new_take_data (gpointer data, gsize len)
{
  g_return_val_if_fail (data != NULL, NULL);
  g_return_val_if_fail (len > 0, NULL);

  return gst_buffer_new_wrapped (data, len);
}

/**
 * gst_rtp_buffer_new_copy_data:
 * @data: (array length=len) (element-type guint8): data for the new
 *   buffer
 * @len: the length of data
 *
 * Create a new buffer and set the data to a copy of @len
 * bytes of @data and the size to @len. The data will be freed when the buffer
 * is freed.
 *
 * Returns: A newly allocated buffer with a copy of @data and of size @len.
 */
GstBuffer *
gst_rtp_buffer_new_copy_data (gpointer data, gsize len)
{
  return gst_rtp_buffer_new_take_data (g_memdup (data, len), len);
}

/**
 * gst_rtp_buffer_new_allocate:
 * @payload_len: the length of the payload
 * @pad_len: the amount of padding
 * @csrc_count: the number of CSRC entries
 *
 * Allocate a new #GstBuffer with enough data to hold an RTP packet with
 * @csrc_count CSRCs, a payload length of @payload_len and padding of @pad_len.
 * All other RTP header fields will be set to 0/FALSE.
 *
 * Returns: A newly allocated buffer that can hold an RTP packet with given
 * parameters.
 */
GstBuffer *
gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len,
    guint8 csrc_count)
{
  GstBuffer *result;

  g_return_val_if_fail (csrc_count <= 15, NULL);

  result = gst_buffer_new ();
  gst_rtp_buffer_allocate_data (result, payload_len, pad_len, csrc_count);

  return result;
}

/**
 * gst_rtp_buffer_new_allocate_len:
 * @packet_len: the total length of the packet
 * @pad_len: the amount of padding
 * @csrc_count: the number of CSRC entries
 *
 * Create a new #GstBuffer that can hold an RTP packet that is exactly
 * @packet_len long. The length of the payload depends on @pad_len and
 * @csrc_count and can be calculated with gst_rtp_buffer_calc_payload_len().
 * All RTP header fields will be set to 0/FALSE.
 *
 * Returns: A newly allocated buffer that can hold an RTP packet of @packet_len.
 */
GstBuffer *
gst_rtp_buffer_new_allocate_len (guint packet_len, guint8 pad_len,
    guint8 csrc_count)
{
  guint len;

  g_return_val_if_fail (csrc_count <= 15, NULL);

  len = gst_rtp_buffer_calc_payload_len (packet_len, pad_len, csrc_count);

  return gst_rtp_buffer_new_allocate (len, pad_len, csrc_count);
}

/**
 * gst_rtp_buffer_calc_header_len:
 * @csrc_count: the number of CSRC entries
 *
 * Calculate the header length of an RTP packet with @csrc_count CSRC entries.
 * An RTP packet can have at most 15 CSRC entries.
 *
 * Returns: The length of an RTP header with @csrc_count CSRC entries.
 */
guint
gst_rtp_buffer_calc_header_len (guint8 csrc_count)
{
  g_return_val_if_fail (csrc_count <= 15, 0);

  return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32));
}

/**
 * gst_rtp_buffer_calc_packet_len:
 * @payload_len: the length of the payload
 * @pad_len: the amount of padding
 * @csrc_count: the number of CSRC entries
 *
 * Calculate the total length of an RTP packet with a payload size of @payload_len,
 * a padding of @pad_len and a @csrc_count CSRC entries.
 *
 * Returns: The total length of an RTP header with given parameters.
 */
guint
gst_rtp_buffer_calc_packet_len (guint payload_len, guint8 pad_len,
    guint8 csrc_count)
{
  g_return_val_if_fail (csrc_count <= 15, 0);

  return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32))
      + pad_len;
}

/**
 * gst_rtp_buffer_calc_payload_len:
 * @packet_len: the length of the total RTP packet
 * @pad_len: the amount of padding
 * @csrc_count: the number of CSRC entries
 *
 * Calculate the length of the payload of an RTP packet with size @packet_len,
 * a padding of @pad_len and a @csrc_count CSRC entries.
 *
 * Returns: The length of the payload of an RTP packet  with given parameters.
 */
guint
gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len,
    guint8 csrc_count)
{
  g_return_val_if_fail (csrc_count <= 15, 0);

  if (packet_len <
      GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32)) + pad_len)
    return 0;

  return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
      - pad_len;
}

/**
 * gst_rtp_buffer_map:
 * @buffer: a #GstBuffer
 * @flags: #GstMapFlags
 * @rtp: (out): a #GstRTPBuffer
 *
 * Map the contents of @buffer into @rtp.
 *
 * Returns: %TRUE if @buffer could be mapped.
 */
gboolean
gst_rtp_buffer_map (GstBuffer * buffer, GstMapFlags flags, GstRTPBuffer * rtp)
{
  guint8 padding;
  guint8 csrc_count;
  guint header_len;
  guint8 version, pt;
  guint8 *data;
  guint size;
  gsize bufsize, skip;
  guint idx, length;
  guint n_mem;

  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
  g_return_val_if_fail (rtp != NULL, FALSE);
  g_return_val_if_fail (rtp->buffer == NULL, FALSE);

  n_mem = gst_buffer_n_memory (buffer);
  if (n_mem < 1)
    goto no_memory;

  /* map first memory, this should be the header */
  if (!gst_buffer_map_range (buffer, 0, 1, &rtp->map[0], flags))
    goto map_failed;

  data = rtp->data[0] = rtp->map[0].data;
  size = rtp->map[0].size;

  /* the header must be completely in the first buffer */
  header_len = GST_RTP_HEADER_LEN;
  if (G_UNLIKELY (size < header_len))
    goto wrong_length;

  /* check version */
  version = (data[0] & 0xc0);
  if (G_UNLIKELY (version != (GST_RTP_VERSION << 6)))
    goto wrong_version;

  /* check reserved PT and marker bit, this is to check for RTCP
   * packets. We do a relaxed check, you can still use 72-76 as long
   * as the marker bit is cleared. */
  pt = data[1];
  if (G_UNLIKELY (pt >= 200 && pt <= 204))
    goto reserved_pt;

  /* calc header length with csrc */
  csrc_count = (data[0] & 0x0f);
  header_len += csrc_count * sizeof (guint32);

  rtp->size[0] = header_len;

  bufsize = gst_buffer_get_size (buffer);

  /* calc extension length when present. */
  if (data[0] & 0x10) {
    guint8 *extdata;
    guint16 extlen;

    /* find memory for the extension bits, we find the block for the first 4
     * bytes, all other extension bytes should also be in this block */
    if (!gst_buffer_find_memory (buffer, header_len, 4, &idx, &length, &skip))
      goto wrong_length;

    if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[1], flags))
      goto map_failed;

    extdata = rtp->data[1] = rtp->map[1].data + skip;
    /* skip id */
    extdata += 2;
    /* read length as the number of 32 bits words */
    extlen = GST_READ_UINT16_BE (extdata);
    extlen *= sizeof (guint32);
    /* add id and length */
    extlen += 4;

    /* all extension bytes must be in this block */
    if (G_UNLIKELY (rtp->map[1].size < extlen))
      goto wrong_length;

    rtp->size[1] = extlen;

    header_len += rtp->size[1];
  } else {
    rtp->data[1] = NULL;
    rtp->size[1] = 0;
  }

  /* check for padding unless flags says to skip */
  if ((data[0] & 0x20) != 0 &&
      (flags & GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING) == 0) {
    /* find memory for the padding bits */
    if (!gst_buffer_find_memory (buffer, bufsize - 1, 1, &idx, &length, &skip))
      goto wrong_length;

    if (!gst_buffer_map_range (buffer, idx, length, &rtp->map[3], flags))
      goto map_failed;

    padding = rtp->map[3].data[skip];
    rtp->data[3] = rtp->map[3].data + skip + 1 - padding;
    rtp->size[3] = padding;

    if (skip + 1 < padding)
      goto wrong_length;
  } else {
    rtp->data[3] = NULL;
    rtp->size[3] = 0;
    padding = 0;
  }

  /* check if padding and header not bigger than packet length */
  if (G_UNLIKELY (bufsize < padding + header_len))
    goto wrong_padding;

  rtp->buffer = buffer;

  if (n_mem == 1) {
    /* we have mapped the buffer already, so might just as well fill in the
     * payload pointer and size and avoid another buffer map/unmap later */
    rtp->data[2] = rtp->map[0].data + header_len;
    rtp->size[2] = bufsize - header_len - padding;
  } else {
    /* we have not yet mapped the payload */
    rtp->data[2] = NULL;
    rtp->size[2] = 0;
  }

  /* rtp->state = 0; *//* unused */

  return TRUE;

  /* ERRORS */
no_memory:
  {
    GST_ERROR ("buffer without memory");
    return FALSE;
  }
map_failed:
  {
    GST_ERROR ("failed to map memory");
    return FALSE;
  }
wrong_length:
  {
    GST_DEBUG ("length check failed");
    goto dump_packet;
  }
wrong_version:
  {
    GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION);
    goto dump_packet;
  }
reserved_pt:
  {
    GST_DEBUG ("reserved PT %d found", pt);
    goto dump_packet;
  }
wrong_padding:
  {
    GST_DEBUG ("padding check failed (%" G_GSIZE_FORMAT " - %d < %d)", bufsize,
        header_len, padding);
    goto dump_packet;
  }
dump_packet:
  {
    gint i;

    GST_MEMDUMP ("buffer", data, size);

    for (i = 0; i < G_N_ELEMENTS (rtp->map); ++i) {
      if (rtp->map[i].memory != NULL)
        gst_buffer_unmap (buffer, &rtp->map[i]);
    }
    return FALSE;
  }
}

/**
 * gst_rtp_buffer_unmap:
 * @rtp: a #GstRTPBuffer
 *
 * Unmap @rtp previously mapped with gst_rtp_buffer_map().
 */
void
gst_rtp_buffer_unmap (GstRTPBuffer * rtp)
{
  gint i;

  g_return_if_fail (rtp != NULL);
  g_return_if_fail (rtp->buffer != NULL);

  for (i = 0; i < 4; i++) {
    if (rtp->map[i].memory != NULL) {
      gst_buffer_unmap (rtp->buffer, &rtp->map[i]);
      rtp->map[i].memory = NULL;
    }
    rtp->data[i] = NULL;
    rtp->size[i] = 0;
  }
  rtp->buffer = NULL;
}


/**
 * gst_rtp_buffer_set_packet_len:
 * @rtp: the RTP packet
 * @len: the new packet length
 *
 * Set the total @rtp size to @len. The data in the buffer will be made
 * larger if needed. Any padding will be removed from the packet.
 */
void
gst_rtp_buffer_set_packet_len (GstRTPBuffer * rtp, guint len)
{
  guint8 *data;

  data = rtp->data[0];

  /* FIXME */

  if (rtp->map[0].maxsize <= len) {
    /* FIXME, realloc bigger space */
    g_warning ("not implemented");
  }

  gst_buffer_set_size (rtp->buffer, len);
  rtp->map[0].size = len;

  /* remove any padding */
  GST_RTP_HEADER_PADDING (data) = FALSE;
}

/**
 * gst_rtp_buffer_get_packet_len:
 * @rtp: the RTP packet
 *
 * Return the total length of the packet in @buffer.
 *
 * Returns: The total length of the packet in @buffer.
 */
guint
gst_rtp_buffer_get_packet_len (GstRTPBuffer * rtp)
{
  return gst_buffer_get_size (rtp->buffer);
}

/**
 * gst_rtp_buffer_get_header_len:
 * @rtp: the RTP packet
 *
 * Return the total length of the header in @buffer. This include the length of
 * the fixed header, the CSRC list and the extension header.
 *
 * Returns: The total length of the header in @buffer.
 */
guint
gst_rtp_buffer_get_header_len (GstRTPBuffer * rtp)
{
  return rtp->size[0] + rtp->size[1];
}

/**
 * gst_rtp_buffer_get_version:
 * @rtp: the RTP packet
 *
 * Get the version number of the RTP packet in @buffer.
 *
 * Returns: The version of @buffer.
 */
guint8
gst_rtp_buffer_get_version (GstRTPBuffer * rtp)
{
  return GST_RTP_HEADER_VERSION (rtp->data[0]);
}

/**
 * gst_rtp_buffer_set_version:
 * @rtp: the RTP packet
 * @version: the new version
 *
 * Set the version of the RTP packet in @buffer to @version.
 */
void
gst_rtp_buffer_set_version (GstRTPBuffer * rtp, guint8 version)
{
  g_return_if_fail (version < 0x04);

  GST_RTP_HEADER_VERSION (rtp->data[0]) = version;
}

/**
 * gst_rtp_buffer_get_padding:
 * @rtp: the RTP packet
 *
 * Check if the padding bit is set on the RTP packet in @buffer.
 *
 * Returns: TRUE if @buffer has the padding bit set.
 */
gboolean
gst_rtp_buffer_get_padding (GstRTPBuffer * rtp)
{
  return GST_RTP_HEADER_PADDING (rtp->data[0]);
}

/**
 * gst_rtp_buffer_set_padding:
 * @rtp: the buffer
 * @padding: the new padding
 *
 * Set the padding bit on the RTP packet in @buffer to @padding.
 */
void
gst_rtp_buffer_set_padding (GstRTPBuffer * rtp, gboolean padding)
{
  GST_RTP_HEADER_PADDING (rtp->data[0]) = padding;
}

/**
 * gst_rtp_buffer_pad_to:
 * @rtp: the RTP packet
 * @len: the new amount of padding
 *
 * Set the amount of padding in the RTP packet in @buffer to
 * @len. If @len is 0, the padding is removed.
 *
 * NOTE: This function does not work correctly.
 */
void
gst_rtp_buffer_pad_to (GstRTPBuffer * rtp, guint len)
{
  guint8 *data;

  data = rtp->data[0];

  if (len > 0)
    GST_RTP_HEADER_PADDING (data) = TRUE;
  else
    GST_RTP_HEADER_PADDING (data) = FALSE;

  /* FIXME, set the padding byte at the end of the payload data */
}

/**
 * gst_rtp_buffer_get_extension:
 * @rtp: the RTP packet
 *
 * Check if the extension bit is set on the RTP packet in @buffer.
 *
 * Returns: TRUE if @buffer has the extension bit set.
 */
gboolean
gst_rtp_buffer_get_extension (GstRTPBuffer * rtp)
{
  return GST_RTP_HEADER_EXTENSION (rtp->data[0]);
}

/**
 * gst_rtp_buffer_set_extension:
 * @rtp: the RTP packet
 * @extension: the new extension
 *
 * Set the extension bit on the RTP packet in @buffer to @extension.
 */
void
gst_rtp_buffer_set_extension (GstRTPBuffer * rtp, gboolean extension)
{
  GST_RTP_HEADER_EXTENSION (rtp->data[0]) = extension;
}

/**
 * gst_rtp_buffer_get_extension_data: (skip)
 * @rtp: the RTP packet
 * @bits: (out): location for result bits
 * @data: (out) (array) (element-type guint8) (transfer none): location for data
 * @wordlen: (out): location for length of @data in 32 bits words
 *
 * Get the extension data. @bits will contain the extension 16 bits of custom
 * data. @data will point to the data in the extension and @wordlen will contain
 * the length of @data in 32 bits words.
 *
 * If @buffer did not contain an extension, this function will return %FALSE
 * with @bits, @data and @wordlen unchanged.
 *
 * Returns: TRUE if @buffer had the extension bit set.
 */
gboolean
gst_rtp_buffer_get_extension_data (GstRTPBuffer * rtp, guint16 * bits,
    gpointer * data, guint * wordlen)
{
  guint8 *pdata;

  /* move to the extension */
  pdata = rtp->data[1];
  if (!pdata)
    return FALSE;

  if (bits)
    *bits = GST_READ_UINT16_BE (pdata);
  if (wordlen)
    *wordlen = GST_READ_UINT16_BE (pdata + 2);
  pdata += 4;
  if (data)
    *data = (gpointer *) pdata;

  return TRUE;
}

/**
 * gst_rtp_buffer_get_extension_bytes: (rename-to gst_rtp_buffer_get_extension_data)
 * @rtp: the RTP packet
 * @bits: (out): location for header bits
 *
 * Similar to gst_rtp_buffer_get_extension_data, but more suitable for language
 * bindings usage. @bits will contain the extension 16 bits of custom data and
 * the extension data (not including the extension header) is placed in a new
 * #GBytes structure.
 *
 * If @rtp did not contain an extension, this function will return %NULL, with
 * @bits unchanged. If there is an extension header but no extension data then
 * an empty #GBytes will be returned.
 *
 * Returns: (transfer full): A new #GBytes if an extension header was present
 * and %NULL otherwise.
 *
 * Since: 1.2
 */
GBytes *
gst_rtp_buffer_get_extension_bytes (GstRTPBuffer * rtp, guint16 * bits)
{
  gpointer buf_data = NULL;
  guint buf_len;

  g_return_val_if_fail (rtp != NULL, FALSE);

  if (!gst_rtp_buffer_get_extension_data (rtp, bits, &buf_data, &buf_len))
    return NULL;

  if (buf_len == 0) {
    /* if no extension data is present return an empty GBytes */
    buf_data = NULL;
  }

  /* multiply length with 4 to get length in bytes */
  return g_bytes_new (buf_data, 4 * buf_len);
}

static gboolean
gst_rtp_buffer_map_payload (GstRTPBuffer * rtp)
{
  guint hlen, plen;
  guint idx, length;
  gsize skip;

  if (rtp->map[2].memory != NULL)
    return TRUE;

  hlen = gst_rtp_buffer_get_header_len (rtp);
  plen = gst_buffer_get_size (rtp->buffer) - hlen - rtp->size[3];

  if (!gst_buffer_find_memory (rtp->buffer, hlen, plen, &idx, &length, &skip))
    return FALSE;

  if (!gst_buffer_map_range (rtp->buffer, idx, length, &rtp->map[2],
          rtp->map[0].flags))
    return FALSE;

  rtp->data[2] = rtp->map[2].data + skip;
  rtp->size[2] = plen;

  return TRUE;
}

/* ensure header, payload and padding are in separate buffers */
static void
ensure_buffers (GstRTPBuffer * rtp)
{
  guint i, pos;
  gboolean changed = FALSE;

  /* make sure payload is mapped */
  gst_rtp_buffer_map_payload (rtp);

  for (i = 0, pos = 0; i < 4; i++) {
    if (rtp->size[i]) {
      gsize offset = (guint8 *) rtp->data[i] - rtp->map[i].data;

      if (offset != 0 || rtp->map[i].size != rtp->size[i]) {
        GstMemory *mem;

        /* make copy */
        mem = gst_memory_copy (rtp->map[i].memory, offset, rtp->size[i]);

        /* insert new memory */
        gst_buffer_insert_memory (rtp->buffer, pos, mem);

        changed = TRUE;
      }
      pos++;
    }
  }

  if (changed) {
    GstBuffer *buf = rtp->buffer;

    gst_rtp_buffer_unmap (rtp);
    gst_buffer_remove_memory_range (buf, pos, -1);
    gst_rtp_buffer_map (buf, GST_MAP_READWRITE, rtp);
  }
}

/**
 * gst_rtp_buffer_set_extension_data:
 * @rtp: the RTP packet
 * @bits: the bits specific for the extension
 * @length: the length that counts the number of 32-bit words in
 * the extension, excluding the extension header ( therefore zero is a valid length)
 *
 * Set the extension bit of the rtp buffer and fill in the @bits and @length of the
 * extension header. If the existing extension data is not large enough, it will
 * be made larger.
 *
 * Returns: True if done.
 */
gboolean
gst_rtp_buffer_set_extension_data (GstRTPBuffer * rtp, guint16 bits,
    guint16 length)
{
  guint32 min_size = 0;
  guint8 *data;
  GstMemory *mem = NULL;

  ensure_buffers (rtp);

  /* this is the size of the extension data we need */
  min_size = 4 + length * sizeof (guint32);

  /* we should allocate and map the extension data */
  if (rtp->data[1] == NULL || min_size > rtp->size[1]) {
    GstMapInfo map;

    /* we don't have (enough) extension data, make some */
    mem = gst_allocator_alloc (NULL, min_size, NULL);

    if (rtp->data[1]) {
      /* copy old data */
      gst_memory_map (mem, &map, GST_MAP_WRITE);
      memcpy (map.data, rtp->data[1], rtp->size[1]);
      gst_memory_unmap (mem, &map);

      /* unmap old */
      gst_buffer_unmap (rtp->buffer, &rtp->map[1]);
      gst_buffer_replace_memory (rtp->buffer, 1, mem);
    } else {
      /* we didn't have extension data, add */
      gst_buffer_insert_memory (rtp->buffer, 1, mem);
    }

    /* map new */
    gst_memory_map (mem, &rtp->map[1], GST_MAP_READWRITE);
    gst_memory_ref (mem);
    rtp->data[1] = rtp->map[1].data;
    rtp->size[1] = rtp->map[1].size;
  }

  /* now we can set the extension bit */
  data = rtp->data[0];
  GST_RTP_HEADER_EXTENSION (data) = TRUE;

  data = rtp->data[1];
  GST_WRITE_UINT16_BE (data, bits);
  GST_WRITE_UINT16_BE (data + 2, length);

  return TRUE;
}

/**
 * gst_rtp_buffer_get_ssrc:
 * @rtp: the RTP packet
 *
 * Get the SSRC of the RTP packet in @buffer.
 *
 * Returns: the SSRC of @buffer in host order.
 */
guint32
gst_rtp_buffer_get_ssrc (GstRTPBuffer * rtp)
{
  return g_ntohl (GST_RTP_HEADER_SSRC (rtp->data[0]));
}

/**
 * gst_rtp_buffer_set_ssrc:
 * @rtp: the RTP packet
 * @ssrc: the new SSRC
 *
 * Set the SSRC on the RTP packet in @buffer to @ssrc.
 */
void
gst_rtp_buffer_set_ssrc (GstRTPBuffer * rtp, guint32 ssrc)
{
  GST_RTP_HEADER_SSRC (rtp->data[0]) = g_htonl (ssrc);
}

/**
 * gst_rtp_buffer_get_csrc_count:
 * @rtp: the RTP packet
 *
 * Get the CSRC count of the RTP packet in @buffer.
 *
 * Returns: the CSRC count of @buffer.
 */
guint8
gst_rtp_buffer_get_csrc_count (GstRTPBuffer * rtp)
{
  return GST_RTP_HEADER_CSRC_COUNT (rtp->data[0]);
}

/**
 * gst_rtp_buffer_get_csrc:
 * @rtp: the RTP packet
 * @idx: the index of the CSRC to get
 *
 * Get the CSRC at index @idx in @buffer.
 *
 * Returns: the CSRC at index @idx in host order.
 */
guint32
gst_rtp_buffer_get_csrc (GstRTPBuffer * rtp, guint8 idx)
{
  guint8 *data;

  data = rtp->data[0];

  g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);

  return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx));
}

/**
 * gst_rtp_buffer_set_csrc:
 * @rtp: the RTP packet
 * @idx: the CSRC index to set
 * @csrc: the CSRC in host order to set at @idx
 *
 * Modify the CSRC at index @idx in @buffer to @csrc.
 */
void
gst_rtp_buffer_set_csrc (GstRTPBuffer * rtp, guint8 idx, guint32 csrc)
{
  guint8 *data;

  data = rtp->data[0];

  g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));

  GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
}

/**
 * gst_rtp_buffer_get_marker:
 * @rtp: the RTP packet
 *
 * Check if the marker bit is set on the RTP packet in @buffer.
 *
 * Returns: TRUE if @buffer has the marker bit set.
 */
gboolean
gst_rtp_buffer_get_marker (GstRTPBuffer * rtp)
{
  return GST_RTP_HEADER_MARKER (rtp->data[0]);
}

/**
 * gst_rtp_buffer_set_marker:
 * @rtp: the RTP packet
 * @marker: the new marker
 *
 * Set the marker bit on the RTP packet in @buffer to @marker.
 */
void
gst_rtp_buffer_set_marker (GstRTPBuffer * rtp, gboolean marker)
{
  GST_RTP_HEADER_MARKER (rtp->data[0]) = marker;
}

/**
 * gst_rtp_buffer_get_payload_type:
 * @rtp: the RTP packet
 *
 * Get the payload type of the RTP packet in @buffer.
 *
 * Returns: The payload type.
 */
guint8
gst_rtp_buffer_get_payload_type (GstRTPBuffer * rtp)
{
  return GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data[0]);
}

/**
 * gst_rtp_buffer_set_payload_type:
 * @rtp: the RTP packet
 * @payload_type: the new type
 *
 * Set the payload type of the RTP packet in @buffer to @payload_type.
 */
void
gst_rtp_buffer_set_payload_type (GstRTPBuffer * rtp, guint8 payload_type)
{
  g_return_if_fail (payload_type < 0x80);

  GST_RTP_HEADER_PAYLOAD_TYPE (rtp->data[0]) = payload_type;
}

/**
 * gst_rtp_buffer_get_seq:
 * @rtp: the RTP packet
 *
 * Get the sequence number of the RTP packet in @buffer.
 *
 * Returns: The sequence number in host order.
 */
guint16
gst_rtp_buffer_get_seq (GstRTPBuffer * rtp)
{
  return g_ntohs (GST_RTP_HEADER_SEQ (rtp->data[0]));
}

/**
 * gst_rtp_buffer_set_seq:
 * @rtp: the RTP packet
 * @seq: the new sequence number
 *
 * Set the sequence number of the RTP packet in @buffer to @seq.
 */
void
gst_rtp_buffer_set_seq (GstRTPBuffer * rtp, guint16 seq)
{
  GST_RTP_HEADER_SEQ (rtp->data[0]) = g_htons (seq);
}

/**
 * gst_rtp_buffer_get_timestamp:
 * @rtp: the RTP packet
 *
 * Get the timestamp of the RTP packet in @buffer.
 *
 * Returns: The timestamp in host order.
 */
guint32
gst_rtp_buffer_get_timestamp (GstRTPBuffer * rtp)
{
  return g_ntohl (GST_RTP_HEADER_TIMESTAMP (rtp->data[0]));
}

/**
 * gst_rtp_buffer_set_timestamp:
 * @rtp: the RTP packet
 * @timestamp: the new timestamp
 *
 * Set the timestamp of the RTP packet in @buffer to @timestamp.
 */
void
gst_rtp_buffer_set_timestamp (GstRTPBuffer * rtp, guint32 timestamp)
{
  GST_RTP_HEADER_TIMESTAMP (rtp->data[0]) = g_htonl (timestamp);
}


/**
 * gst_rtp_buffer_get_payload_subbuffer:
 * @rtp: the RTP packet
 * @offset: the offset in the payload
 * @len: the length in the payload
 *
 * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes
 * are skipped in the payload and the subbuffer will be of size @len.
 * If @len is -1 the total payload starting from @offset is subbuffered.
 *
 * Returns: A new buffer with the specified data of the payload.
 */
GstBuffer *
gst_rtp_buffer_get_payload_subbuffer (GstRTPBuffer * rtp, guint offset,
    guint len)
{
  guint poffset, plen;

  plen = gst_rtp_buffer_get_payload_len (rtp);
  /* we can't go past the length */
  if (G_UNLIKELY (offset > plen))
    goto wrong_offset;

  /* apply offset */
  poffset = gst_rtp_buffer_get_header_len (rtp) + offset;
  plen -= offset;

  /* see if we need to shrink the buffer based on @len */
  if (len != -1 && len < plen)
    plen = len;

  return gst_buffer_copy_region (rtp->buffer, GST_BUFFER_COPY_ALL, poffset,
      plen);

  /* ERRORS */
wrong_offset:
  {
    g_warning ("offset=%u should be less than plen=%u", offset, plen);
    return NULL;
  }
}

/**
 * gst_rtp_buffer_get_payload_buffer:
 * @rtp: the RTP packet
 *
 * Create a buffer of the payload of the RTP packet in @buffer. This function
 * will internally create a subbuffer of @buffer so that a memcpy can be
 * avoided.
 *
 * Returns: A new buffer with the data of the payload.
 */
GstBuffer *
gst_rtp_buffer_get_payload_buffer (GstRTPBuffer * rtp)
{
  return gst_rtp_buffer_get_payload_subbuffer (rtp, 0, -1);
}

/**
 * gst_rtp_buffer_get_payload_len:
 * @rtp: the RTP packet
 *
 * Get the length of the payload of the RTP packet in @buffer.
 *
 * Returns: The length of the payload in @buffer.
 */
guint
gst_rtp_buffer_get_payload_len (GstRTPBuffer * rtp)
{
  return gst_buffer_get_size (rtp->buffer) - gst_rtp_buffer_get_header_len (rtp)
      - rtp->size[3];
}

/**
 * gst_rtp_buffer_get_payload: (skip)
 * @rtp: the RTP packet
 *
 * Get a pointer to the payload data in @buffer. This pointer is valid as long
 * as a reference to @buffer is held.
 *
 * Returns: (array) (element-type guint8) (transfer none): A pointer
 * to the payload data in @buffer.
 */
gpointer
gst_rtp_buffer_get_payload (GstRTPBuffer * rtp)
{
  if (rtp->data[2])
    return rtp->data[2];

  if (!gst_rtp_buffer_map_payload (rtp))
    return NULL;

  return rtp->data[2];
}

/**
 * gst_rtp_buffer_get_payload_bytes: (rename-to gst_rtp_buffer_get_payload)
 * @rtp: the RTP packet
 *
 * Similar to gst_rtp_buffer_get_payload, but more suitable for language
 * bindings usage. The return value is a pointer to a #GBytes structure
 * containing the payload data in @rtp.
 *
 * Returns: (transfer full): A new #GBytes containing the payload data in @rtp.
 *
 * Since: 1.2
 */
GBytes *
gst_rtp_buffer_get_payload_bytes (GstRTPBuffer * rtp)
{
  gpointer data;

  g_return_val_if_fail (rtp != NULL, NULL);

  data = gst_rtp_buffer_get_payload (rtp);
  if (data == NULL)
    return NULL;

  return g_bytes_new (data, gst_rtp_buffer_get_payload_len (rtp));
}

/**
 * gst_rtp_buffer_default_clock_rate:
 * @payload_type: the static payload type
 *
 * Get the default clock-rate for the static payload type @payload_type.
 *
 * Returns: the default clock rate or -1 if the payload type is not static or
 * the clock-rate is undefined.
 */
guint32
gst_rtp_buffer_default_clock_rate (guint8 payload_type)
{
  const GstRTPPayloadInfo *info;
  guint32 res;

  info = gst_rtp_payload_info_for_pt (payload_type);
  if (!info)
    return -1;

  res = info->clock_rate;
  /* 0 means unknown so we have to return -1 from this function */
  if (res == 0)
    res = -1;

  return res;
}

/**
 * gst_rtp_buffer_compare_seqnum:
 * @seqnum1: a sequence number
 * @seqnum2: a sequence number
 *
 * Compare two sequence numbers, taking care of wraparounds. This function
 * returns the difference between @seqnum1 and @seqnum2.
 *
 * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they
 * are equal or a positive value if @seqnum1 is smaller than @segnum2.
 */
gint
gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
{
  /* See http://en.wikipedia.org/wiki/Serial_number_arithmetic
   * for an explanation why this does the right thing even for
   * wraparounds, under the assumption that the difference is
   * never bigger than 2**15 sequence numbers
   */
  return (gint16) (seqnum2 - seqnum1);
}

/**
 * gst_rtp_buffer_ext_timestamp:
 * @exttimestamp: a previous extended timestamp
 * @timestamp: a new timestamp
 *
 * Update the @exttimestamp field with @timestamp. For the first call of the
 * method, @exttimestamp should point to a location with a value of -1.
 *
 * This function makes sure that the returned value is a constantly increasing
 * value even in the case where there is a timestamp wraparound.
 *
 * Returns: The extended timestamp of @timestamp.
 */
guint64
gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
{
  guint64 result, diff, ext;

  g_return_val_if_fail (exttimestamp != NULL, -1);

  ext = *exttimestamp;

  if (ext == -1) {
    result = timestamp;
  } else {
    /* pick wraparound counter from previous timestamp and add to new timestamp */
    result = timestamp + (ext & ~(G_GUINT64_CONSTANT (0xffffffff)));

    /* check for timestamp wraparound */
    if (result < ext)
      diff = ext - result;
    else
      diff = result - ext;

    if (diff > G_MAXINT32) {
      /* timestamp went backwards more than allowed, we wrap around and get
       * updated extended timestamp. */
      result += (G_GUINT64_CONSTANT (1) << 32);
    }
  }
  *exttimestamp = result;

  return result;
}

/**
 * gst_rtp_buffer_get_extension_onebyte_header:
 * @rtp: the RTP packet
 * @id: The ID of the header extension to be read (between 1 and 14).
 * @nth: Read the nth extension packet with the requested ID
 * @data: (out) (array length=size) (element-type guint8) (transfer none):
 *   location for data
 * @size: (out): the size of the data in bytes
 *
 * Parses RFC 5285 style header extensions with a one byte header. It will
 * return the nth extension with the requested id.
 *
 * Returns: TRUE if @buffer had the requested header extension
 */

gboolean
gst_rtp_buffer_get_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
    guint nth, gpointer * data, guint * size)
{
  guint16 bits;
  guint8 *pdata;
  guint wordlen;
  gulong offset = 0;
  guint count = 0;

  g_return_val_if_fail (id > 0 && id < 15, FALSE);

  if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata,
          &wordlen))
    return FALSE;

  if (bits != 0xBEDE)
    return FALSE;

  for (;;) {
    guint8 read_id, read_len;

    if (offset + 1 >= wordlen * 4)
      break;

    read_id = GST_READ_UINT8 (pdata + offset) >> 4;
    read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
    offset += 1;

    /* ID 0 means its padding, skip */
    if (read_id == 0)
      continue;

    /* ID 15 is special and means we should stop parsing */
    if (read_id == 15)
      break;

    /* Ignore extension headers where the size does not fit */
    if (offset + read_len > wordlen * 4)
      break;

    /* If we have the right one */
    if (id == read_id) {
      if (nth == count) {
        if (data)
          *data = pdata + offset;
        if (size)
          *size = read_len;

        return TRUE;
      }

      count++;
    }
    offset += read_len;

    if (offset >= wordlen * 4)
      break;
  }

  return FALSE;
}

/**
 * gst_rtp_buffer_get_extension_twobytes_header:
 * @rtp: the RTP packet
 * @appbits: (out): Application specific bits
 * @id: The ID of the header extension to be read (between 1 and 14).
 * @nth: Read the nth extension packet with the requested ID
 * @data: (out) (array length=size) (element-type guint8) (transfer none):
 *   location for data
 * @size: (out): the size of the data in bytes
 *
 * Parses RFC 5285 style header extensions with a two bytes header. It will
 * return the nth extension with the requested id.
 *
 * Returns: TRUE if @buffer had the requested header extension
 */

gboolean
gst_rtp_buffer_get_extension_twobytes_header (GstRTPBuffer * rtp,
    guint8 * appbits, guint8 id, guint nth, gpointer * data, guint * size)
{
  guint16 bits;
  guint8 *pdata = NULL;
  guint wordlen;
  guint bytelen;
  gulong offset = 0;
  guint count = 0;

  if (!gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer *) & pdata,
          &wordlen))
    return FALSE;

  if (bits >> 4 != 0x100)
    return FALSE;

  bytelen = wordlen * 4;

  for (;;) {
    guint8 read_id, read_len;

    if (offset + 2 >= bytelen)
      break;

    read_id = GST_READ_UINT8 (pdata + offset);
    offset += 1;

    if (read_id == 0)
      continue;

    read_len = GST_READ_UINT8 (pdata + offset);
    offset += 1;

    /* Ignore extension headers where the size does not fit */
    if (offset + read_len > bytelen)
      break;

    /* If we have the right one, return it */
    if (id == read_id) {
      if (nth == count) {
        if (data)
          *data = pdata + offset;
        if (size)
          *size = read_len;
        if (appbits)
          *appbits = bits;

        return TRUE;
      }

      count++;
    }
    offset += read_len;
  }

  return FALSE;
}

static guint
get_onebyte_header_end_offset (guint8 * pdata, guint wordlen)
{
  guint offset = 0;
  guint bytelen = wordlen * 4;
  guint paddingcount = 0;

  while (offset + 1 < bytelen) {
    guint8 read_id, read_len;

    read_id = GST_READ_UINT8 (pdata + offset) >> 4;
    read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
    offset += 1;

    /* ID 0 means its padding, skip */
    if (read_id == 0) {
      paddingcount++;
      continue;
    }

    paddingcount = 0;

    /* ID 15 is special and means we should stop parsing */
    /* It also means we can't add an extra packet */
    if (read_id == 15)
      return 0;

    /* Ignore extension headers where the size does not fit */
    if (offset + read_len > bytelen)
      return 0;

    offset += read_len;
  }

  return offset - paddingcount;
}

/**
 * gst_rtp_buffer_add_extension_onebyte_header:
 * @rtp: the RTP packet
 * @id: The ID of the header extension (between 1 and 14).
 * @data: (array length=size) (element-type guint8): location for data
 * @size: the size of the data in bytes
 *
 * Adds a RFC 5285 header extension with a one byte header to the end of the
 * RTP header. If there is already a RFC 5285 header extension with a one byte
 * header, the new extension will be appended.
 * It will not work if there is already a header extension that does not follow
 * the mecanism described in RFC 5285 or if there is a header extension with
 * a two bytes header as described in RFC 5285. In that case, use
 * gst_rtp_buffer_add_extension_twobytes_header()
 *
 * Returns: %TRUE if header extension could be added
 */

gboolean
gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
    gconstpointer data, guint size)
{
  guint16 bits;
  guint8 *pdata = 0;
  guint wordlen;
  gboolean has_bit;
  guint extlen, offset = 0;

  g_return_val_if_fail (id > 0 && id < 15, FALSE);
  g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
  g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);

  has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
      (gpointer) & pdata, &wordlen);

  if (has_bit) {
    if (bits != 0xBEDE)
      return FALSE;

    offset = get_onebyte_header_end_offset (pdata, wordlen);
    if (offset == 0)
      return FALSE;
  }

  /* the required size of the new extension data */
  extlen = offset + size + 1;
  /* calculate amount of words */
  wordlen = extlen / 4 + ((extlen % 4) ? 1 : 0);

  gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
  gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata, &wordlen);

  pdata += offset;

  pdata[0] = (id << 4) | (0x0F & (size - 1));
  memcpy (pdata + 1, data, size);

  if (extlen % 4)
    memset (pdata + 1 + size, 0, 4 - (extlen % 4));

  return TRUE;
}


static guint
get_twobytes_header_end_offset (const guint8 * pdata, guint wordlen)
{
  guint offset = 0;
  guint bytelen = wordlen * 4;
  guint paddingcount = 0;

  while (offset + 2 < bytelen) {
    guint8 read_id, read_len;

    read_id = GST_READ_UINT8 (pdata + offset);
    offset += 1;

    /* ID 0 means its padding, skip */
    if (read_id == 0) {
      paddingcount++;
      continue;
    }

    paddingcount = 0;

    read_len = GST_READ_UINT8 (pdata + offset);
    offset += 1;

    /* Ignore extension headers where the size does not fit */
    if (offset + read_len > bytelen)
      return 0;

    offset += read_len;
  }

  return offset - paddingcount;
}

/**
 * gst_rtp_buffer_add_extension_twobytes_header:
 * @rtp: the RTP packet
 * @appbits: Application specific bits
 * @id: The ID of the header extension
 * @data: (array length=size) (element-type guint8): location for data
 * @size: the size of the data in bytes
 *
 * Adds a RFC 5285 header extension with a two bytes header to the end of the
 * RTP header. If there is already a RFC 5285 header extension with a two bytes
 * header, the new extension will be appended.
 * It will not work if there is already a header extension that does not follow
 * the mecanism described in RFC 5285 or if there is a header extension with
 * a one byte header as described in RFC 5285. In that case, use
 * gst_rtp_buffer_add_extension_onebyte_header()
 *
 * Returns: %TRUE if header extension could be added
 */

gboolean
gst_rtp_buffer_add_extension_twobytes_header (GstRTPBuffer * rtp,
    guint8 appbits, guint8 id, gconstpointer data, guint size)
{
  guint16 bits;
  guint8 *pdata = 0;
  guint wordlen;
  gboolean has_bit;
  gulong offset = 0;
  guint extlen;

  g_return_val_if_fail ((appbits & 0xF0) == 0, FALSE);
  g_return_val_if_fail (size < 256, FALSE);
  g_return_val_if_fail (gst_buffer_is_writable (rtp->buffer), FALSE);

  has_bit = gst_rtp_buffer_get_extension_data (rtp, &bits,
      (gpointer) & pdata, &wordlen);

  if (has_bit) {
    if (bits != ((0x100 << 4) | (appbits & 0x0f)))
      return FALSE;

    offset = get_twobytes_header_end_offset (pdata, wordlen);
    if (offset == 0)
      return FALSE;
  }

  /* the required size of the new extension data */
  extlen = offset + size + 2;
  /* calculate amount of words */
  wordlen = extlen / 4 + ((extlen % 4) ? 1 : 0);

  gst_rtp_buffer_set_extension_data (rtp, (0x100 << 4) | (appbits & 0x0F),
      wordlen);
  gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata, &wordlen);

  pdata += offset;

  pdata[0] = id;
  pdata[1] = size;
  memcpy (pdata + 2, data, size);
  if (extlen % 4)
    memset (pdata + 2 + size, 0, 4 - (extlen % 4));

  return TRUE;
}
