rtpbuffer: Add function to append RFC 5285 one byte header extensions
authorOlivier CrĂȘte <olivier.crete@collabora.co.uk>
Fri, 20 Aug 2010 16:54:38 +0000 (12:54 -0400)
committerWim Taymans <wim.taymans@collabora.co.uk>
Tue, 5 Oct 2010 14:19:14 +0000 (16:19 +0200)
docs/libs/gst-plugins-base-libs-sections.txt
gst-libs/gst/rtp/gstrtpbuffer.c
gst-libs/gst/rtp/gstrtpbuffer.h

index a80bb16..56c95fc 100644 (file)
@@ -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
index d28ec5e..c80410b 100644 (file)
@@ -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;
+}
index 680895a..7e1d292 100644 (file)
@@ -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