/* GStreamer
 * Copyright (C) <2007> Wim Taymans <wim@fluendo.com>
 *
 * gstrtcpbuffer.h: various helper functions to manipulate buffers
 *     with RTCP payload.
 *
 * 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:gstrtcpbuffer
 * @title: GstRTCPBuffer
 * @short_description: Helper methods for dealing with RTCP buffers
 * @see_also: #GstRTPBasePayload, #GstRTPBaseDepayload, #gstrtpbuffer
 *
 * Note: The API in this module is not yet declared stable.
 *
 * The GstRTPCBuffer helper functions makes it easy to parse and create regular
 * #GstBuffer objects that contain compound RTCP packets. These buffers are typically
 * of 'application/x-rtcp' #GstCaps.
 *
 * An RTCP buffer consists of 1 or more #GstRTCPPacket structures that you can
 * retrieve with gst_rtcp_buffer_get_first_packet(). #GstRTCPPacket acts as a pointer
 * into the RTCP buffer; you can move to the next packet with
 * gst_rtcp_packet_move_to_next().
 *
 */

#include <string.h>

#include "gstrtcpbuffer.h"

/**
 * gst_rtcp_buffer_new_take_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 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_rtcp_buffer_new_take_data (gpointer data, guint len)
{
  GstBuffer *result;

  g_return_val_if_fail (data != NULL, NULL);
  g_return_val_if_fail (len > 0, NULL);

  result = gst_buffer_new_wrapped (data, len);

  return result;
}

/**
 * gst_rtcp_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_rtcp_buffer_new_copy_data (gconstpointer data, guint len)
{
  return gst_rtcp_buffer_new_take_data (g_memdup (data, len), len);
}

static gboolean
gst_rtcp_buffer_validate_data_internal (guint8 * data, guint len,
    guint16 valid_mask)
{
  guint16 header_mask;
  guint header_len;
  guint8 version;
  guint data_len;
  gboolean padding;
  guint8 pad_bytes;

  g_return_val_if_fail (data != NULL, FALSE);

  /* we need 4 bytes for the type and length */
  if (G_UNLIKELY (len < 4))
    goto wrong_length;

  /* first packet must be RR or SR  and version must be 2 */
  header_mask = ((data[0] << 8) | data[1]) & valid_mask;
  if (G_UNLIKELY (header_mask != GST_RTCP_VALID_VALUE))
    goto wrong_mask;

  /* no padding when mask succeeds */
  padding = FALSE;

  /* store len */
  data_len = len;

  while (TRUE) {
    /* get packet length */
    header_len = (((data[2] << 8) | data[3]) + 1) << 2;
    if (data_len < header_len)
      goto wrong_length;

    /* move to next compount packet */
    data += header_len;
    data_len -= header_len;

    /* we are at the end now */
    if (data_len < 4)
      break;

    /* padding only allowed on last packet */
    if (padding)
      break;

    /* check version of new packet */
    version = data[0] & 0xc0;
    if (version != (GST_RTCP_VERSION << 6))
      goto wrong_version;

    /* check padding of new packet */
    if (data[0] & 0x20) {
      padding = TRUE;
      /* last byte of padding contains the number of padded bytes including
       * itself. must be a multiple of 4, but cannot be 0. */
      pad_bytes = data[data_len - 1];
      if (pad_bytes == 0 || (pad_bytes & 0x3))
        goto wrong_padding;
    }
  }
  if (data_len != 0) {
    /* some leftover bytes */
    goto wrong_length;
  }
  return TRUE;

  /* ERRORS */
wrong_length:
  {
    GST_DEBUG ("len check failed");
    return FALSE;
  }
wrong_mask:
  {
    GST_DEBUG ("mask check failed (%04x != %04x)", header_mask, valid_mask);
    return FALSE;
  }
wrong_version:
  {
    GST_DEBUG ("wrong version (%d < 2)", version >> 6);
    return FALSE;
  }
wrong_padding:
  {
    GST_DEBUG ("padding check failed");
    return FALSE;
  }
}

/**
 * gst_rtcp_buffer_validate_data_reduced:
 * @data: (array length=len): the data to validate
 * @len: the length of @data to validate
 *
 * Check if the @data and @size point to the data of a valid RTCP packet.
 * Use this function to validate a packet before using the other functions in
 * this module.
 *
 * This function is updated to support reduced size rtcp packets according to
 * RFC 5506 and will validate full compound RTCP packets as well as reduced
 * size RTCP packets.
 *
 * Returns: TRUE if the data points to a valid RTCP packet.
 *
 * Since: 1.6
 */
gboolean
gst_rtcp_buffer_validate_data_reduced (guint8 * data, guint len)
{
  return gst_rtcp_buffer_validate_data_internal (data, len,
      GST_RTCP_REDUCED_SIZE_VALID_MASK);
}

/**
 * gst_rtcp_buffer_validate_data:
 * @data: (array length=len): the data to validate
 * @len: the length of @data to validate
 *
 * Check if the @data and @size point to the data of a valid compound,
 * non-reduced size RTCP packet.
 * Use this function to validate a packet before using the other functions in
 * this module.
 *
 * Returns: TRUE if the data points to a valid RTCP packet.
 */
gboolean
gst_rtcp_buffer_validate_data (guint8 * data, guint len)
{
  return gst_rtcp_buffer_validate_data_internal (data, len,
      GST_RTCP_VALID_MASK);
}

/**
 * gst_rtcp_buffer_validate_reduced:
 * @buffer: the buffer to validate
 *
 * Check if the data pointed to by @buffer is a valid RTCP packet using
 * gst_rtcp_buffer_validate_reduced().
 *
 * Returns: TRUE if @buffer is a valid RTCP packet.
 *
 * Since: 1.6
 */
gboolean
gst_rtcp_buffer_validate_reduced (GstBuffer * buffer)
{
  gboolean res;
  GstMapInfo map;

  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);

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

  return res;
}

/**
 * gst_rtcp_buffer_validate:
 * @buffer: the buffer to validate
 *
 * Check if the data pointed to by @buffer is a valid RTCP packet using
 * gst_rtcp_buffer_validate_data().
 *
 * Returns: TRUE if @buffer is a valid RTCP packet.
 */
gboolean
gst_rtcp_buffer_validate (GstBuffer * buffer)
{
  gboolean res;
  GstMapInfo map;

  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);

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

  return res;
}

/**
 * gst_rtcp_buffer_new:
 * @mtu: the maximum mtu size.
 *
 * Create a new buffer for constructing RTCP packets. The packet will have a
 * maximum size of @mtu.
 *
 * Returns: A newly allocated buffer.
 */
GstBuffer *
gst_rtcp_buffer_new (guint mtu)
{
  GstBuffer *result;
  guint8 *data;

  g_return_val_if_fail (mtu > 0, NULL);

  data = g_malloc0 (mtu);

  result = gst_buffer_new_wrapped_full (0, data, mtu, 0, 0, data, g_free);

  return result;
}

/**
 * gst_rtcp_buffer_map:
 * @buffer: a buffer with an RTCP packet
 * @flags: flags for the mapping
 * @rtcp: resulting #GstRTCPBuffer
 *
 * Open @buffer for reading or writing, depending on @flags. The resulting RTCP
 * buffer state is stored in @rtcp.
 */
gboolean
gst_rtcp_buffer_map (GstBuffer * buffer, GstMapFlags flags,
    GstRTCPBuffer * rtcp)
{
  g_return_val_if_fail (rtcp != NULL, FALSE);
  g_return_val_if_fail (rtcp->buffer == NULL, FALSE);
  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
  g_return_val_if_fail (flags & GST_MAP_READ, FALSE);

  rtcp->buffer = buffer;
  gst_buffer_map (buffer, &rtcp->map, flags);

  return TRUE;
}

/**
 * gst_rtcp_buffer_unmap:
 * @rtcp: a buffer with an RTCP packet
 *
 * Finish @rtcp after being constructed. This function is usually called
 * after gst_rtcp_buffer_map() and after adding the RTCP items to the new buffer.
 *
 * The function adjusts the size of @rtcp with the total length of all the
 * added packets.
 */
gboolean
gst_rtcp_buffer_unmap (GstRTCPBuffer * rtcp)
{
  g_return_val_if_fail (rtcp != NULL, FALSE);
  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), FALSE);

  if (rtcp->map.flags & GST_MAP_WRITE) {
    /* shrink size */
    gst_buffer_resize (rtcp->buffer, 0, rtcp->map.size);
  }

  gst_buffer_unmap (rtcp->buffer, &rtcp->map);
  rtcp->buffer = NULL;

  return TRUE;
}

/**
 * gst_rtcp_buffer_get_packet_count:
 * @rtcp: a valid RTCP buffer
 *
 * Get the number of RTCP packets in @rtcp.
 *
 * Returns: the number of RTCP packets in @rtcp.
 */
guint
gst_rtcp_buffer_get_packet_count (GstRTCPBuffer * rtcp)
{
  GstRTCPPacket packet;
  guint count;

  g_return_val_if_fail (rtcp != NULL, 0);
  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), 0);
  g_return_val_if_fail (rtcp != NULL, 0);
  g_return_val_if_fail (rtcp->map.flags & GST_MAP_READ, 0);

  count = 0;
  if (gst_rtcp_buffer_get_first_packet (rtcp, &packet)) {
    do {
      count++;
    } while (gst_rtcp_packet_move_to_next (&packet));
  }

  return count;
}

/**
 * read_packet_header:
 * @packet: a packet
 *
 * Read the packet headers for the packet pointed to by @packet.
 *
 * Returns: TRUE if @packet pointed to a valid header.
 */
static gboolean
read_packet_header (GstRTCPPacket * packet)
{
  guint8 *data;
  gsize maxsize;
  guint offset;

  g_return_val_if_fail (packet != NULL, FALSE);

  data = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.size;

  offset = packet->offset;

  /* check if we are at the end of the buffer, we add 4 because we also want to
   * ensure we can read the header. */
  if (offset + 4 > maxsize)
    return FALSE;

  if ((data[offset] & 0xc0) != (GST_RTCP_VERSION << 6))
    return FALSE;

  /* read count, type and length */
  packet->padding = (data[offset] & 0x20) == 0x20;
  packet->count = data[offset] & 0x1f;
  packet->type = data[offset + 1];
  packet->length = (data[offset + 2] << 8) | data[offset + 3];
  packet->item_offset = 4;
  packet->item_count = 0;
  packet->entry_offset = 4;

  /* Ensure no overread from the claimed data size. The packet length
     is expressed in multiple of 32 bits, to make things obvious. */
  if (offset + 4 + packet->length * 4 > maxsize)
    return FALSE;

  return TRUE;
}

/**
 * gst_rtcp_buffer_get_first_packet:
 * @rtcp: a valid RTCP buffer
 * @packet: a #GstRTCPPacket
 *
 * Initialize a new #GstRTCPPacket pointer that points to the first packet in
 * @rtcp.
 *
 * Returns: TRUE if the packet existed in @rtcp.
 */
gboolean
gst_rtcp_buffer_get_first_packet (GstRTCPBuffer * rtcp, GstRTCPPacket * packet)
{
  g_return_val_if_fail (rtcp != NULL, FALSE);
  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), FALSE);
  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (rtcp != NULL, 0);
  g_return_val_if_fail (rtcp->map.flags & GST_MAP_READ, 0);

  /* init to 0 */
  packet->rtcp = rtcp;
  packet->offset = 0;
  packet->type = GST_RTCP_TYPE_INVALID;

  if (!read_packet_header (packet))
    return FALSE;

  return TRUE;
}

/**
 * gst_rtcp_packet_move_to_next:
 * @packet: a #GstRTCPPacket
 *
 * Move the packet pointer @packet to the next packet in the payload.
 * Use gst_rtcp_buffer_get_first_packet() to initialize @packet.
 *
 * Returns: TRUE if @packet is pointing to a valid packet after calling this
 * function.
 */
gboolean
gst_rtcp_packet_move_to_next (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  /* if we have a padding or invalid packet, it must be the last, 
   * return FALSE */
  if (packet->type == GST_RTCP_TYPE_INVALID || packet->padding)
    goto end;

  /* move to next packet. Add 4 because the header is not included in length */
  packet->offset += (packet->length << 2) + 4;

  /* try to read new header */
  if (!read_packet_header (packet))
    goto end;

  return TRUE;

  /* ERRORS */
end:
  {
    packet->type = GST_RTCP_TYPE_INVALID;
    return FALSE;
  }
}

/**
 * gst_rtcp_buffer_add_packet:
 * @rtcp: a valid RTCP buffer
 * @type: the #GstRTCPType of the new packet
 * @packet: pointer to new packet
 *
 * Add a new packet of @type to @rtcp. @packet will point to the newly created
 * packet.
 *
 * Returns: %TRUE if the packet could be created. This function returns %FALSE
 * if the max mtu is exceeded for the buffer.
 */
gboolean
gst_rtcp_buffer_add_packet (GstRTCPBuffer * rtcp, GstRTCPType type,
    GstRTCPPacket * packet)
{
  guint len;
  gsize maxsize;
  guint8 *data;
  gboolean result;

  g_return_val_if_fail (rtcp != NULL, FALSE);
  g_return_val_if_fail (GST_IS_BUFFER (rtcp->buffer), FALSE);
  g_return_val_if_fail (type != GST_RTCP_TYPE_INVALID, FALSE);
  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (rtcp->map.flags & GST_MAP_WRITE, FALSE);

  /* find free space */
  if (gst_rtcp_buffer_get_first_packet (rtcp, packet))
    while (gst_rtcp_packet_move_to_next (packet));

  maxsize = rtcp->map.maxsize;

  /* packet->offset is now pointing to the next free offset in the buffer to
   * start a compount packet. Next we figure out if we have enough free space in
   * the buffer to continue. */
  switch (type) {
    case GST_RTCP_TYPE_SR:
      len = 28;
      break;
    case GST_RTCP_TYPE_RR:
      len = 8;
      break;
    case GST_RTCP_TYPE_SDES:
      len = 4;
      break;
    case GST_RTCP_TYPE_BYE:
      len = 4;
      break;
    case GST_RTCP_TYPE_APP:
      len = 12;
      break;
    case GST_RTCP_TYPE_RTPFB:
      len = 12;
      break;
    case GST_RTCP_TYPE_PSFB:
      len = 12;
      break;
    case GST_RTCP_TYPE_XR:
      len = 4;
      break;
    default:
      goto unknown_type;
  }
  if (packet->offset + len >= maxsize)
    goto no_space;

  rtcp->map.size += len;

  data = rtcp->map.data + packet->offset;

  data[0] = (GST_RTCP_VERSION << 6);
  data[1] = type;
  /* length is stored in multiples of 32 bit words minus the length of the
   * header */
  len = (len - 4) >> 2;
  data[2] = len >> 8;
  data[3] = len & 0xff;

  /* now try to position to the packet */
  result = read_packet_header (packet);

  return result;

  /* ERRORS */
unknown_type:
  {
    g_warning ("unknown type %d", type);
    return FALSE;
  }
no_space:
  {
    return FALSE;
  }
}

/**
 * gst_rtcp_packet_remove:
 * @packet: a #GstRTCPPacket
 *
 * Removes the packet pointed to by @packet and moves pointer to the next one
 *
 * Returns: TRUE if @packet is pointing to a valid packet after calling this
 * function.
 */
gboolean
gst_rtcp_packet_remove (GstRTCPPacket * packet)
{
  gboolean ret = FALSE;
  guint offset = 0;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  /* The next packet starts at offset + length + 4 (the header) */
  offset = packet->offset + (packet->length << 2) + 4;

  /* Overwrite this packet with the rest of the data */
  memmove (packet->rtcp->map.data + packet->offset,
      packet->rtcp->map.data + offset, packet->rtcp->map.size - offset);

  packet->rtcp->map.size -= offset - packet->offset;

  /* try to read next header */
  ret = read_packet_header (packet);
  if (!ret)
    packet->type = GST_RTCP_TYPE_INVALID;

  return ret;
}

/**
 * gst_rtcp_packet_get_padding:
 * @packet: a valid #GstRTCPPacket
 *
 * Get the packet padding of the packet pointed to by @packet.
 *
 * Returns: If the packet has the padding bit set.
 */
gboolean
gst_rtcp_packet_get_padding (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, FALSE);

  return packet->padding;
}

/**
 * gst_rtcp_packet_get_type:
 * @packet: a valid #GstRTCPPacket
 *
 * Get the packet type of the packet pointed to by @packet.
 *
 * Returns: The packet type or GST_RTCP_TYPE_INVALID when @packet is not
 * pointing to a valid packet.
 */
GstRTCPType
gst_rtcp_packet_get_type (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, GST_RTCP_TYPE_INVALID);

  return packet->type;
}

/**
 * gst_rtcp_packet_get_count:
 * @packet: a valid #GstRTCPPacket
 *
 * Get the count field in @packet.
 *
 * Returns: The count field in @packet or -1 if @packet does not point to a
 * valid packet.
 */
guint8
gst_rtcp_packet_get_count (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, -1);
  g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, -1);

  return packet->count;
}

/**
 * gst_rtcp_packet_get_length:
 * @packet: a valid #GstRTCPPacket
 *
 * Get the length field of @packet. This is the length of the packet in
 * 32-bit words minus one.
 *
 * Returns: The length field of @packet.
 */
guint16
gst_rtcp_packet_get_length (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type != GST_RTCP_TYPE_INVALID, 0);

  return packet->length;
}

/**
 * gst_rtcp_packet_sr_get_sender_info:
 * @packet: a valid SR #GstRTCPPacket
 * @ssrc: (out): result SSRC
 * @ntptime: (out): result NTP time
 * @rtptime: (out): result RTP time
 * @packet_count: (out): result packet count
 * @octet_count: (out): result octet count
 *
 * Parse the SR sender info and store the values.
 */
void
gst_rtcp_packet_sr_get_sender_info (GstRTCPPacket * packet, guint32 * ssrc,
    guint64 * ntptime, guint32 * rtptime, guint32 * packet_count,
    guint32 * octet_count)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_SR);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_READ);

  data = packet->rtcp->map.data;

  /* skip header */
  data += packet->offset + 4;
  if (ssrc)
    *ssrc = GST_READ_UINT32_BE (data);
  data += 4;
  if (ntptime)
    *ntptime = GST_READ_UINT64_BE (data);
  data += 8;
  if (rtptime)
    *rtptime = GST_READ_UINT32_BE (data);
  data += 4;
  if (packet_count)
    *packet_count = GST_READ_UINT32_BE (data);
  data += 4;
  if (octet_count)
    *octet_count = GST_READ_UINT32_BE (data);
}

/**
 * gst_rtcp_packet_sr_set_sender_info:
 * @packet: a valid SR #GstRTCPPacket
 * @ssrc: the SSRC
 * @ntptime: the NTP time
 * @rtptime: the RTP time
 * @packet_count: the packet count
 * @octet_count: the octet count
 *
 * Set the given values in the SR packet @packet.
 */
void
gst_rtcp_packet_sr_set_sender_info (GstRTCPPacket * packet, guint32 ssrc,
    guint64 ntptime, guint32 rtptime, guint32 packet_count, guint32 octet_count)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_SR);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data;

  /* skip header */
  data += packet->offset + 4;
  GST_WRITE_UINT32_BE (data, ssrc);
  data += 4;
  GST_WRITE_UINT64_BE (data, ntptime);
  data += 8;
  GST_WRITE_UINT32_BE (data, rtptime);
  data += 4;
  GST_WRITE_UINT32_BE (data, packet_count);
  data += 4;
  GST_WRITE_UINT32_BE (data, octet_count);
}

/**
 * gst_rtcp_packet_rr_get_ssrc:
 * @packet: a valid RR #GstRTCPPacket
 *
 * Get the ssrc field of the RR @packet.
 *
 * Returns: the ssrc.
 */
guint32
gst_rtcp_packet_rr_get_ssrc (GstRTCPPacket * packet)
{
  guint8 *data;
  guint32 ssrc;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data;

  /* skip header */
  data += packet->offset + 4;
  ssrc = GST_READ_UINT32_BE (data);

  return ssrc;
}

/**
 * gst_rtcp_packet_rr_set_ssrc:
 * @packet: a valid RR #GstRTCPPacket
 * @ssrc: the SSRC to set
 *
 * Set the ssrc field of the RR @packet.
 */
void
gst_rtcp_packet_rr_set_ssrc (GstRTCPPacket * packet, guint32 ssrc)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_RR);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data;

  /* skip header */
  data += packet->offset + 4;
  GST_WRITE_UINT32_BE (data, ssrc);
}

/**
 * gst_rtcp_packet_get_rb_count:
 * @packet: a valid SR or RR #GstRTCPPacket
 *
 * Get the number of report blocks in @packet.
 *
 * Returns: The number of report blocks in @packet.
 */
guint
gst_rtcp_packet_get_rb_count (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  return packet->count;
}

/**
 * gst_rtcp_packet_get_rb:
 * @packet: a valid SR or RR #GstRTCPPacket
 * @nth: the nth report block in @packet
 * @ssrc: (out): result for data source being reported
 * @fractionlost: (out): result for fraction lost since last SR/RR
 * @packetslost: (out): result for the cumululative number of packets lost
 * @exthighestseq: (out): result for the extended last sequence number received
 * @jitter: (out): result for the interarrival jitter
 * @lsr: (out): result for the last SR packet from this source
 * @dlsr: (out): result for the delay since last SR packet
 *
 * Parse the values of the @nth report block in @packet and store the result in
 * the values.
 */
void
gst_rtcp_packet_get_rb (GstRTCPPacket * packet, guint nth, guint32 * ssrc,
    guint8 * fractionlost, gint32 * packetslost, guint32 * exthighestseq,
    guint32 * jitter, guint32 * lsr, guint32 * dlsr)
{
  guint offset;
  guint8 *data;
  guint32 tmp;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_READ);
  g_return_if_fail (nth < packet->count);

  /* get offset in 32-bits words into packet, skip the header */
  if (packet->type == GST_RTCP_TYPE_RR)
    offset = 2;
  else
    offset = 7;

  /* move to requested index */
  offset += (nth * 6);

  /* check that we don't go past the packet length */
  if (offset > packet->length)
    return;

  /* scale to bytes */
  offset <<= 2;
  offset += packet->offset;

  /* check if the packet is valid */
  if (offset + 24 > packet->rtcp->map.size)
    return;

  data = packet->rtcp->map.data;
  data += offset;

  if (ssrc)
    *ssrc = GST_READ_UINT32_BE (data);
  data += 4;
  tmp = GST_READ_UINT32_BE (data);
  if (fractionlost)
    *fractionlost = (tmp >> 24);
  if (packetslost) {
    /* sign extend */
    if (tmp & 0x00800000)
      tmp |= 0xff000000;
    else
      tmp &= 0x00ffffff;
    *packetslost = (gint32) tmp;
  }
  data += 4;
  if (exthighestseq)
    *exthighestseq = GST_READ_UINT32_BE (data);
  data += 4;
  if (jitter)
    *jitter = GST_READ_UINT32_BE (data);
  data += 4;
  if (lsr)
    *lsr = GST_READ_UINT32_BE (data);
  data += 4;
  if (dlsr)
    *dlsr = GST_READ_UINT32_BE (data);
}

/**
 * gst_rtcp_packet_add_rb:
 * @packet: a valid SR or RR #GstRTCPPacket
 * @ssrc: data source being reported
 * @fractionlost: fraction lost since last SR/RR
 * @packetslost: the cumululative number of packets lost
 * @exthighestseq: the extended last sequence number received
 * @jitter: the interarrival jitter
 * @lsr: the last SR packet from this source
 * @dlsr: the delay since last SR packet
 *
 * Add a new report block to @packet with the given values.
 *
 * Returns: %TRUE if the packet was created. This function can return %FALSE if
 * the max MTU is exceeded or the number of report blocks is greater than
 * #GST_RTCP_MAX_RB_COUNT.
 */
gboolean
gst_rtcp_packet_add_rb (GstRTCPPacket * packet, guint32 ssrc,
    guint8 fractionlost, gint32 packetslost, guint32 exthighestseq,
    guint32 jitter, guint32 lsr, guint32 dlsr)
{
  guint8 *data;
  guint maxsize, offset;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);
  /* if profile-specific extension is added, fail for now!? */
  g_return_val_if_fail (gst_rtcp_packet_get_profile_specific_ext_length (packet)
      == 0, FALSE);

  if (packet->count >= GST_RTCP_MAX_RB_COUNT)
    goto no_space;

  data = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.maxsize;

  /* skip header */
  offset = packet->offset + 4;
  if (packet->type == GST_RTCP_TYPE_RR)
    offset += 4;
  else
    offset += 24;

  /* move to current index */
  offset += (packet->count * 24);

  /* we need 24 free bytes now */
  if (offset + 24 >= maxsize)
    goto no_space;

  /* increment packet count and length */
  packet->count++;
  data[packet->offset]++;
  packet->length += 6;
  data[packet->offset + 2] = (packet->length) >> 8;
  data[packet->offset + 3] = (packet->length) & 0xff;
  packet->rtcp->map.size += 6 * 4;

  /* move to new report block offset */
  data += offset;

  GST_WRITE_UINT32_BE (data, ssrc);
  data += 4;
  GST_WRITE_UINT32_BE (data,
      ((guint32) fractionlost << 24) | (packetslost & 0xffffff));
  data += 4;
  GST_WRITE_UINT32_BE (data, exthighestseq);
  data += 4;
  GST_WRITE_UINT32_BE (data, jitter);
  data += 4;
  GST_WRITE_UINT32_BE (data, lsr);
  data += 4;
  GST_WRITE_UINT32_BE (data, dlsr);

  return TRUE;

no_space:
  {
    return FALSE;
  }
}

/**
 * gst_rtcp_packet_set_rb:
 * @packet: a valid SR or RR #GstRTCPPacket
 * @nth: the nth report block to set
 * @ssrc: data source being reported
 * @fractionlost: fraction lost since last SR/RR
 * @packetslost: the cumululative number of packets lost
 * @exthighestseq: the extended last sequence number received
 * @jitter: the interarrival jitter
 * @lsr: the last SR packet from this source
 * @dlsr: the delay since last SR packet
 *
 * Set the @nth new report block in @packet with the given values.
 *
 * Note: Not implemented.
 */
void
gst_rtcp_packet_set_rb (GstRTCPPacket * packet, guint nth, guint32 ssrc,
    guint8 fractionlost, gint32 packetslost, guint32 exthighestseq,
    guint32 jitter, guint32 lsr, guint32 dlsr)
{
  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  g_warning ("not implemented");
}


/**
 * gst_rtcp_packet_add_profile_specific_ext:
 * @packet: a valid SR or RR #GstRTCPPacket
 * @data: (array length=len) (transfer none): profile-specific data
 * @len: length of the profile-specific data in bytes
 *
 * Add profile-specific extension @data to @packet. If @packet already
 * contains profile-specific extension @data will be appended to the existing
 * extension.
 *
 * Returns: %TRUE if the profile specific extension data was added.
 */
gboolean
gst_rtcp_packet_add_profile_specific_ext (GstRTCPPacket * packet,
    const guint8 * data, guint len)
{
  guint8 *bdata;
  guint maxsize, offset;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);
  g_return_val_if_fail ((len & 0x03) == 0, FALSE);

  bdata = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.maxsize;

  /* skip to the end of the packet */
  offset = packet->offset + (packet->length << 2) + 4;

  /* we need 'len' free bytes now */
  if (G_UNLIKELY (offset + len > maxsize))
    return FALSE;

  memcpy (&bdata[offset], data, len);
  packet->length += len >> 2;
  bdata[packet->offset + 2] = (packet->length) >> 8;
  bdata[packet->offset + 3] = (packet->length) & 0xff;
  packet->rtcp->map.size += len;

  return TRUE;
}

/**
 * gst_rtcp_packet_get_profile_specific_ext_length:
 * @packet: a valid SR or RR #GstRTCPPacket
 *
 * Returns: The number of 32-bit words containing profile-specific extension
 *          data from @packet.
 */
guint16
gst_rtcp_packet_get_profile_specific_ext_length (GstRTCPPacket * packet)
{
  guint pse_offset = 2;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  if (packet->type == GST_RTCP_TYPE_SR)
    pse_offset += 5;
  pse_offset += (packet->count * 6);

  if (pse_offset <= (packet->length + 1))
    return packet->length + 1 - pse_offset;

  /* This means that the packet is invalid! */
  return 0;
}

/**
 * gst_rtcp_packet_get_profile_specific_ext:
 * @packet: a valid SR or RR #GstRTCPPacket
 * @data: (out) (array length=len) (transfer none): result profile-specific data
 * @len: (out): result length of the profile-specific data
 *
 * Returns: %TRUE if there was valid data.
 */
gboolean
gst_rtcp_packet_get_profile_specific_ext (GstRTCPPacket * packet,
    guint8 ** data, guint * len)
{
  guint16 pse_len;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  pse_len = gst_rtcp_packet_get_profile_specific_ext_length (packet);
  if (pse_len > 0) {
    if (len != NULL)
      *len = pse_len * sizeof (guint32);
    if (data != NULL) {
      *data = packet->rtcp->map.data;
      *data += packet->offset;
      *data += ((packet->length + 1 - pse_len) * sizeof (guint32));
    }

    return TRUE;
  }

  return FALSE;
}

/**
 * gst_rtcp_packet_copy_profile_specific_ext:
 * @packet: a valid SR or RR #GstRTCPPacket
 * @data: (out) (array length=len): result profile-specific data
 * @len: (out): length of the profile-specific extension data
 *
 * The profile-specific extension data is copied into a new allocated
 * memory area @data. This must be freed with g_free() after usage.
 *
 * Returns: %TRUE if there was valid data.
 */
gboolean
gst_rtcp_packet_copy_profile_specific_ext (GstRTCPPacket * packet,
    guint8 ** data, guint * len)
{
  guint16 pse_len;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RR ||
      packet->type == GST_RTCP_TYPE_SR, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  pse_len = gst_rtcp_packet_get_profile_specific_ext_length (packet);
  if (pse_len > 0) {
    if (len != NULL)
      *len = pse_len * sizeof (guint32);
    if (data != NULL) {
      guint8 *ptr = packet->rtcp->map.data + packet->offset;
      ptr += ((packet->length + 1 - pse_len) * sizeof (guint32));
      *data = g_memdup (ptr, pse_len * sizeof (guint32));
    }

    return TRUE;
  }

  return FALSE;
}


/**
 * gst_rtcp_packet_sdes_get_item_count:
 * @packet: a valid SDES #GstRTCPPacket
 *
 * Get the number of items in the SDES packet @packet.
 *
 * Returns: The number of items in @packet.
 */
guint
gst_rtcp_packet_sdes_get_item_count (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);

  return packet->count;
}

/**
 * gst_rtcp_packet_sdes_first_item:
 * @packet: a valid SDES #GstRTCPPacket
 *
 * Move to the first SDES item in @packet.
 *
 * Returns: TRUE if there was a first item.
 */
gboolean
gst_rtcp_packet_sdes_first_item (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);

  packet->item_offset = 4;
  packet->item_count = 0;
  packet->entry_offset = 4;

  if (packet->count == 0)
    return FALSE;

  return TRUE;
}

/**
 * gst_rtcp_packet_sdes_next_item:
 * @packet: a valid SDES #GstRTCPPacket
 *
 * Move to the next SDES item in @packet.
 *
 * Returns: TRUE if there was a next item.
 */
gboolean
gst_rtcp_packet_sdes_next_item (GstRTCPPacket * packet)
{
  guint8 *data;
  guint offset;
  guint len;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  /* if we are at the last item, we are done */
  if (packet->item_count == packet->count)
    return FALSE;

  /* move to SDES */
  data = packet->rtcp->map.data;
  data += packet->offset;
  /* move to item */
  offset = packet->item_offset;
  /* skip SSRC */
  offset += 4;

  /* don't overrun */
  len = (packet->length << 2);

  while (offset < len) {
    if (data[offset] == 0) {
      /* end of list, round to next 32-bit word */
      offset = (offset + 4) & ~3;
      break;
    }
    offset += data[offset + 1] + 2;
  }
  if (offset >= len)
    return FALSE;

  packet->item_offset = offset;
  packet->item_count++;
  packet->entry_offset = 4;

  return TRUE;
}

/**
 * gst_rtcp_packet_sdes_get_ssrc:
 * @packet: a valid SDES #GstRTCPPacket
 *
 * Get the SSRC of the current SDES item.
 *
 * Returns: the SSRC of the current item.
 */
guint32
gst_rtcp_packet_sdes_get_ssrc (GstRTCPPacket * packet)
{
  guint32 ssrc;
  guint8 *data;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  /* move to SDES */
  data = packet->rtcp->map.data;
  data += packet->offset;
  /* move to item */
  data += packet->item_offset;

  ssrc = GST_READ_UINT32_BE (data);

  return ssrc;
}

/**
 * gst_rtcp_packet_sdes_first_entry:
 * @packet: a valid SDES #GstRTCPPacket
 *
 * Move to the first SDES entry in the current item.
 *
 * Returns: %TRUE if there was a first entry.
 */
gboolean
gst_rtcp_packet_sdes_first_entry (GstRTCPPacket * packet)
{
  guint8 *data;
  guint len, offset;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  /* move to SDES */
  data = packet->rtcp->map.data;
  data += packet->offset;
  /* move to item */
  offset = packet->item_offset;
  /* skip SSRC */
  offset += 4;

  packet->entry_offset = 4;

  /* don't overrun */
  len = (packet->length << 2);
  if (offset >= len)
    return FALSE;

  if (data[offset] == 0)
    return FALSE;

  return TRUE;
}

/**
 * gst_rtcp_packet_sdes_next_entry:
 * @packet: a valid SDES #GstRTCPPacket
 *
 * Move to the next SDES entry in the current item.
 *
 * Returns: %TRUE if there was a next entry.
 */
gboolean
gst_rtcp_packet_sdes_next_entry (GstRTCPPacket * packet)
{
  guint8 *data;
  guint len, offset, item_len;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  /* move to SDES */
  data = packet->rtcp->map.data;
  data += packet->offset;
  /* move to item */
  offset = packet->item_offset;
  /* move to entry */
  offset += packet->entry_offset;

  item_len = data[offset + 1] + 2;
  /* skip item */
  offset += item_len;

  /* don't overrun */
  len = (packet->length << 2);
  if (offset >= len)
    return FALSE;

  packet->entry_offset += item_len;

  /* check for end of list */
  if (data[offset] == 0)
    return FALSE;

  return TRUE;
}

/**
 * gst_rtcp_packet_sdes_get_entry:
 * @packet: a valid SDES #GstRTCPPacket
 * @type: result of the entry type
 * @len: (out): result length of the entry data
 * @data: (out) (array length=len) (transfer none): result entry data
 *
 * Get the data of the current SDES item entry. @type (when not NULL) will
 * contain the type of the entry. @data (when not NULL) will point to @len
 * bytes.
 *
 * When @type refers to a text item, @data will point to a UTF8 string. Note
 * that this UTF8 string is NOT null-terminated. Use
 * gst_rtcp_packet_sdes_copy_entry() to get a null-terminated copy of the entry.
 *
 * Returns: %TRUE if there was valid data.
 */
gboolean
gst_rtcp_packet_sdes_get_entry (GstRTCPPacket * packet,
    GstRTCPSDESType * type, guint8 * len, guint8 ** data)
{
  guint8 *bdata;
  guint offset;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  /* move to SDES */
  bdata = packet->rtcp->map.data;
  bdata += packet->offset;
  /* move to item */
  offset = packet->item_offset;
  /* move to entry */
  offset += packet->entry_offset;

  if (bdata[offset] == 0)
    return FALSE;

  if (type)
    *type = bdata[offset];
  if (len)
    *len = bdata[offset + 1];
  if (data)
    *data = &bdata[offset + 2];

  return TRUE;
}

/**
 * gst_rtcp_packet_sdes_copy_entry:
 * @packet: a valid SDES #GstRTCPPacket
 * @type: result of the entry type
 * @len: (out): result length of the entry data
 * @data: (out) (array length=len): result entry data
 *
 * This function is like gst_rtcp_packet_sdes_get_entry() but it returns a
 * null-terminated copy of the data instead. use g_free() after usage.
 *
 * Returns: %TRUE if there was valid data.
 */
gboolean
gst_rtcp_packet_sdes_copy_entry (GstRTCPPacket * packet,
    GstRTCPSDESType * type, guint8 * len, guint8 ** data)
{
  guint8 *tdata;
  guint8 tlen;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, FALSE);

  if (!gst_rtcp_packet_sdes_get_entry (packet, type, &tlen, &tdata))
    return FALSE;

  if (len)
    *len = tlen;
  if (data)
    *data = (guint8 *) g_strndup ((gchar *) tdata, tlen);

  return TRUE;
}

/**
 * gst_rtcp_packet_sdes_add_item:
 * @packet: a valid SDES #GstRTCPPacket
 * @ssrc: the SSRC of the new item to add
 *
 * Add a new SDES item for @ssrc to @packet.
 *
 * Returns: %TRUE if the item could be added, %FALSE if the maximum amount of
 * items has been exceeded for the SDES packet or the MTU has been reached.
 */
gboolean
gst_rtcp_packet_sdes_add_item (GstRTCPPacket * packet, guint32 ssrc)
{
  guint8 *data;
  guint offset;
  gsize maxsize;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  /* increment item count when possible */
  if (packet->count >= GST_RTCP_MAX_SDES_ITEM_COUNT)
    goto no_space;

  /* pretend there is a next packet for the next call */
  packet->count++;

  /* jump over current item */
  gst_rtcp_packet_sdes_next_item (packet);

  /* move to SDES */
  data = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.maxsize;
  data += packet->offset;
  /* move to current item */
  offset = packet->item_offset;

  /* we need 2 free words now */
  if (offset + 8 >= maxsize)
    goto no_next;

  /* write SSRC */
  GST_WRITE_UINT32_BE (&data[offset], ssrc);
  /* write 0 entry with padding */
  GST_WRITE_UINT32_BE (&data[offset + 4], 0);

  /* update count */
  data[0] = (data[0] & 0xe0) | packet->count;
  /* update length, we added 2 words */
  packet->length += 2;
  data[2] = (packet->length) >> 8;
  data[3] = (packet->length) & 0xff;

  packet->rtcp->map.size += 8;

  return TRUE;

  /* ERRORS */
no_space:
  {
    return FALSE;
  }
no_next:
  {
    packet->count--;
    return FALSE;
  }
}

/**
 * gst_rtcp_packet_sdes_add_entry:
 * @packet: a valid SDES #GstRTCPPacket
 * @type: the #GstRTCPSDESType of the SDES entry
 * @len: the data length
 * @data: (array length=len): the data
 *
 * Add a new SDES entry to the current item in @packet.
 *
 * Returns: %TRUE if the item could be added, %FALSE if the MTU has been
 * reached.
 */
gboolean
gst_rtcp_packet_sdes_add_entry (GstRTCPPacket * packet, GstRTCPSDESType type,
    guint8 len, const guint8 * data)
{
  guint8 *bdata;
  guint offset, padded;
  gsize maxsize;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_SDES, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  /* move to SDES */
  bdata = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.maxsize;
  bdata += packet->offset;
  /* move to item */
  offset = packet->item_offset;
  /* move to entry */
  offset += packet->entry_offset;

  /* add 1 byte end and up to 3 bytes padding to fill a full 32 bit word */
  padded = (offset + 2 + len + 1 + 3) & ~3;

  /* we need enough space for type, len, data and padding */
  if (packet->offset + padded >= maxsize)
    goto no_space;

  packet->rtcp->map.size = packet->offset + padded;

  bdata[offset] = type;
  bdata[offset + 1] = len;
  memcpy (&bdata[offset + 2], data, len);
  bdata[offset + 2 + len] = 0;

  /* calculate new packet length */
  packet->length = (padded - 4) >> 2;
  bdata[2] = (packet->length) >> 8;
  bdata[3] = (packet->length) & 0xff;

  /* position to new next entry */
  packet->entry_offset += 2 + len;

  return TRUE;

  /* ERRORS */
no_space:
  {
    return FALSE;
  }
}

/**
 * gst_rtcp_packet_bye_get_ssrc_count:
 * @packet: a valid BYE #GstRTCPPacket
 *
 * Get the number of SSRC fields in @packet.
 *
 * Returns: The number of SSRC fields in @packet.
 */
guint
gst_rtcp_packet_bye_get_ssrc_count (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, -1);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, -1);

  return packet->count;
}

/**
 * gst_rtcp_packet_bye_get_nth_ssrc:
 * @packet: a valid BYE #GstRTCPPacket
 * @nth: the nth SSRC to get
 *
 * Get the @nth SSRC of the BYE @packet.
 *
 * Returns: The @nth SSRC of @packet.
 */
guint32
gst_rtcp_packet_bye_get_nth_ssrc (GstRTCPPacket * packet, guint nth)
{
  guint8 *data;
  guint offset;
  guint32 ssrc;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);
  g_return_val_if_fail (nth < packet->count, 0);

  /* get offset in 32-bits words into packet, skip the header */
  offset = 1 + nth;
  /* check that we don't go past the packet length */
  if (offset > packet->length)
    return 0;

  /* scale to bytes */
  offset <<= 2;
  offset += packet->offset;

  /* check if the packet is valid */
  if (offset + 4 > packet->rtcp->map.size)
    return 0;

  data = packet->rtcp->map.data;
  data += offset;

  ssrc = GST_READ_UINT32_BE (data);

  return ssrc;
}

/**
 * gst_rtcp_packet_bye_add_ssrc:
 * @packet: a valid BYE #GstRTCPPacket
 * @ssrc: an SSRC to add
 *
 * Add @ssrc to the BYE @packet.
 *
 * Returns: %TRUE if the ssrc was added. This function can return %FALSE if
 * the max MTU is exceeded or the number of sources blocks is greater than
 * #GST_RTCP_MAX_BYE_SSRC_COUNT.
 */
gboolean
gst_rtcp_packet_bye_add_ssrc (GstRTCPPacket * packet, guint32 ssrc)
{
  guint8 *data;
  gsize maxsize;
  guint offset;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  if (packet->count >= GST_RTCP_MAX_BYE_SSRC_COUNT)
    goto no_space;

  data = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.maxsize;

  /* skip header */
  offset = packet->offset + 4;

  /* move to current index */
  offset += (packet->count * 4);

  if (offset + 4 >= maxsize)
    goto no_space;

  /* increment packet count and length */
  packet->count++;
  data[packet->offset]++;
  packet->length += 1;
  data[packet->offset + 2] = (packet->length) >> 8;
  data[packet->offset + 3] = (packet->length) & 0xff;

  packet->rtcp->map.size += 4;

  /* move to new SSRC offset and write ssrc */
  data += offset;
  GST_WRITE_UINT32_BE (data, ssrc);

  return TRUE;

  /* ERRORS */
no_space:
  {
    return FALSE;
  }
}

/**
 * gst_rtcp_packet_bye_add_ssrcs:
 * @packet: a valid BYE #GstRTCPPacket
 * @ssrc: (array length=len) (transfer none): an array of SSRCs to add
 * @len: number of elements in @ssrc
 *
 * Adds @len SSRCs in @ssrc to BYE @packet.
 *
 * Returns: %TRUE if the all the SSRCs were added. This function can return %FALSE if
 * the max MTU is exceeded or the number of sources blocks is greater than
 * #GST_RTCP_MAX_BYE_SSRC_COUNT.
 */
gboolean
gst_rtcp_packet_bye_add_ssrcs (GstRTCPPacket * packet, guint32 * ssrc,
    guint len)
{
  guint i;
  gboolean res;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  res = TRUE;
  for (i = 0; i < len && res; i++) {
    res = gst_rtcp_packet_bye_add_ssrc (packet, ssrc[i]);
  }
  return res;
}

/* get the offset in packet of the reason length */
static guint
get_reason_offset (GstRTCPPacket * packet)
{
  guint offset;

  /* get amount of sources plus header */
  offset = 1 + packet->count;

  /* check that we don't go past the packet length */
  if (offset > packet->length)
    return 0;

  /* scale to bytes */
  offset <<= 2;
  offset += packet->offset;

  /* check if the packet is valid */
  if (offset + 1 > packet->rtcp->map.size)
    return 0;

  return offset;
}

/**
 * gst_rtcp_packet_bye_get_reason_len:
 * @packet: a valid BYE #GstRTCPPacket
 *
 * Get the length of the reason string.
 *
 * Returns: The length of the reason string or 0 when there is no reason string
 * present.
 */
guint8
gst_rtcp_packet_bye_get_reason_len (GstRTCPPacket * packet)
{
  guint8 *data;
  guint roffset;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  roffset = get_reason_offset (packet);
  if (roffset == 0)
    return 0;

  data = packet->rtcp->map.data;

  return data[roffset];
}

/**
 * gst_rtcp_packet_bye_get_reason:
 * @packet: a valid BYE #GstRTCPPacket
 *
 * Get the reason in @packet.
 *
 * Returns: The reason for the BYE @packet or NULL if the packet did not contain
 * a reason string. The string must be freed with g_free() after usage.
 */
gchar *
gst_rtcp_packet_bye_get_reason (GstRTCPPacket * packet)
{
  guint8 *data;
  guint roffset;
  guint8 len;

  g_return_val_if_fail (packet != NULL, NULL);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, NULL);
  g_return_val_if_fail (packet->rtcp != NULL, NULL);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, NULL);

  roffset = get_reason_offset (packet);
  if (roffset == 0)
    return NULL;

  data = packet->rtcp->map.data;

  /* get length of reason string */
  len = data[roffset];
  if (len == 0)
    return NULL;

  /* move to string */
  roffset += 1;

  /* check if enough data to copy */
  if (roffset + len > packet->rtcp->map.size)
    return NULL;

  return g_strndup ((gconstpointer) (data + roffset), len);
}

/**
 * gst_rtcp_packet_bye_set_reason:
 * @packet: a valid BYE #GstRTCPPacket
 * @reason: a reason string
 *
 * Set the reason string to @reason in @packet.
 *
 * Returns: TRUE if the string could be set.
 */
gboolean
gst_rtcp_packet_bye_set_reason (GstRTCPPacket * packet, const gchar * reason)
{
  guint8 *data;
  guint roffset;
  gsize maxsize;
  guint8 len, padded;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_BYE, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  if (reason == NULL)
    return TRUE;

  len = strlen (reason);
  if (len == 0)
    return TRUE;

  /* make room for the string before we get the offset */
  packet->length++;

  roffset = get_reason_offset (packet);
  if (roffset == 0)
    goto no_space;

  data = packet->rtcp->map.data;
  maxsize = packet->rtcp->map.maxsize;

  /* we have 1 byte length and we need to pad to 4 bytes */
  padded = ((len + 1) + 3) & ~3;

  /* we need enough space for the padded length */
  if (roffset + padded >= maxsize)
    goto no_space;

  data[roffset] = len;
  memcpy (&data[roffset + 1], reason, len);

  /* update packet length, we made room for 1 double word already */
  packet->length += (padded >> 2) - 1;
  data[packet->offset + 2] = (packet->length) >> 8;
  data[packet->offset + 3] = (packet->length) & 0xff;

  packet->rtcp->map.size += padded;

  return TRUE;

  /* ERRORS */
no_space:
  {
    packet->length--;
    return FALSE;
  }
}

/**
 * gst_rtcp_packet_fb_get_sender_ssrc:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 *
 * Get the sender SSRC field of the RTPFB or PSFB @packet.
 *
 * Returns: the sender SSRC.
 */
guint32
gst_rtcp_packet_fb_get_sender_ssrc (GstRTCPPacket * packet)
{
  guint8 *data;
  guint32 ssrc;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail ((packet->type == GST_RTCP_TYPE_RTPFB ||
          packet->type == GST_RTCP_TYPE_PSFB), 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data;

  /* skip header */
  data += packet->offset + 4;
  ssrc = GST_READ_UINT32_BE (data);

  return ssrc;
}

/**
 * gst_rtcp_packet_fb_set_sender_ssrc:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 * @ssrc: a sender SSRC
 *
 * Set the sender SSRC field of the RTPFB or PSFB @packet.
 */
void
gst_rtcp_packet_fb_set_sender_ssrc (GstRTCPPacket * packet, guint32 ssrc)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_READ);

  data = packet->rtcp->map.data;

  /* skip header */
  data += packet->offset + 4;
  GST_WRITE_UINT32_BE (data, ssrc);
}

/**
 * gst_rtcp_packet_fb_get_media_ssrc:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 *
 * Get the media SSRC field of the RTPFB or PSFB @packet.
 *
 * Returns: the media SSRC.
 */
guint32
gst_rtcp_packet_fb_get_media_ssrc (GstRTCPPacket * packet)
{
  guint8 *data;
  guint32 ssrc;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail ((packet->type == GST_RTCP_TYPE_RTPFB ||
          packet->type == GST_RTCP_TYPE_PSFB), 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data;

  /* skip header and sender ssrc */
  data += packet->offset + 8;
  ssrc = GST_READ_UINT32_BE (data);

  return ssrc;
}

/**
 * gst_rtcp_packet_fb_set_media_ssrc:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 * @ssrc: a media SSRC
 *
 * Set the media SSRC field of the RTPFB or PSFB @packet.
 */
void
gst_rtcp_packet_fb_set_media_ssrc (GstRTCPPacket * packet, guint32 ssrc)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data;

  /* skip header and sender ssrc */
  data += packet->offset + 8;
  GST_WRITE_UINT32_BE (data, ssrc);
}

/**
 * gst_rtcp_packet_fb_get_type:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 *
 * Get the feedback message type of the FB @packet.
 *
 * Returns: The feedback message type.
 */
GstRTCPFBType
gst_rtcp_packet_fb_get_type (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, GST_RTCP_FB_TYPE_INVALID);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB, GST_RTCP_FB_TYPE_INVALID);

  return packet->count;
}

/**
 * gst_rtcp_packet_fb_set_type:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 * @type: the #GstRTCPFBType to set
 *
 * Set the feedback message type of the FB @packet.
 */
void
gst_rtcp_packet_fb_set_type (GstRTCPPacket * packet, GstRTCPFBType type)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data;

  data[packet->offset] = (data[packet->offset] & 0xe0) | type;
  packet->count = type;
}

/**
 * gst_rtcp_ntp_to_unix:
 * @ntptime: an NTP timestamp
 *
 * Converts an NTP time to UNIX nanoseconds. @ntptime can typically be
 * the NTP time of an SR RTCP message and contains, in the upper 32 bits, the
 * number of seconds since 1900 and, in the lower 32 bits, the fractional
 * seconds. The resulting value will be the number of nanoseconds since 1970.
 *
 * Returns: the UNIX time for @ntptime in nanoseconds.
 */
guint64
gst_rtcp_ntp_to_unix (guint64 ntptime)
{
  guint64 unixtime;

  /* conversion from NTP timestamp (seconds since 1900) to seconds since
   * 1970. */
  unixtime = ntptime - (G_GUINT64_CONSTANT (2208988800) << 32);
  /* conversion to nanoseconds */
  unixtime =
      gst_util_uint64_scale (unixtime, GST_SECOND,
      (G_GINT64_CONSTANT (1) << 32));

  return unixtime;
}

/**
 * gst_rtcp_unix_to_ntp:
 * @unixtime: an UNIX timestamp in nanoseconds
 *
 * Converts a UNIX timestamp in nanoseconds to an NTP time. The caller should
 * pass a value with nanoseconds since 1970. The NTP time will, in the upper
 * 32 bits, contain the number of seconds since 1900 and, in the lower 32
 * bits, the fractional seconds. The resulting value can be used as an ntptime
 * for constructing SR RTCP packets.
 *
 * Returns: the NTP time for @unixtime.
 */
guint64
gst_rtcp_unix_to_ntp (guint64 unixtime)
{
  guint64 ntptime;

  /* convert clock time to NTP time. upper 32 bits should contain the seconds
   * and the lower 32 bits, the fractions of a second. */
  ntptime =
      gst_util_uint64_scale (unixtime, (G_GINT64_CONSTANT (1) << 32),
      GST_SECOND);
  /* conversion from UNIX timestamp (seconds since 1970) to NTP (seconds
   * since 1900). */
  ntptime += (G_GUINT64_CONSTANT (2208988800) << 32);

  return ntptime;
}

/**
 * gst_rtcp_sdes_type_to_name:
 * @type: a #GstRTCPSDESType
 *
 * Converts @type to the string equivalent. The string is typically used as a
 * key in a #GstStructure containing SDES items.
 *
 * Returns: the string equivalent of @type
 */
const gchar *
gst_rtcp_sdes_type_to_name (GstRTCPSDESType type)
{
  const gchar *result;

  switch (type) {
    case GST_RTCP_SDES_CNAME:
      result = "cname";
      break;
    case GST_RTCP_SDES_NAME:
      result = "name";
      break;
    case GST_RTCP_SDES_EMAIL:
      result = "email";
      break;
    case GST_RTCP_SDES_PHONE:
      result = "phone";
      break;
    case GST_RTCP_SDES_LOC:
      result = "location";
      break;
    case GST_RTCP_SDES_TOOL:
      result = "tool";
      break;
    case GST_RTCP_SDES_NOTE:
      result = "note";
      break;
    case GST_RTCP_SDES_PRIV:
      result = "priv";
      break;
    default:
      result = NULL;
      break;
  }
  return result;
}

/**
 * gst_rtcp_sdes_name_to_type:
 * @name: a SDES name
 *
 * Convert @name into a @GstRTCPSDESType. @name is typically a key in a
 * #GstStructure containing SDES items.
 *
 * Returns: the #GstRTCPSDESType for @name or #GST_RTCP_SDES_PRIV when @name
 * is a private sdes item.
 */
GstRTCPSDESType
gst_rtcp_sdes_name_to_type (const gchar * name)
{
  if (name == NULL || strlen (name) == 0)
    return GST_RTCP_SDES_INVALID;

  if (strcmp ("cname", name) == 0)
    return GST_RTCP_SDES_CNAME;

  if (strcmp ("name", name) == 0)
    return GST_RTCP_SDES_NAME;

  if (strcmp ("email", name) == 0)
    return GST_RTCP_SDES_EMAIL;

  if (strcmp ("phone", name) == 0)
    return GST_RTCP_SDES_PHONE;

  if (strcmp ("location", name) == 0)
    return GST_RTCP_SDES_LOC;

  if (strcmp ("tool", name) == 0)
    return GST_RTCP_SDES_TOOL;

  if (strcmp ("note", name) == 0)
    return GST_RTCP_SDES_NOTE;

  return GST_RTCP_SDES_PRIV;
}

/**
 * gst_rtcp_packet_fb_get_fci_length:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 *
 * Get the length of the Feedback Control Information attached to a
 * RTPFB or PSFB @packet.
 *
 * Returns: The length of the FCI in 32-bit words.
 */
guint16
gst_rtcp_packet_fb_get_fci_length (GstRTCPPacket * packet)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data + packet->offset + 2;

  return GST_READ_UINT16_BE (data) - 2;
}

/**
 * gst_rtcp_packet_fb_set_fci_length:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 * @wordlen: Length of the FCI in 32-bit words
 *
 * Set the length of the Feedback Control Information attached to a
 * RTPFB or PSFB @packet.
 *
 * Returns: %TRUE if there was enough space in the packet to add this much FCI
 */
gboolean
gst_rtcp_packet_fb_set_fci_length (GstRTCPPacket * packet, guint16 wordlen)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  if (packet->rtcp->map.maxsize < packet->offset + ((wordlen + 3) * 4))
    return FALSE;

  data = packet->rtcp->map.data + packet->offset + 2;
  wordlen += 2;
  GST_WRITE_UINT16_BE (data, wordlen);

  packet->rtcp->map.size = packet->offset + ((wordlen + 1) * 4);

  return TRUE;
}

/**
 * gst_rtcp_packet_fb_get_fci:
 * @packet: a valid RTPFB or PSFB #GstRTCPPacket
 *
 * Get the Feedback Control Information attached to a RTPFB or PSFB @packet.
 *
 * Returns: a pointer to the FCI
 */
guint8 *
gst_rtcp_packet_fb_get_fci (GstRTCPPacket * packet)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, NULL);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_RTPFB ||
      packet->type == GST_RTCP_TYPE_PSFB, NULL);
  g_return_val_if_fail (packet->rtcp != NULL, NULL);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, NULL);

  data = packet->rtcp->map.data + packet->offset;

  if (GST_READ_UINT16_BE (data + 2) <= 2)
    return NULL;

  return data + 12;
}

/**
 * gst_rtcp_packet_app_set_subtype:
 * @packet: a valid APP #GstRTCPPacket
 * @subtype: subtype of the packet
 *
 * Set the subtype field of the APP @packet.
 *
 * Since: 1.10
 **/
void
gst_rtcp_packet_app_set_subtype (GstRTCPPacket * packet, guint8 subtype)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_APP);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data + packet->offset;
  data[0] = (data[0] & 0xe0) | subtype;
}

/**
 * gst_rtcp_packet_app_get_subtype:
 * @packet: a valid APP #GstRTCPPacket
 *
 * Get the subtype field of the APP @packet.
 *
 * Returns: The subtype.
 *
 * Since: 1.10
 */
guint8
gst_rtcp_packet_app_get_subtype (GstRTCPPacket * packet)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data + packet->offset;

  return data[0] & 0x1f;
}

/**
 * gst_rtcp_packet_app_set_ssrc:
 * @packet: a valid APP #GstRTCPPacket
 * @ssrc: SSRC/CSRC of the packet
 *
 * Set the SSRC/CSRC field of the APP @packet.
 *
 * Since: 1.10
 */
void
gst_rtcp_packet_app_set_ssrc (GstRTCPPacket * packet, guint32 ssrc)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_APP);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data + packet->offset + 4;
  GST_WRITE_UINT32_BE (data, ssrc);
}

/**
 * gst_rtcp_packet_app_get_ssrc:
 * @packet: a valid APP #GstRTCPPacket
 *
 * Get the SSRC/CSRC field of the APP @packet.
 *
 * Returns: The SSRC/CSRC.
 *
 * Since: 1.10
 */
guint32
gst_rtcp_packet_app_get_ssrc (GstRTCPPacket * packet)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data + packet->offset + 4;

  return GST_READ_UINT32_BE (data);
}

/**
 * gst_rtcp_packet_app_set_name:
 * @packet: a valid APP #GstRTCPPacket
 * @name: 4-byte ASCII name
 *
 * Set the name field of the APP @packet.
 *
 * Since: 1.10
 */
void
gst_rtcp_packet_app_set_name (GstRTCPPacket * packet, const gchar * name)
{
  guint8 *data;

  g_return_if_fail (packet != NULL);
  g_return_if_fail (packet->type == GST_RTCP_TYPE_APP);
  g_return_if_fail (packet->rtcp != NULL);
  g_return_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE);

  data = packet->rtcp->map.data + packet->offset + 8;
  memcpy (data, name, 4);
}

/**
 * gst_rtcp_packet_app_get_name:
 * @packet: a valid APP #GstRTCPPacket
 *
 * Get the name field of the APP @packet.
 *
 * Returns: The 4-byte name field, not zero-terminated.
 *
 * Since: 1.10
 */
const gchar *
gst_rtcp_packet_app_get_name (GstRTCPPacket * packet)
{
  g_return_val_if_fail (packet != NULL, NULL);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, NULL);
  g_return_val_if_fail (packet->rtcp != NULL, NULL);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, NULL);

  return (const gchar *) &packet->rtcp->map.data[packet->offset + 8];
}

/**
 * gst_rtcp_packet_app_get_data_length:
 * @packet: a valid APP #GstRTCPPacket
 *
 * Get the length of the application-dependent data attached to an APP
 * @packet.
 *
 * Returns: The length of data in 32-bit words.
 *
 * Since: 1.10
 */
guint16
gst_rtcp_packet_app_get_data_length (GstRTCPPacket * packet)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, 0);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, 0);
  g_return_val_if_fail (packet->rtcp != NULL, 0);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, 0);

  data = packet->rtcp->map.data + packet->offset + 2;

  return GST_READ_UINT16_BE (data) - 2;
}

/**
 * gst_rtcp_packet_app_set_data_length:
 * @packet: a valid APP #GstRTCPPacket
 * @wordlen: Length of the data in 32-bit words
 *
 * Set the length of the application-dependent data attached to an APP
 * @packet.
 *
 * Returns: %TRUE if there was enough space in the packet to add this much
 * data.
 *
 * Since: 1.10
 */
gboolean
gst_rtcp_packet_app_set_data_length (GstRTCPPacket * packet, guint16 wordlen)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, FALSE);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, FALSE);
  g_return_val_if_fail (packet->rtcp != NULL, FALSE);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_WRITE, FALSE);

  if (packet->rtcp->map.maxsize < packet->offset + ((wordlen + 3) * 4))
    return FALSE;

  data = packet->rtcp->map.data + packet->offset + 2;
  wordlen += 2;
  GST_WRITE_UINT16_BE (data, wordlen);

  packet->rtcp->map.size = packet->offset + ((wordlen + 1) * 4);

  return TRUE;
}

/**
 * gst_rtcp_packet_app_get_data:
 * @packet: a valid APP #GstRTCPPacket
 *
 * Get the application-dependent data attached to a RTPFB or PSFB @packet.
 *
 * Returns: A pointer to the data
 *
 * Since: 1.10
 */
guint8 *
gst_rtcp_packet_app_get_data (GstRTCPPacket * packet)
{
  guint8 *data;

  g_return_val_if_fail (packet != NULL, NULL);
  g_return_val_if_fail (packet->type == GST_RTCP_TYPE_APP, NULL);
  g_return_val_if_fail (packet->rtcp != NULL, NULL);
  g_return_val_if_fail (packet->rtcp->map.flags & GST_MAP_READ, NULL);

  data = packet->rtcp->map.data + packet->offset;

  if (GST_READ_UINT16_BE (data + 2) <= 2)
    return NULL;

  return data + 12;
}
