summaryrefslogtreecommitdiff
path: root/gst-libs/gst/rtp/gstrtpbuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst-libs/gst/rtp/gstrtpbuffer.c')
-rw-r--r--gst-libs/gst/rtp/gstrtpbuffer.c1388
1 files changed, 0 insertions, 1388 deletions
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c
deleted file mode 100644
index b050b080..00000000
--- a/gst-libs/gst/rtp/gstrtpbuffer.c
+++ /dev/null
@@ -1,1388 +0,0 @@
-/* GStreamer
- * Copyright (C) <2005> Philippe Khalaf <burger@speedy.org>
- * Copyright (C) <2006> Wim Taymans <wim@fluendo.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:gstrtpbuffer
- * @short_description: Helper methods for dealing with RTP buffers
- * @see_also: #GstBaseRTPPayload, #GstBaseRTPDepayload, gstrtcpbuffer
- *
- * <refsect2>
- * <para>
- * The GstRTPBuffer helper functions makes it easy to parse and create regular
- * #GstBuffer objects that contain RTP payloads. These buffers are typically of
- * 'application/x-rtp' #GstCaps.
- * </para>
- * </refsect2>
- *
- * Last reviewed on 2006-07-17 (0.10.10)
- */
-
-#include "gstrtpbuffer.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-#define GST_RTP_HEADER_LEN 12
-
-/* Note: we use bitfields here to make sure the compiler doesn't add padding
- * between fields on certain architectures; can't assume aligned access either
- */
-typedef struct _GstRTPHeader
-{
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- unsigned int csrc_count:4; /* CSRC count */
- unsigned int extension:1; /* header extension flag */
- unsigned int padding:1; /* padding flag */
- unsigned int version:2; /* protocol version */
- unsigned int payload_type:7; /* payload type */
- unsigned int marker:1; /* marker bit */
-#elif G_BYTE_ORDER == G_BIG_ENDIAN
- unsigned int version:2; /* protocol version */
- unsigned int padding:1; /* padding flag */
- unsigned int extension:1; /* header extension flag */
- unsigned int csrc_count:4; /* CSRC count */
- unsigned int marker:1; /* marker bit */
- unsigned int payload_type:7; /* payload type */
-#else
-#error "G_BYTE_ORDER should be big or little endian."
-#endif
- unsigned int seq:16; /* sequence number */
- unsigned int timestamp:32; /* timestamp */
- unsigned int ssrc:32; /* synchronization source */
- guint8 csrclist[4]; /* optional CSRC list, 32 bits each */
-} GstRTPHeader;
-
-#define GST_RTP_HEADER_VERSION(data) (((GstRTPHeader *)(data))->version)
-#define GST_RTP_HEADER_PADDING(data) (((GstRTPHeader *)(data))->padding)
-#define GST_RTP_HEADER_EXTENSION(data) (((GstRTPHeader *)(data))->extension)
-#define GST_RTP_HEADER_CSRC_COUNT(data) (((GstRTPHeader *)(data))->csrc_count)
-#define GST_RTP_HEADER_MARKER(data) (((GstRTPHeader *)(data))->marker)
-#define GST_RTP_HEADER_PAYLOAD_TYPE(data) (((GstRTPHeader *)(data))->payload_type)
-#define GST_RTP_HEADER_SEQ(data) (((GstRTPHeader *)(data))->seq)
-#define GST_RTP_HEADER_TIMESTAMP(data) (((GstRTPHeader *)(data))->timestamp)
-#define GST_RTP_HEADER_SSRC(data) (((GstRTPHeader *)(data))->ssrc)
-#define GST_RTP_HEADER_CSRC_LIST_OFFSET(data,i) \
- data + G_STRUCT_OFFSET(GstRTPHeader, csrclist) + \
- ((i) * sizeof(guint32))
-#define GST_RTP_HEADER_CSRC_SIZE(data) (GST_RTP_HEADER_CSRC_COUNT(data) * sizeof (guint32))
-
-/**
- * gst_rtp_buffer_allocate_data:
- * @buffer: a #GstBuffer
- * @payload_len: the length of the payload
- * @pad_len: the amount of padding
- * @csrc_count: the number of CSRC entries
- *
- * Allocate enough data in @buffer to hold an RTP packet with @csrc_count CSRCs,
- * a payload length of @payload_len and padding of @pad_len.
- * MALLOCDATA of @buffer will be overwritten and will not be freed.
- * All other RTP header fields will be set to 0/FALSE.
- */
-void
-gst_rtp_buffer_allocate_data (GstBuffer * buffer, guint payload_len,
- guint8 pad_len, guint8 csrc_count)
-{
- guint len;
- guint8 *data;
-
- g_return_if_fail (csrc_count <= 15);
- g_return_if_fail (GST_IS_BUFFER (buffer));
-
- len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
- + payload_len + pad_len;
-
- data = g_malloc (len);
- GST_BUFFER_MALLOCDATA (buffer) = data;
- GST_BUFFER_DATA (buffer) = data;
- GST_BUFFER_SIZE (buffer) = len;
-
- /* fill in defaults */
- GST_RTP_HEADER_VERSION (data) = GST_RTP_VERSION;
- GST_RTP_HEADER_PADDING (data) = FALSE;
- GST_RTP_HEADER_EXTENSION (data) = FALSE;
- GST_RTP_HEADER_CSRC_COUNT (data) = csrc_count;
- memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, 0), 0,
- csrc_count * sizeof (guint32));
- GST_RTP_HEADER_MARKER (data) = FALSE;
- GST_RTP_HEADER_PAYLOAD_TYPE (data) = 0;
- GST_RTP_HEADER_SEQ (data) = 0;
- GST_RTP_HEADER_TIMESTAMP (data) = 0;
- GST_RTP_HEADER_SSRC (data) = 0;
-}
-
-/**
- * gst_rtp_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_rtp_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_rtp_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_rtp_buffer_new_copy_data (gpointer data, guint len)
-{
- return gst_rtp_buffer_new_take_data (g_memdup (data, len), len);
-}
-
-/**
- * gst_rtp_buffer_new_allocate:
- * @payload_len: the length of the payload
- * @pad_len: the amount of padding
- * @csrc_count: the number of CSRC entries
- *
- * Allocate a new #Gstbuffer with enough data to hold an RTP packet with @csrc_count CSRCs,
- * a payload length of @payload_len and padding of @pad_len.
- * All other RTP header fields will be set to 0/FALSE.
- *
- * Returns: A newly allocated buffer that can hold an RTP packet with given
- * parameters.
- */
-GstBuffer *
-gst_rtp_buffer_new_allocate (guint payload_len, guint8 pad_len,
- guint8 csrc_count)
-{
- GstBuffer *result;
-
- g_return_val_if_fail (csrc_count <= 15, NULL);
-
- result = gst_buffer_new ();
- gst_rtp_buffer_allocate_data (result, payload_len, pad_len, csrc_count);
-
- return result;
-}
-
-/**
- * gst_rtp_buffer_new_allocate_len:
- * @packet_len: the total length of the packet
- * @pad_len: the amount of padding
- * @csrc_count: the number of CSRC entries
- *
- * Create a new #GstBuffer that can hold an RTP packet that is exactly
- * @packet_len long. The length of the payload depends on @pad_len and
- * @csrc_count and can be calculated with gst_rtp_buffer_calc_payload_len().
- * All RTP header fields will be set to 0/FALSE.
- *
- * Returns: A newly allocated buffer that can hold an RTP packet of @packet_len.
- */
-GstBuffer *
-gst_rtp_buffer_new_allocate_len (guint packet_len, guint8 pad_len,
- guint8 csrc_count)
-{
- guint len;
-
- g_return_val_if_fail (csrc_count <= 15, NULL);
-
- len = gst_rtp_buffer_calc_payload_len (packet_len, pad_len, csrc_count);
-
- return gst_rtp_buffer_new_allocate (len, pad_len, csrc_count);
-}
-
-/**
- * gst_rtp_buffer_calc_header_len:
- * @csrc_count: the number of CSRC entries
- *
- * Calculate the header length of an RTP packet with @csrc_count CSRC entries.
- * An RTP packet can have at most 15 CSRC entries.
- *
- * Returns: The length of an RTP header with @csrc_count CSRC entries.
- */
-guint
-gst_rtp_buffer_calc_header_len (guint8 csrc_count)
-{
- g_return_val_if_fail (csrc_count <= 15, 0);
-
- return GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32));
-}
-
-/**
- * gst_rtp_buffer_calc_packet_len:
- * @payload_len: the length of the payload
- * @pad_len: the amount of padding
- * @csrc_count: the number of CSRC entries
- *
- * Calculate the total length of an RTP packet with a payload size of @payload_len,
- * a padding of @pad_len and a @csrc_count CSRC entries.
- *
- * Returns: The total length of an RTP header with given parameters.
- */
-guint
-gst_rtp_buffer_calc_packet_len (guint payload_len, guint8 pad_len,
- guint8 csrc_count)
-{
- g_return_val_if_fail (csrc_count <= 15, 0);
-
- return payload_len + GST_RTP_HEADER_LEN + (csrc_count * sizeof (guint32))
- + pad_len;
-}
-
-/**
- * gst_rtp_buffer_calc_payload_len:
- * @packet_len: the length of the total RTP packet
- * @pad_len: the amount of padding
- * @csrc_count: the number of CSRC entries
- *
- * Calculate the length of the payload of an RTP packet with size @packet_len,
- * a padding of @pad_len and a @csrc_count CSRC entries.
- *
- * Returns: The length of the payload of an RTP packet with given parameters.
- */
-guint
-gst_rtp_buffer_calc_payload_len (guint packet_len, guint8 pad_len,
- guint8 csrc_count)
-{
- g_return_val_if_fail (csrc_count <= 15, 0);
-
- return packet_len - GST_RTP_HEADER_LEN - (csrc_count * sizeof (guint32))
- - pad_len;
-}
-
-/**
- * validate_data:
- * @data: the data to validate
- * @len: the length of @data to validate
- * @payload: the payload if @data represents the header only
- * @payload_len: the len of the payload
- *
- * Checks if @data is a valid RTP packet.
- *
- * Returns: TRUE if @data is a valid RTP packet
- */
-static gboolean
-validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len)
-{
- guint8 padding;
- guint8 csrc_count;
- guint header_len;
- guint8 version;
-
- g_return_val_if_fail (data != NULL, FALSE);
-
- header_len = GST_RTP_HEADER_LEN;
- if (G_UNLIKELY (len < header_len))
- goto wrong_length;
-
- /* check version */
- version = (data[0] & 0xc0);
- if (G_UNLIKELY (version != (GST_RTP_VERSION << 6)))
- goto wrong_version;
-
- /* calc header length with csrc */
- csrc_count = (data[0] & 0x0f);
- header_len += csrc_count * sizeof (guint32);
-
- /* calc extension length when present. */
- if (data[0] & 0x10) {
- guint8 *extpos;
- guint16 extlen;
-
- /* this points to the extenstion bits and header length */
- extpos = &data[header_len];
-
- /* skip the header and check that we have enough space */
- header_len += 4;
- if (G_UNLIKELY (len < header_len))
- goto wrong_length;
-
- /* skip id */
- extpos += 2;
- /* read length as the number of 32 bits words */
- extlen = GST_READ_UINT16_BE (extpos);
-
- header_len += extlen * sizeof (guint32);
- }
-
- /* check for padding */
- if (data[0] & 0x20) {
- if (payload)
- padding = payload[payload_len - 1];
- else
- padding = data[len - 1];
- } else {
- padding = 0;
- }
-
- /* check if padding and header not bigger than packet length */
- if (G_UNLIKELY (len < padding + header_len))
- goto wrong_padding;
-
- return TRUE;
-
- /* ERRORS */
-wrong_length:
- {
- GST_DEBUG ("len < header_len check failed (%d < %d)", len, header_len);
- goto dump_packet;
- }
-wrong_version:
- {
- GST_DEBUG ("version check failed (%d != %d)", version, GST_RTP_VERSION);
- goto dump_packet;
- }
-wrong_padding:
- {
- GST_DEBUG ("padding check failed (%d - %d < %d)", len, header_len, padding);
- goto dump_packet;
- }
-dump_packet:
- {
- GST_MEMDUMP ("buffer", data, len);
- return FALSE;
- }
-}
-
-/**
- * gst_rtp_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 RTP packet.
- * This function checks the length, version and padding of the packet data.
- * Use this function to validate a packet before using the other functions in
- * this module.
- *
- * Returns: TRUE if the data points to a valid RTP packet.
- */
-gboolean
-gst_rtp_buffer_validate_data (guint8 * data, guint len)
-{
- return validate_data (data, len, NULL, 0);
-}
-
-/**
- * gst_rtp_buffer_validate:
- * @buffer: the buffer to validate
- *
- * Check if the data pointed to by @buffer is a valid RTP packet using
- * validate_data().
- * Use this function to validate a packet before using the other functions in
- * this module.
- *
- * Returns: TRUE if @buffer is a valid RTP packet.
- */
-gboolean
-gst_rtp_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 validate_data (data, len, NULL, 0);
-}
-
-/**
- * gst_rtp_buffer_list_validate:
- * @list: the buffer list to validate
- *
- * Check if all RTP packets in the @list are valid using validate_data().
- * Use this function to validate an list before using the other functions in
- * this module.
- *
- * Returns: TRUE if @list consists only of valid RTP packets.
- *
- * Since: 0.10.24
- */
-gboolean
-gst_rtp_buffer_list_validate (GstBufferList * list)
-{
- guint16 prev_seqnum = 0;
- GstBufferListIterator *it;
- guint i = 0;
-
- g_return_val_if_fail (GST_IS_BUFFER_LIST (list), FALSE);
-
- it = gst_buffer_list_iterate (list);
- g_return_val_if_fail (it != NULL, FALSE);
-
- /* iterate through all the RTP packets in the list */
- while (gst_buffer_list_iterator_next_group (it)) {
- GstBuffer *rtpbuf;
- GstBuffer *paybuf;
- guint8 *packet_header;
- guint8 *packet_payload;
- guint payload_size;
- guint packet_size;
-
- /* each group should consists of 2 buffers: one containing the RTP header
- * and the other one the payload, FIXME, relax the requirement of only one
- * payload buffer. */
- if (gst_buffer_list_iterator_n_buffers (it) != 2)
- goto invalid_list;
-
- /* get the RTP header */
- rtpbuf = gst_buffer_list_iterator_next (it);
- packet_header = GST_BUFFER_DATA (rtpbuf);
- if (packet_header == NULL)
- goto invalid_list;
-
- /* get the payload */
- paybuf = gst_buffer_list_iterator_next (it);
- packet_payload = GST_BUFFER_DATA (paybuf);
- if (packet_payload == NULL) {
- goto invalid_list;
- }
- payload_size = GST_BUFFER_SIZE (paybuf);
- if (payload_size == 0) {
- goto invalid_list;
- }
-
- /* the size of the RTP packet within the current group */
- packet_size = GST_BUFFER_SIZE (rtpbuf) + payload_size;
-
- /* check the sequence number */
- if (G_UNLIKELY (i == 0)) {
- prev_seqnum = g_ntohs (GST_RTP_HEADER_SEQ (packet_header));
- i++;
- } else {
- if (++prev_seqnum != g_ntohs (GST_RTP_HEADER_SEQ (packet_header)))
- goto invalid_list;
- }
-
- /* validate packet */
- if (!validate_data (packet_header, packet_size, packet_payload,
- payload_size)) {
- goto invalid_list;
- }
- }
-
- gst_buffer_list_iterator_free (it);
-
- return TRUE;
-
- /* ERRORS */
-invalid_list:
- {
- gst_buffer_list_iterator_free (it);
- return FALSE;
- }
-}
-
-/**
- * gst_rtp_buffer_set_packet_len:
- * @buffer: the buffer
- * @len: the new packet length
- *
- * Set the total @buffer size to @len. The data in the buffer will be made
- * larger if needed. Any padding will be removed from the packet.
- */
-void
-gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
-{
- guint oldlen;
- guint8 *data;
-
- oldlen = GST_BUFFER_SIZE (buffer);
- data = GST_BUFFER_DATA (buffer);
-
- if (oldlen < len) {
- data = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
- GST_BUFFER_MALLOCDATA (buffer) = data;
- GST_BUFFER_DATA (buffer) = data;
- }
- GST_BUFFER_SIZE (buffer) = len;
-
- /* remove any padding */
- GST_RTP_HEADER_PADDING (data) = FALSE;
-}
-
-/**
- * gst_rtp_buffer_get_packet_len:
- * @buffer: the buffer
- *
- * Return the total length of the packet in @buffer.
- *
- * Returns: The total length of the packet in @buffer.
- */
-guint
-gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
-{
- return GST_BUFFER_SIZE (buffer);
-}
-
-/**
- * gst_rtp_buffer_get_header_len:
- * @buffer: the buffer
- *
- * Return the total length of the header in @buffer. This include the length of
- * the fixed header, the CSRC list and the extension header.
- *
- * Returns: The total length of the header in @buffer.
- */
-guint
-gst_rtp_buffer_get_header_len (GstBuffer * buffer)
-{
- guint len;
- guint8 *data;
-
- data = GST_BUFFER_DATA (buffer);
-
- len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
- if (GST_RTP_HEADER_EXTENSION (data))
- len += GST_READ_UINT16_BE (data + len + 2) * 4 + 4;
-
- return len;
-}
-
-/**
- * gst_rtp_buffer_get_version:
- * @buffer: the buffer
- *
- * Get the version number of the RTP packet in @buffer.
- *
- * Returns: The version of @buffer.
- */
-guint8
-gst_rtp_buffer_get_version (GstBuffer * buffer)
-{
- return GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_set_version:
- * @buffer: the buffer
- * @version: the new version
- *
- * Set the version of the RTP packet in @buffer to @version.
- */
-void
-gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
-{
- g_return_if_fail (version < 0x04);
-
- GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer)) = version;
-}
-
-/**
- * gst_rtp_buffer_get_padding:
- * @buffer: the buffer
- *
- * Check if the padding bit is set on the RTP packet in @buffer.
- *
- * Returns: TRUE if @buffer has the padding bit set.
- */
-gboolean
-gst_rtp_buffer_get_padding (GstBuffer * buffer)
-{
- return GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_set_padding:
- * @buffer: the buffer
- * @padding: the new padding
- *
- * Set the padding bit on the RTP packet in @buffer to @padding.
- */
-void
-gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
-{
- GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer)) = padding;
-}
-
-/**
- * gst_rtp_buffer_pad_to:
- * @buffer: the buffer
- * @len: the new amount of padding
- *
- * Set the amount of padding in the RTP packet in @buffer to
- * @len. If @len is 0, the padding is removed.
- *
- * NOTE: This function does not work correctly.
- */
-void
-gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
-{
- guint8 *data;
-
- data = GST_BUFFER_DATA (buffer);
-
- if (len > 0)
- GST_RTP_HEADER_PADDING (data) = TRUE;
- else
- GST_RTP_HEADER_PADDING (data) = FALSE;
-
- /* FIXME, set the padding byte at the end of the payload data */
-}
-
-/**
- * gst_rtp_buffer_get_extension:
- * @buffer: the buffer
- *
- * Check if the extension bit is set on the RTP packet in @buffer.
- *
- * Returns: TRUE if @buffer has the extension bit set.
- */
-gboolean
-gst_rtp_buffer_get_extension (GstBuffer * buffer)
-{
- return GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_set_extension:
- * @buffer: the buffer
- * @extension: the new extension
- *
- * Set the extension bit on the RTP packet in @buffer to @extension.
- */
-void
-gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
-{
- GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer)) = extension;
-}
-
-/**
- * gst_rtp_buffer_get_extension_data:
- * @buffer: the buffer
- * @bits: location for result bits
- * @data: location for data
- * @wordlen: location for length of @data in 32 bits words
- *
- * Get the extension data. @bits will contain the extension 16 bits of custom
- * data. @data will point to the data in the extension and @wordlen will contain
- * the length of @data in 32 bits words.
- *
- * If @buffer did not contain an extension, this function will return %FALSE
- * with @bits, @data and @wordlen unchanged.
- *
- * Returns: TRUE if @buffer had the extension bit set.
- *
- * Since: 0.10.15
- */
-gboolean
-gst_rtp_buffer_get_extension_data (GstBuffer * buffer, guint16 * bits,
- gpointer * data, guint * wordlen)
-{
- guint len;
- guint8 *pdata;
-
- pdata = GST_BUFFER_DATA (buffer);
-
- if (!GST_RTP_HEADER_EXTENSION (pdata))
- return FALSE;
-
- /* move to the extension */
- len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata);
- pdata += len;
-
- if (bits)
- *bits = GST_READ_UINT16_BE (pdata);
- if (wordlen)
- *wordlen = GST_READ_UINT16_BE (pdata + 2);
- if (data)
- *data = pdata + 4;
-
- return TRUE;
-}
-
-/**
- * gst_rtp_buffer_set_extension_data:
- * @buffer: the buffer
- * @bits: the bits specific for the extension
- * @length: the length that counts the number of 32-bit words in
- * the extension, excluding the extension header ( therefore zero is a valid length)
- *
- * Set the extension bit of the rtp buffer and fill in the @bits and @length of the
- * extension header. It will refuse to set the extension data if the buffer is not
- * large enough.
- *
- * Returns: True if done.
- *
- * Since : 0.10.18
- */
-gboolean
-gst_rtp_buffer_set_extension_data (GstBuffer * buffer, guint16 bits,
- guint16 length)
-{
- guint32 min_size = 0;
- guint8 *data;
-
- data = GST_BUFFER_DATA (buffer);
-
- /* check if the buffer is big enough to hold the extension */
- min_size =
- GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data) + 4 +
- length * sizeof (guint32);
- if (G_UNLIKELY (min_size > GST_BUFFER_SIZE (buffer)))
- goto too_small;
-
- /* now we can set the extension bit */
- gst_rtp_buffer_set_extension (buffer, TRUE);
-
- data += GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (data);
- GST_WRITE_UINT16_BE (data, bits);
- GST_WRITE_UINT16_BE (data + 2, length);
-
- return TRUE;
-
- /* ERRORS */
-too_small:
- {
- g_warning
- ("rtp buffer too small: need more than %d bytes but only have %d bytes",
- min_size, GST_BUFFER_SIZE (buffer));
- return FALSE;
- }
-}
-
-/**
- * gst_rtp_buffer_get_ssrc:
- * @buffer: the buffer
- *
- * Get the SSRC of the RTP packet in @buffer.
- *
- * Returns: the SSRC of @buffer in host order.
- */
-guint32
-gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
-{
- return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_list_get_ssrc:
- * @list: the buffer list
- *
- * Get the SSRC of the first RTP packet in @list.
- * All RTP packets within @list have the same SSRC.
- *
- * Returns: the SSRC of @list in host order.
- *
- * Since: 0.10.24
- */
-guint32
-gst_rtp_buffer_list_get_ssrc (GstBufferList * list)
-{
- GstBuffer *buffer;
-
- buffer = gst_buffer_list_get (list, 0, 0);
- g_return_val_if_fail (buffer != NULL, 0);
-
- return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_set_ssrc:
- * @buffer: the buffer
- * @ssrc: the new SSRC
- *
- * Set the SSRC on the RTP packet in @buffer to @ssrc.
- */
-void
-gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
-{
- GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)) = g_htonl (ssrc);
-}
-
-static GstBufferListItem
-set_ssrc_header (GstBuffer ** buffer, guint group, guint idx, guint32 * ssrc)
-{
- GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (*buffer)) = g_htonl (*ssrc);
- return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_ssrc:
- * @list: the buffer list
- * @ssrc: the new SSRC
- *
- * Set the SSRC on each RTP packet in @list to @ssrc.
- *
- * Since: 0.10.24
- */
-void
-gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc)
-{
- gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc);
-}
-
-/**
- * gst_rtp_buffer_get_csrc_count:
- * @buffer: the buffer
- *
- * Get the CSRC count of the RTP packet in @buffer.
- *
- * Returns: the CSRC count of @buffer.
- */
-guint8
-gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
-{
- return GST_RTP_HEADER_CSRC_COUNT (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_get_csrc:
- * @buffer: the buffer
- * @idx: the index of the CSRC to get
- *
- * Get the CSRC at index @idx in @buffer.
- *
- * Returns: the CSRC at index @idx in host order.
- */
-guint32
-gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
-{
- guint8 *data;
-
- data = GST_BUFFER_DATA (buffer);
-
- g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data), 0);
-
- return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx));
-}
-
-/**
- * gst_rtp_buffer_set_csrc:
- * @buffer: the buffer
- * @idx: the CSRC index to set
- * @csrc: the CSRC in host order to set at @idx
- *
- * Modify the CSRC at index @idx in @buffer to @csrc.
- */
-void
-gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
-{
- guint8 *data;
-
- data = GST_BUFFER_DATA (buffer);
-
- g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
-
- GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
-}
-
-/**
- * gst_rtp_buffer_get_marker:
- * @buffer: the buffer
- *
- * Check if the marker bit is set on the RTP packet in @buffer.
- *
- * Returns: TRUE if @buffer has the marker bit set.
- */
-gboolean
-gst_rtp_buffer_get_marker (GstBuffer * buffer)
-{
- return GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_set_marker:
- * @buffer: the buffer
- * @marker: the new marker
- *
- * Set the marker bit on the RTP packet in @buffer to @marker.
- */
-void
-gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
-{
- GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer)) = marker;
-}
-
-/**
- * gst_rtp_buffer_get_payload_type:
- * @buffer: the buffer
- *
- * Get the payload type of the RTP packet in @buffer.
- *
- * Returns: The payload type.
- */
-guint8
-gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
-{
- return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_list_get_payload_type:
- * @list: the buffer list
- *
- * Get the payload type of the first RTP packet in @list.
- * All packets in @list should have the same payload type.
- *
- * Returns: The payload type.
- *
- * Since: 0.10.24
- */
-guint8
-gst_rtp_buffer_list_get_payload_type (GstBufferList * list)
-{
- GstBuffer *buffer;
-
- buffer = gst_buffer_list_get (list, 0, 0);
- g_return_val_if_fail (buffer != NULL, 0);
-
- return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
-}
-
-/**
- * gst_rtp_buffer_set_payload_type:
- * @buffer: the buffer
- * @payload_type: the new type
- *
- * Set the payload type of the RTP packet in @buffer to @payload_type.
- */
-void
-gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
-{
- g_return_if_fail (payload_type < 0x80);
-
- GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer)) = payload_type;
-}
-
-static GstBufferListItem
-set_pt_header (GstBuffer ** buffer, guint group, guint idx, guint8 * pt)
-{
- GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (*buffer)) = *pt;
- return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_payload_type:
- * @list: the buffer list
- * @payload_type: the new type
- *
- * Set the payload type of each RTP packet in @list to @payload_type.
- *
- * Since: 0.10.24
- */
-void
-gst_rtp_buffer_list_set_payload_type (GstBufferList * list, guint8 payload_type)
-{
- g_return_if_fail (payload_type < 0x80);
-
- gst_buffer_list_foreach (list, (GstBufferListFunc) set_pt_header,
- &payload_type);
-}
-
-/**
- * gst_rtp_buffer_get_seq:
- * @buffer: the buffer
- *
- * Get the sequence number of the RTP packet in @buffer.
- *
- * Returns: The sequence number in host order.
- */
-guint16
-gst_rtp_buffer_get_seq (GstBuffer * buffer)
-{
- return g_ntohs (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_set_seq:
- * @buffer: the buffer
- * @seq: the new sequence number
- *
- * Set the sequence number of the RTP packet in @buffer to @seq.
- */
-void
-gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
-{
- GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)) = g_htons (seq);
-}
-
-static GstBufferListItem
-set_seq_header (GstBuffer ** buffer, guint group, guint idx, guint16 * seq)
-{
- GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (*buffer)) = g_htons (*seq);
- (*seq)++;
- return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_seq:
- * @list: the buffer list
- * @seq: the new sequence number
- *
- * Set the sequence number of each RTP packet in @list to @seq.
- *
- * Returns: The seq number of the last packet in the list + 1.
- *
- * Since: 0.10.24
- */
-guint16
-gst_rtp_buffer_list_set_seq (GstBufferList * list, guint16 seq)
-{
- gst_buffer_list_foreach (list, (GstBufferListFunc) set_seq_header, &seq);
- return seq;
-}
-
-/**
- * gst_rtp_buffer_list_get_seq:
- * @list: the buffer list
- *
- * Get the sequence number of the first RTP packet in @list.
- * All packets within @list have the same sequence number.
- *
- * Returns: The seq number
- *
- * Since: 0.10.24
- */
-guint16
-gst_rtp_buffer_list_get_seq (GstBufferList * list)
-{
- GstBuffer *buffer;
-
- buffer = gst_buffer_list_get (list, 0, 0);
- g_return_val_if_fail (buffer != NULL, 0);
-
- return g_ntohl (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
-}
-
-
-/**
- * gst_rtp_buffer_get_timestamp:
- * @buffer: the buffer
- *
- * Get the timestamp of the RTP packet in @buffer.
- *
- * Returns: The timestamp in host order.
- */
-guint32
-gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
-{
- return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_list_get_timestamp:
- * @list: the buffer list
- *
- * Get the timestamp of the first RTP packet in @list.
- * All packets within @list have the same timestamp.
- *
- * Returns: The timestamp in host order.
- *
- * Since: 0.10.24
- */
-guint32
-gst_rtp_buffer_list_get_timestamp (GstBufferList * list)
-{
- GstBuffer *buffer;
-
- buffer = gst_buffer_list_get (list, 0, 0);
- g_return_val_if_fail (buffer != NULL, 0);
-
- return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
-}
-
-/**
- * gst_rtp_buffer_set_timestamp:
- * @buffer: the buffer
- * @timestamp: the new timestamp
- *
- * Set the timestamp of the RTP packet in @buffer to @timestamp.
- */
-void
-gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
-{
- GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)) = g_htonl (timestamp);
-}
-
-
-static GstBufferListItem
-set_timestamp_header (GstBuffer ** buffer, guint group, guint idx,
- guint32 * timestamp)
-{
- GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (*buffer)) = g_htonl (*timestamp);
- return GST_BUFFER_LIST_SKIP_GROUP;
-}
-
-/**
- * gst_rtp_buffer_list_set_timestamp:
- * @list: the buffer list
- * @timestamp: the new timestamp
- *
- * Set the timestamp of each RTP packet in @list to @timestamp.
- *
- * Since: 0.10.24
- */
-void
-gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
-{
- gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header,
- &timestamp);
-}
-
-/**
- * gst_rtp_buffer_get_payload_subbuffer:
- * @buffer: the buffer
- * @offset: the offset in the payload
- * @len: the length in the payload
- *
- * Create a subbuffer of the payload of the RTP packet in @buffer. @offset bytes
- * are skipped in the payload and the subbuffer will be of size @len.
- * If @len is -1 the total payload starting from @offset if subbuffered.
- *
- * Returns: A new buffer with the specified data of the payload.
- *
- * Since: 0.10.10
- */
-GstBuffer *
-gst_rtp_buffer_get_payload_subbuffer (GstBuffer * buffer, guint offset,
- guint len)
-{
- guint poffset, plen;
-
- plen = gst_rtp_buffer_get_payload_len (buffer);
- /* we can't go past the length */
- if (G_UNLIKELY (offset >= plen))
- goto wrong_offset;
-
- /* apply offset */
- poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
- plen -= offset;
-
- /* see if we need to shrink the buffer based on @len */
- if (len != -1 && len < plen)
- plen = len;
-
- return gst_buffer_create_sub (buffer, poffset, plen);
-
- /* ERRORS */
-wrong_offset:
- {
- g_warning ("offset=%u should be less then plen=%u", offset, plen);
- return NULL;
- }
-}
-
-/**
- * gst_rtp_buffer_get_payload_buffer:
- * @buffer: the buffer
- *
- * Create a buffer of the payload of the RTP packet in @buffer. This function
- * will internally create a subbuffer of @buffer so that a memcpy can be
- * avoided.
- *
- * Returns: A new buffer with the data of the payload.
- */
-GstBuffer *
-gst_rtp_buffer_get_payload_buffer (GstBuffer * buffer)
-{
- return gst_rtp_buffer_get_payload_subbuffer (buffer, 0, -1);
-}
-
-/**
- * gst_rtp_buffer_get_payload_len:
- * @buffer: the buffer
- *
- * Get the length of the payload of the RTP packet in @buffer.
- *
- * Returns: The length of the payload in @buffer.
- */
-guint
-gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
-{
- guint len, size;
- guint8 *data;
-
- size = GST_BUFFER_SIZE (buffer);
- data = GST_BUFFER_DATA (buffer);
-
- len = size - gst_rtp_buffer_get_header_len (buffer);
-
- if (GST_RTP_HEADER_PADDING (data))
- len -= data[size - 1];
-
- return len;
-}
-
-/**
- * gst_rtp_buffer_list_get_payload_len:
- * @list: the buffer list
- *
- * Get the length of the payload of the RTP packet in @list.
- *
- * Returns: The length of the payload in @list.
- *
- * Since: 0.10.24
- */
-guint
-gst_rtp_buffer_list_get_payload_len (GstBufferList * list)
-{
- guint len;
- GstBufferListIterator *it;
-
- it = gst_buffer_list_iterate (list);
- len = 0;
-
- while (gst_buffer_list_iterator_next_group (it)) {
- guint i;
- GstBuffer *buf;
-
- i = 0;
- while ((buf = gst_buffer_list_iterator_next (it))) {
- /* skip the RTP header */
- if (!i++)
- continue;
- /* take the size of the current buffer */
- len += GST_BUFFER_SIZE (buf);
- }
- }
-
- gst_buffer_list_iterator_free (it);
-
- return len;
-}
-
-/**
- * gst_rtp_buffer_get_payload:
- * @buffer: the buffer
- *
- * Get a pointer to the payload data in @buffer. This pointer is valid as long
- * as a reference to @buffer is held.
- *
- * Returns: A pointer to the payload data in @buffer.
- */
-gpointer
-gst_rtp_buffer_get_payload (GstBuffer * buffer)
-{
- return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer);
-}
-
-/**
- * gst_rtp_buffer_default_clock_rate:
- * @payload_type: the static payload type
- *
- * Get the default clock-rate for the static payload type @payload_type.
- *
- * Returns: the default clock rate or -1 if the payload type is not static or
- * the clock-rate is undefined.
- *
- * Since: 0.10.13
- */
-guint32
-gst_rtp_buffer_default_clock_rate (guint8 payload_type)
-{
- const GstRTPPayloadInfo *info;
- guint32 res;
-
- info = gst_rtp_payload_info_for_pt (payload_type);
- if (!info)
- return -1;
-
- res = info->clock_rate;
- /* 0 means unknown so we have to return -1 from this function */
- if (res == 0)
- res = -1;
-
- return res;
-}
-
-/**
- * gst_rtp_buffer_compare_seqnum:
- * @seqnum1: a sequence number
- * @seqnum2: a sequence number
- *
- * Compare two sequence numbers, taking care of wraparounds. This function
- * returns the difference between @seqnum1 and @seqnum2.
- *
- * Returns: a negative value if @seqnum1 is bigger than @seqnum2, 0 if they
- * are equal or a positive value if @seqnum1 is smaller than @segnum2.
- *
- * Since: 0.10.15
- */
-gint
-gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
-{
- return (gint16) (seqnum2 - seqnum1);
-}
-
-/**
- * gst_rtp_buffer_ext_timestamp:
- * @exttimestamp: a previous extended timestamp
- * @timestamp: a new timestamp
- *
- * Update the @exttimestamp field with @timestamp. For the first call of the
- * method, @exttimestamp should point to a location with a value of -1.
- *
- * This function makes sure that the returned value is a constantly increasing
- * value even in the case where there is a timestamp wraparound.
- *
- * Returns: The extended timestamp of @timestamp.
- *
- * Since: 0.10.15
- */
-guint64
-gst_rtp_buffer_ext_timestamp (guint64 * exttimestamp, guint32 timestamp)
-{
- guint64 result, diff, ext;
-
- g_return_val_if_fail (exttimestamp != NULL, -1);
-
- ext = *exttimestamp;
-
- if (ext == -1) {
- result = timestamp;
- } else {
- /* pick wraparound counter from previous timestamp and add to new timestamp */
- result = timestamp + (ext & ~(G_GINT64_CONSTANT (0xffffffff)));
-
- /* check for timestamp wraparound */
- if (result < ext)
- diff = ext - result;
- else
- diff = result - ext;
-
- if (diff > G_MAXINT32) {
- /* timestamp went backwards more than allowed, we wrap around and get
- * updated extended timestamp. */
- result += (G_GINT64_CONSTANT (1) << 32);
- }
- }
- *exttimestamp = result;
-
- return result;
-}