--- a/gst_plugins_base/gst-libs/gst/rtp/gstrtpbuffer.c Wed Mar 31 22:03:18 2010 +0300
+++ b/gst_plugins_base/gst-libs/gst/rtp/gstrtpbuffer.c Tue Aug 31 15:30:33 2010 +0300
@@ -69,20 +69,19 @@
guint8 csrclist[4]; /* optional CSRC list, 32 bits each */
} GstRTPHeader;
-#define GST_RTP_HEADER_VERSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->version)
-#define GST_RTP_HEADER_PADDING(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->padding)
-#define GST_RTP_HEADER_EXTENSION(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->extension)
-#define GST_RTP_HEADER_CSRC_COUNT(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->csrc_count)
-#define GST_RTP_HEADER_MARKER(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->marker)
-#define GST_RTP_HEADER_PAYLOAD_TYPE(buf)(((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->payload_type)
-#define GST_RTP_HEADER_SEQ(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->seq)
-#define GST_RTP_HEADER_TIMESTAMP(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->timestamp)
-#define GST_RTP_HEADER_SSRC(buf) (((GstRTPHeader *)(GST_BUFFER_DATA (buf)))->ssrc)
-#define GST_RTP_HEADER_CSRC_LIST_OFFSET(buf,i) \
- GST_BUFFER_DATA (buf) + \
- G_STRUCT_OFFSET(GstRTPHeader, csrclist) + \
+#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(buf) (GST_RTP_HEADER_CSRC_COUNT(buf) * sizeof (guint32))
+#define GST_RTP_HEADER_CSRC_SIZE(data) (GST_RTP_HEADER_CSRC_COUNT(data) * sizeof (guint32))
/**
* gst_rtp_buffer_allocate_data:
@@ -105,6 +104,7 @@
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));
@@ -112,22 +112,23 @@
len = GST_RTP_HEADER_LEN + csrc_count * sizeof (guint32)
+ payload_len + pad_len;
- GST_BUFFER_MALLOCDATA (buffer) = g_malloc (len);
- GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
+ 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 (buffer) = GST_RTP_VERSION;
- GST_RTP_HEADER_PADDING (buffer) = FALSE;
- GST_RTP_HEADER_EXTENSION (buffer) = FALSE;
- GST_RTP_HEADER_CSRC_COUNT (buffer) = csrc_count;
- memset (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, 0), 0,
+ 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 (buffer) = FALSE;
- GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = 0;
- GST_RTP_HEADER_SEQ (buffer) = 0;
- GST_RTP_HEADER_TIMESTAMP (buffer) = 0;
- GST_RTP_HEADER_SSRC (buffer) = 0;
+ 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;
}
/**
@@ -316,23 +317,18 @@
}
/**
- * gst_rtp_buffer_validate_data:
+ * 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
*
- * 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.
+ * Checks if @data is a valid RTP packet.
*
- * Returns: TRUE if the data points to a valid RTP packet.
+ * Returns: TRUE if @data is a valid RTP packet
*/
-#ifdef __SYMBIAN32__
-EXPORT_C
-#endif
-
-gboolean
-gst_rtp_buffer_validate_data (guint8 * data, guint len)
+static gboolean
+validate_data (guint8 * data, guint len, guint8 * payload, guint payload_len)
{
guint8 padding;
guint8 csrc_count;
@@ -346,8 +342,8 @@
goto wrong_length;
/* check version */
- version = (data[0] & 0xc0) >> 6;
- if (G_UNLIKELY (version != GST_RTP_VERSION))
+ version = (data[0] & 0xc0);
+ if (G_UNLIKELY (version != (GST_RTP_VERSION << 6)))
goto wrong_version;
/* calc header length with csrc */
@@ -376,13 +372,17 @@
}
/* check for padding */
- if (data[0] & 0x20)
- padding = data[len - 1];
- else
+ if (data[0] & 0x20) {
+ if (payload)
+ padding = payload[payload_len - 1];
+ else
+ padding = data[len - 1];
+ } else {
padding = 0;
+ }
- /* check if padding not bigger than packet and header */
- if (G_UNLIKELY (len - header_len < padding))
+ /* check if padding and header not bigger than packet length */
+ if (G_UNLIKELY (len < padding + header_len))
goto wrong_padding;
return TRUE;
@@ -406,11 +406,35 @@
}
/**
+ * 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.
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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
- * gst_rtp_buffer_validate_data().
+ * 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.
*/
@@ -429,7 +453,99 @@
data = GST_BUFFER_DATA (buffer);
len = GST_BUFFER_SIZE (buffer);
- return gst_rtp_buffer_validate_data (data, len);
+ 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
+ */
+
+ #ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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;
+ }
}
/**
@@ -448,22 +564,20 @@
gst_rtp_buffer_set_packet_len (GstBuffer * buffer, guint len)
{
guint oldlen;
-
- g_return_if_fail (GST_IS_BUFFER (buffer));
+ guint8 *data;
oldlen = GST_BUFFER_SIZE (buffer);
+ data = GST_BUFFER_DATA (buffer);
if (oldlen < len) {
- guint8 *newdata;
-
- newdata = g_realloc (GST_BUFFER_MALLOCDATA (buffer), len);
- GST_BUFFER_MALLOCDATA (buffer) = newdata;
- GST_BUFFER_DATA (buffer) = newdata;
+ 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 (buffer) = FALSE;
+ GST_RTP_HEADER_PADDING (data) = FALSE;
}
/**
@@ -481,8 +595,6 @@
guint
gst_rtp_buffer_get_packet_len (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
-
return GST_BUFFER_SIZE (buffer);
}
@@ -503,12 +615,13 @@
gst_rtp_buffer_get_header_len (GstBuffer * buffer)
{
guint len;
+ guint8 *data;
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+ data = GST_BUFFER_DATA (buffer);
- len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer);
- if (GST_RTP_HEADER_EXTENSION (buffer))
- len += GST_READ_UINT16_BE (GST_BUFFER_DATA (buffer) + len + 2) * 4 + 4;
+ 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;
}
@@ -528,10 +641,7 @@
guint8
gst_rtp_buffer_get_version (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
-
- return GST_RTP_HEADER_VERSION (buffer);
+ return GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer));
}
/**
@@ -548,11 +658,9 @@
void
gst_rtp_buffer_set_version (GstBuffer * buffer, guint8 version)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
g_return_if_fail (version < 0x04);
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
- GST_RTP_HEADER_VERSION (buffer) = version;
+ GST_RTP_HEADER_VERSION (GST_BUFFER_DATA (buffer)) = version;
}
/**
@@ -570,10 +678,7 @@
gboolean
gst_rtp_buffer_get_padding (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
-
- return GST_RTP_HEADER_PADDING (buffer);
+ return GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer));
}
/**
@@ -590,10 +695,7 @@
void
gst_rtp_buffer_set_padding (GstBuffer * buffer, gboolean padding)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
-
- GST_RTP_HEADER_PADDING (buffer) = padding;
+ GST_RTP_HEADER_PADDING (GST_BUFFER_DATA (buffer)) = padding;
}
/**
@@ -613,13 +715,14 @@
void
gst_rtp_buffer_pad_to (GstBuffer * buffer, guint len)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+ guint8 *data;
+
+ data = GST_BUFFER_DATA (buffer);
if (len > 0)
- GST_RTP_HEADER_PADDING (buffer) = TRUE;
+ GST_RTP_HEADER_PADDING (data) = TRUE;
else
- GST_RTP_HEADER_PADDING (buffer) = FALSE;
+ GST_RTP_HEADER_PADDING (data) = FALSE;
/* FIXME, set the padding byte at the end of the payload data */
}
@@ -639,10 +742,7 @@
gboolean
gst_rtp_buffer_get_extension (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
-
- return GST_RTP_HEADER_EXTENSION (buffer);
+ return GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer));
}
/**
@@ -659,10 +759,7 @@
void
gst_rtp_buffer_set_extension (GstBuffer * buffer, gboolean extension)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
-
- GST_RTP_HEADER_EXTENSION (buffer) = extension;
+ GST_RTP_HEADER_EXTENSION (GST_BUFFER_DATA (buffer)) = extension;
}
/**
@@ -694,15 +791,14 @@
guint len;
guint8 *pdata;
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
+ pdata = GST_BUFFER_DATA (buffer);
- if (!GST_RTP_HEADER_EXTENSION (buffer))
+ if (!GST_RTP_HEADER_EXTENSION (pdata))
return FALSE;
/* move to the extension */
- len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer);
- pdata = GST_BUFFER_DATA (buffer) + len;
+ len = GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (pdata);
+ pdata += len;
if (bits)
*bits = GST_READ_UINT16_BE (pdata);
@@ -740,27 +836,32 @@
guint32 min_size = 0;
guint8 *data;
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
+ data = GST_BUFFER_DATA (buffer);
- gst_rtp_buffer_set_extension (buffer, TRUE);
+ /* check if the buffer is big enough to hold the extension */
min_size =
- GST_RTP_HEADER_LEN + GST_RTP_HEADER_CSRC_SIZE (buffer) + 4 +
+ 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);
- if (min_size > GST_BUFFER_SIZE (buffer)) {
- GST_WARNING_OBJECT (buffer,
- "rtp buffer too small: need more than %d bytes but only have %d bytes",
+ 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;
}
-
- data =
- GST_BUFFER_DATA (buffer) + GST_RTP_HEADER_LEN +
- GST_RTP_HEADER_CSRC_SIZE (buffer);
- GST_WRITE_UINT16_BE (data, bits);
- GST_WRITE_UINT16_BE (data + 2, length);
- return TRUE;
}
/**
@@ -778,10 +879,34 @@
guint32
gst_rtp_buffer_get_ssrc (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+ return g_ntohl (GST_RTP_HEADER_SSRC (GST_BUFFER_DATA (buffer)));
+}
- return g_ntohl (GST_RTP_HEADER_SSRC (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
+ */
+
+ #ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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)));
}
/**
@@ -798,10 +923,32 @@
void
gst_rtp_buffer_set_ssrc (GstBuffer * buffer, guint32 ssrc)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+ 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_HEADER_SSRC (buffer) = g_htonl (ssrc);
+/**
+ * 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
+ */
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+void
+gst_rtp_buffer_list_set_ssrc (GstBufferList * list, guint32 ssrc)
+{
+ gst_buffer_list_foreach (list, (GstBufferListFunc) set_ssrc_header, &ssrc);
}
/**
@@ -819,10 +966,7 @@
guint8
gst_rtp_buffer_get_csrc_count (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
-
- return GST_RTP_HEADER_CSRC_COUNT (buffer);
+ return GST_RTP_HEADER_CSRC_COUNT (GST_BUFFER_DATA (buffer));
}
/**
@@ -841,11 +985,13 @@
guint32
gst_rtp_buffer_get_csrc (GstBuffer * buffer, guint8 idx)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
- g_return_val_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer), 0);
+ guint8 *data;
+
+ data = GST_BUFFER_DATA (buffer);
- return GST_READ_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx));
+ 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));
}
/**
@@ -863,11 +1009,13 @@
void
gst_rtp_buffer_set_csrc (GstBuffer * buffer, guint8 idx, guint32 csrc)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
- g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (buffer));
+ guint8 *data;
+
+ data = GST_BUFFER_DATA (buffer);
- GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (buffer, idx), csrc);
+ g_return_if_fail (idx < GST_RTP_HEADER_CSRC_COUNT (data));
+
+ GST_WRITE_UINT32_BE (GST_RTP_HEADER_CSRC_LIST_OFFSET (data, idx), csrc);
}
/**
@@ -885,10 +1033,7 @@
gboolean
gst_rtp_buffer_get_marker (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, FALSE);
-
- return GST_RTP_HEADER_MARKER (buffer);
+ return GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer));
}
/**
@@ -905,10 +1050,7 @@
void
gst_rtp_buffer_set_marker (GstBuffer * buffer, gboolean marker)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
-
- GST_RTP_HEADER_MARKER (buffer) = marker;
+ GST_RTP_HEADER_MARKER (GST_BUFFER_DATA (buffer)) = marker;
}
/**
@@ -926,10 +1068,34 @@
guint8
gst_rtp_buffer_get_payload_type (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+ return GST_RTP_HEADER_PAYLOAD_TYPE (GST_BUFFER_DATA (buffer));
+}
- return GST_RTP_HEADER_PAYLOAD_TYPE (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
+ */
+
+ #ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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));
}
/**
@@ -946,11 +1112,39 @@
void
gst_rtp_buffer_set_payload_type (GstBuffer * buffer, guint8 payload_type)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
g_return_if_fail (payload_type < 0x80);
- GST_RTP_HEADER_PAYLOAD_TYPE (buffer) = payload_type;
+ 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
+ */
+
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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);
}
/**
@@ -968,10 +1162,7 @@
guint16
gst_rtp_buffer_get_seq (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
-
- return g_ntohs (GST_RTP_HEADER_SEQ (buffer));
+ return g_ntohs (GST_RTP_HEADER_SEQ (GST_BUFFER_DATA (buffer)));
}
/**
@@ -988,13 +1179,69 @@
void
gst_rtp_buffer_set_seq (GstBuffer * buffer, guint16 seq)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+ 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
+ */
+
+ #ifdef __SYMBIAN32__
+EXPORT_C
+#endif
- GST_RTP_HEADER_SEQ (buffer) = g_htons (seq);
+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
+ */
+
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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
*
@@ -1009,10 +1256,34 @@
guint32
gst_rtp_buffer_get_timestamp (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+ return g_ntohl (GST_RTP_HEADER_TIMESTAMP (GST_BUFFER_DATA (buffer)));
+}
- return g_ntohl (GST_RTP_HEADER_TIMESTAMP (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
+ */
+
+ #ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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)));
}
/**
@@ -1029,10 +1300,37 @@
void
gst_rtp_buffer_set_timestamp (GstBuffer * buffer, guint32 timestamp)
{
- g_return_if_fail (GST_IS_BUFFER (buffer));
- g_return_if_fail (GST_BUFFER_DATA (buffer) != NULL);
+ 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_HEADER_TIMESTAMP (buffer) = g_htonl (timestamp);
+/**
+ * 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
+ */
+
+ #ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+void
+gst_rtp_buffer_list_set_timestamp (GstBufferList * list, guint32 timestamp)
+{
+ gst_buffer_list_foreach (list, (GstBufferListFunc) set_timestamp_header,
+ ×tamp);
}
/**
@@ -1059,15 +1357,10 @@
{
guint poffset, plen;
- g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);
-
plen = gst_rtp_buffer_get_payload_len (buffer);
/* we can't go past the length */
- if (G_UNLIKELY (offset >= plen)) {
- GST_WARNING ("offset=%u should be less then plen=%u", offset, plen);
- return (NULL);
- }
+ if (G_UNLIKELY (offset >= plen))
+ goto wrong_offset;
/* apply offset */
poffset = gst_rtp_buffer_get_header_len (buffer) + offset;
@@ -1078,6 +1371,13 @@
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;
+ }
}
/**
@@ -1116,16 +1416,58 @@
gst_rtp_buffer_get_payload_len (GstBuffer * buffer)
{
guint len, size;
-
- g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, 0);
+ 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 (buffer))
- len -= GST_BUFFER_DATA (buffer)[size - 1];
+ 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
+ */
+
+#ifdef __SYMBIAN32__
+EXPORT_C
+#endif
+
+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;
}
@@ -1146,9 +1488,6 @@
gpointer
gst_rtp_buffer_get_payload (GstBuffer * buffer)
{
- g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
- g_return_val_if_fail (GST_BUFFER_DATA (buffer) != NULL, NULL);
-
return GST_BUFFER_DATA (buffer) + gst_rtp_buffer_get_header_len (buffer);
}
@@ -1190,10 +1529,11 @@
* @seqnum1: a sequence number
* @seqnum2: a sequence number
*
- * Compare two sequence numbers, taking care of wraparounds.
+ * Compare two sequence numbers, taking care of wraparounds. This function
+ * returns the difference between @seqnum1 and @seqnum2.
*
- * Returns: -1 if @seqnum1 is before @seqnum2, 0 if they are equal or 1 if
- * @seqnum1 is bigger than @segnum2.
+ * 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
*/
@@ -1204,13 +1544,7 @@
gint
gst_rtp_buffer_compare_seqnum (guint16 seqnum1, guint16 seqnum2)
{
- /* check if diff more than half of the 16bit range */
- if (abs (seqnum2 - seqnum1) > (1 << 15)) {
- /* one of a/b has wrapped */
- return seqnum1 - seqnum2;
- } else {
- return seqnum2 - seqnum1;
- }
+ return (gint16) (seqnum2 - seqnum1);
}
/**