From 02a0139451f157f2cfb07fb290a35b6874e6973c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Fri, 20 Aug 2010 12:54:38 -0400 Subject: [PATCH] rtpbuffer: Add function to append RFC 5285 one byte header extensions --- docs/libs/gst-plugins-base-libs-sections.txt | 2 + gst-libs/gst/rtp/gstrtpbuffer.c | 109 +++++++++++++++++++ gst-libs/gst/rtp/gstrtpbuffer.h | 4 + 3 files changed, 115 insertions(+) diff --git a/docs/libs/gst-plugins-base-libs-sections.txt b/docs/libs/gst-plugins-base-libs-sections.txt index a80bb16dcc..56c95fc444 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 # rtsp diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c index d28ec5e4cc..c80410bbd0 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 680895a7a8..7e1d2921b1 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