/* 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
 * @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.
 *
 * <refsect2>
 * <para>
 * 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.
 * </para>
 * <para>
 * 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().
 * </para>
 * </refsect2>
 */

#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 (gpointer 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;
    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: result SSRC
 * @ntptime: result NTP time
 * @rtptime: result RTP time
 * @packet_count: result packet count
 * @octet_count: 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: result for data source being reported
 * @fractionlost: result for fraction lost since last SR/RR
 * @packetslost: result for the cumululative number of packets lost
 * @exthighestseq: result for the extended last sequence number received
 * @jitter: result for the interarrival jitter
 * @lsr: result for the last SR packet from this source
 * @dlsr: 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 (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, (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_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: 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;
}
