summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier CrĂȘte <olivier.crete@collabora.co.uk>2010-08-20 12:54:38 -0400
committerWim Taymans <wim.taymans@collabora.co.uk>2010-10-05 16:19:14 +0200
commit02a0139451f157f2cfb07fb290a35b6874e6973c (patch)
tree64e20448832d85a613325b4d3ac4a1e560c21e50
parente4c06debb2b3301b8ee94de2adf158df4f33b23a (diff)
rtpbuffer: Add function to append RFC 5285 one byte header extensions
-rw-r--r--docs/libs/gst-plugins-base-libs-sections.txt2
-rw-r--r--gst-libs/gst/rtp/gstrtpbuffer.c109
-rw-r--r--gst-libs/gst/rtp/gstrtpbuffer.h4
3 files changed, 115 insertions, 0 deletions
diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt
index a80bb16dc..56c95fc44 100644
--- a/docs/libs/gst-plugins-base-libs-sections.txt
+++ b/docs/libs/gst-plugins-base-libs-sections.txt
@@ -1359,6 +1359,8 @@ gst_rtp_buffer_list_set_timestamp
gst_rtp_buffer_get_extension_onebyte_header
gst_rtp_buffer_get_extension_twobytes_header
+
+gst_rtp_buffer_add_extension_twobytes_header
</SECTION>
# rtsp
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c
index d28ec5e4c..c80410bbd 100644
--- a/gst-libs/gst/rtp/gstrtpbuffer.c
+++ b/gst-libs/gst/rtp/gstrtpbuffer.c
@@ -1542,3 +1542,112 @@ gst_rtp_buffer_get_extension_twobytes_header (GstBuffer * buffer,
return FALSE;
}
+
+/**
+ * gst_rtp_buffer_add_extension_onebyte_header:
+ * @buffer: the buffer
+ * @id: The ID of the header extension (between 1 and 14).
+ * @data: location for data
+ * @size: the size of the data in bytes
+ *
+ * Adds a RFC 5285 header extension with a one byte header to the end of the
+ * RTP header. If there is already a RFC 5285 header extension with a one byte
+ * header, the new extension will be appended.
+ * It will not work if there is already a header extension that does not follow
+ * the mecanism described in RFC 5285 or if there is a header extension with
+ * a two bytes header as described in RFC 5285. In that case, use
+ * gst_rtp_buffer_add_extension_twobytes_header()
+ *
+ * Returns: %TRUE if header extension could be added
+ *
+ * Since: 0.10.31
+ */
+
+gboolean
+gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer, guint8 id,
+ gpointer data, guint size)
+{
+ guint16 bits;
+ guint8 *pdata;
+ guint wordlen;
+ gboolean has_bit;
+ guint bytelen;
+
+ g_return_val_if_fail (id > 0 && id < 15, FALSE);
+ g_return_val_if_fail (size >= 1 && size <= 16, FALSE);
+ g_return_val_if_fail (gst_buffer_is_writable (buffer), FALSE);
+
+ has_bit = gst_rtp_buffer_get_extension_data (buffer, &bits,
+ (gpointer) & pdata, &wordlen);
+
+ bytelen = wordlen * 4;
+
+ if (has_bit) {
+ gulong offset = 0;
+ guint8 *nextext;
+ guint extlen;
+
+ if (bits != 0xBEDE)
+ return FALSE;
+
+ while (offset + 1 < bytelen) {
+ guint8 read_id, read_len;
+
+ read_id = GST_READ_UINT8 (pdata + offset) >> 4;
+ read_len = (GST_READ_UINT8 (pdata + offset) & 0x0F) + 1;
+ offset += 1;
+
+ /* ID 0 means its padding, skip */
+ if (read_id == 0)
+ continue;
+
+ /* ID 15 is special and means we should stop parsing */
+ /* It also means we can't add an extra packet */
+ if (read_id == 15)
+ return FALSE;
+
+ /* Ignore extension headers where the size does not fit */
+ if (offset + read_len > bytelen)
+ return FALSE;
+
+ offset += read_len;
+
+ }
+
+ nextext = pdata + offset;
+
+ offset = nextext - GST_BUFFER_DATA (buffer);
+
+ /* Don't add extra header if there isn't enough space */
+ if (GST_BUFFER_SIZE (buffer) < offset + size + 1)
+ return FALSE;
+
+ nextext[0] = (id << 4) | (0x0F & (size - 1));
+ memcpy (nextext + 1, data, size);
+
+ extlen = nextext - pdata + size + 1;
+ if (extlen % 4) {
+ wordlen = extlen / 4 + 1;
+ memset (nextext + size + 1, 0, 4 - extlen % 4);
+ } else {
+ wordlen = extlen / 4;
+ }
+
+ gst_rtp_buffer_set_extension_data (buffer, 0xBEDE, wordlen);
+ } else {
+ wordlen = (size + 1) / 4 + (((size + 1) % 4) ? 1 : 0);
+
+ gst_rtp_buffer_set_extension_data (buffer, 0xBEDE, wordlen);
+
+ gst_rtp_buffer_get_extension_data (buffer, &bits,
+ (gpointer) & pdata, &wordlen);
+
+ pdata[0] = (id << 4) | (0x0F & (size - 1));
+ memcpy (pdata + 1, data, size);
+
+ if ((size + 1) % 4)
+ memset (pdata + size + 1, 0, 4 - ((size + 1) % 4));
+ }
+
+ return TRUE;
+}
diff --git a/gst-libs/gst/rtp/gstrtpbuffer.h b/gst-libs/gst/rtp/gstrtpbuffer.h
index 680895a7a..7e1d2921b 100644
--- a/gst-libs/gst/rtp/gstrtpbuffer.h
+++ b/gst-libs/gst/rtp/gstrtpbuffer.h
@@ -122,6 +122,10 @@ gboolean gst_rtp_buffer_get_extension_twobytes_header (GstBuffer * buffer
gpointer * data,
guint * size);
+gboolean gst_rtp_buffer_add_extension_onebyte_header (GstBuffer * buffer,
+ guint8 id,
+ gpointer data,
+ guint size);
G_END_DECLS