summaryrefslogtreecommitdiff
path: root/gst-libs/gst/rtp/gstrtcpbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst/rtp/gstrtcpbuffer.c')
-rw-r--r--gst-libs/gst/rtp/gstrtcpbuffer.c1945
1 files changed, 0 insertions, 1945 deletions
diff --git a/gst-libs/gst/rtp/gstrtcpbuffer.c b/gst-libs/gst/rtp/gstrtcpbuffer.c
deleted file mode 100644
index 9177b398..00000000
--- a/gst-libs/gst/rtp/gstrtcpbuffer.c
+++ /dev/null
@@ -1,1945 +0,0 @@
-/* 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., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:gstrtcpbuffer
- * @short_description: Helper methods for dealing with RTCP buffers
- * @see_also: #GstBaseRTPPayload, #GstBaseRTPDepayload, #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>
- *
- * Last reviewed on 2007-03-26 (0.10.13)
- *
- * Since: 0.10.13
- */
-
-#include <string.h>
-
-#include "gstrtcpbuffer.h"
-
-/**
- * gst_rtcp_buffer_new_take_data:
- * @data: 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 ();
-
- GST_BUFFER_MALLOCDATA (result) = data;
- GST_BUFFER_DATA (result) = data;
- GST_BUFFER_SIZE (result) = len;
-
- return result;
-}
-
-/**
- * gst_rtcp_buffer_new_copy_data:
- * @data: 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);
-}
-
-/**
- * gst_rtcp_buffer_validate_data:
- * @data: 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 (compound)
- * 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)
-{
- guint16 header_mask;
- guint16 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]) & GST_RTCP_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;
-
- /* check version of new packet */
- version = data[0] & 0xc0;
- if (version != (GST_RTCP_VERSION << 6))
- goto wrong_version;
-
- /* padding only allowed on last packet */
- if ((padding = data[0] & 0x20))
- break;
- }
- if (data_len > 0) {
- /* some leftover bytes, check padding */
- if (!padding)
- goto wrong_length;
-
- /* get padding */
- pad_bytes = data[len - 1];
- if (data_len != pad_bytes)
- goto wrong_padding;
- }
- return TRUE;
-
- /* ERRORS */
-wrong_length:
- {
- GST_DEBUG ("len check failed");
- return FALSE;
- }
-wrong_mask:
- {
- GST_DEBUG ("mask check failed (%04x != %04x)", header_mask,
- GST_RTCP_VALID_VALUE);
- 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:
- * @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)
-{
- guint8 *data;
- guint len;
-
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
-
- data = GST_BUFFER_DATA (buffer);
- len = GST_BUFFER_SIZE (buffer);
-
- return gst_rtcp_buffer_validate_data (data, len);
-}
-
-/**
- * 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;
-
- g_return_val_if_fail (mtu > 0, NULL);
-
- result = gst_buffer_new ();
- GST_BUFFER_MALLOCDATA (result) = g_malloc0 (mtu);
- GST_BUFFER_DATA (result) = GST_BUFFER_MALLOCDATA (result);
- GST_BUFFER_SIZE (result) = mtu;
-
- return result;
-}
-
-/**
- * gst_rtcp_buffer_end:
- * @buffer: a buffer with an RTCP packet
- *
- * Finish @buffer after being constructured. This function is usually called
- * after gst_rtcp_buffer_new() and after adding the RTCP items to the new buffer.
- *
- * The function adjusts the size of @buffer with the total length of all the
- * added packets.
- */
-void
-gst_rtcp_buffer_end (GstBuffer * buffer)
-{
- GstRTCPPacket packet;
-
- g_return_if_fail (GST_IS_BUFFER (buffer));
-
- /* move to the first free space */
- if (gst_rtcp_buffer_get_first_packet (buffer, &packet))
- while (gst_rtcp_packet_move_to_next (&packet));
-
- /* shrink size */
- GST_BUFFER_SIZE (buffer) = packet.offset;
-}
-
-/**
- * gst_rtcp_buffer_get_packet_count:
- * @buffer: a valid RTCP buffer
- *
- * Get the number of RTCP packets in @buffer.
- *
- * Returns: the number of RTCP packets in @buffer.
- */
-guint
-gst_rtcp_buffer_get_packet_count (GstBuffer * buffer)
-{
- GstRTCPPacket packet;
- guint count;
-
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
-
- count = 0;
- if (gst_rtcp_buffer_get_first_packet (buffer, &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;
- guint size;
- guint offset;
-
- g_return_val_if_fail (packet != NULL, FALSE);
- g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), FALSE);
-
- data = GST_BUFFER_DATA (packet->buffer);
- size = GST_BUFFER_SIZE (packet->buffer);
-
- 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 > size)
- 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;
-
- return TRUE;
-}
-
-/**
- * gst_rtcp_buffer_get_first_packet:
- * @buffer: a valid RTCP buffer
- * @packet: a #GstRTCPPacket
- *
- * Initialize a new #GstRTCPPacket pointer that points to the first packet in
- * @buffer.
- *
- * Returns: TRUE if the packet existed in @buffer.
- */
-gboolean
-gst_rtcp_buffer_get_first_packet (GstBuffer * buffer, GstRTCPPacket * packet)
-{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (packet != NULL, FALSE);
-
- /* init to 0 */
- packet->buffer = buffer;
- 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 (GST_IS_BUFFER (packet->buffer), 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:
- * @buffer: a valid RTCP buffer
- * @type: the #GstRTCPType of the new packet
- * @packet: pointer to new packet
- *
- * Add a new packet of @type to @buffer. @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 (GstBuffer * buffer, GstRTCPType type,
- GstRTCPPacket * packet)
-{
- guint len, size;
- guint8 *data;
- gboolean result;
-
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (type != GST_RTCP_TYPE_INVALID, FALSE);
- g_return_val_if_fail (packet != NULL, FALSE);
-
- /* find free space */
- if (gst_rtcp_buffer_get_first_packet (buffer, packet))
- while (gst_rtcp_packet_move_to_next (packet));
-
- size = GST_BUFFER_SIZE (buffer);
-
- /* 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 >= size)
- goto no_space;
-
- data = GST_BUFFER_DATA (buffer) + 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);
-
- /* 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 (GST_BUFFER_DATA (packet->buffer) + packet->offset,
- GST_BUFFER_DATA (packet->buffer) + offset,
- GST_BUFFER_SIZE (packet->buffer) - 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 octect 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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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 octect 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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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 (GST_IS_BUFFER (packet->buffer), 0);
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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 (GST_IS_BUFFER (packet->buffer), 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)
-{
- 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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* skip header */
- data += packet->offset + 4;
- if (packet->type == GST_RTCP_TYPE_RR)
- data += 4;
- else
- data += 24;
-
- /* move to requested index */
- data += (nth * 24);
-
- 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 size, 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- if (packet->count >= GST_RTCP_MAX_RB_COUNT)
- goto no_space;
-
- data = GST_BUFFER_DATA (packet->buffer);
- size = GST_BUFFER_SIZE (packet->buffer);
-
- /* 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 >= size)
- 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;
-
- /* 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 (GST_IS_BUFFER (packet->buffer));
-
- 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);
- g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 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);
- g_return_val_if_fail (GST_IS_BUFFER (packet->buffer), 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- /* if we are at the last item, we are done */
- if (packet->item_count == packet->count)
- return FALSE;
-
- /* move to SDES */
- data = GST_BUFFER_DATA (packet->buffer);
- 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 + 3) & ~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 (GST_IS_BUFFER (packet->buffer), 0);
-
- /* move to SDES */
- data = GST_BUFFER_DATA (packet->buffer);
- 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- /* move to SDES */
- data = GST_BUFFER_DATA (packet->buffer);
- 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- /* move to SDES */
- data = GST_BUFFER_DATA (packet->buffer);
- 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: result length of the entry data
- * @data: 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-termined 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- /* move to SDES */
- bdata = GST_BUFFER_DATA (packet->buffer);
- 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: result length of the entry data
- * @data: 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 (GST_IS_BUFFER (packet->buffer), 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, size;
-
- 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 (GST_IS_BUFFER (packet->buffer), 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 = GST_BUFFER_DATA (packet->buffer);
- size = GST_BUFFER_SIZE (packet->buffer);
- data += packet->offset;
- /* move to current item */
- offset = packet->item_offset;
-
- /* we need 2 free words now */
- if (offset + 8 >= size)
- 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;
-
- 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: 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, size, padded;
-
- 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- /* move to SDES */
- bdata = GST_BUFFER_DATA (packet->buffer);
- size = GST_BUFFER_SIZE (packet->buffer);
- 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 >= size)
- goto no_space;
-
- 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;
- guint8 sc;
-
- 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 (GST_IS_BUFFER (packet->buffer), 0);
-
- /* get amount of sources and check that we don't read too much */
- sc = packet->count;
- if (nth >= sc)
- return 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 > GST_BUFFER_SIZE (packet->buffer))
- return 0;
-
- data = GST_BUFFER_DATA (packet->buffer);
- 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;
- guint size, 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 (GST_IS_BUFFER (packet->buffer), FALSE);
-
- if (packet->count >= GST_RTCP_MAX_BYE_SSRC_COUNT)
- goto no_space;
-
- data = GST_BUFFER_DATA (packet->buffer);
- size = GST_BUFFER_SIZE (packet->buffer);
-
- /* skip header */
- offset = packet->offset + 4;
-
- /* move to current index */
- offset += (packet->count * 4);
-
- if (offset + 4 >= size)
- 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;
-
- /* 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 (GST_IS_BUFFER (packet->buffer), 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 > GST_BUFFER_SIZE (packet->buffer))
- 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 (GST_IS_BUFFER (packet->buffer), 0);
-
- roffset = get_reason_offset (packet);
- if (roffset == 0)
- return 0;
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- 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 (GST_IS_BUFFER (packet->buffer), NULL);
-
- roffset = get_reason_offset (packet);
- if (roffset == 0)
- return NULL;
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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 > GST_BUFFER_SIZE (packet->buffer))
- 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, size;
- 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 (GST_IS_BUFFER (packet->buffer), 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 = GST_BUFFER_DATA (packet->buffer);
- size = GST_BUFFER_SIZE (packet->buffer);
-
- /* 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 >= size)
- 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;
-
- 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.
- *
- * Since: 0.10.23
- */
-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 (GST_IS_BUFFER (packet->buffer), 0);
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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.
- *
- * Since: 0.10.23
- */
-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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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.
- *
- * Since: 0.10.23
- */
-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 (GST_IS_BUFFER (packet->buffer), 0);
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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.
- *
- * Since: 0.10.23
- */
-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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- /* 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.
- *
- * Since: 0.10.23
- */
-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.
- *
- * Since: 0.10.23
- */
-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 (GST_IS_BUFFER (packet->buffer));
-
- data = GST_BUFFER_DATA (packet->buffer);
-
- 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
- *
- * Since: 0.10.26
- */
-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.
- *
- * Since: 0.10.26
- */
-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;
-}