rtpbuffer: add_extension_onebyte_header: fix the proper wordlen
authorMiguel Paris <mparisdiaz@gmail.com>
Thu, 20 Feb 2020 16:25:19 +0000 (17:25 +0100)
committerMiguel Paris <mparisdiaz@gmail.com>
Thu, 19 Mar 2020 13:18:20 +0000 (14:18 +0100)
The wordlen ("length") MUST represent the total "number of 32-bit words
in the extension, excluding the four-octet extension header" (rfc3550).
There are cases where already existent padding is reused for adding
the new extension. So the new wordlen should be updated if the new
added extension makes it to increase.

gst-libs/gst/rtp/gstrtpbuffer.c
tests/check/libs/rtp.c

index 5a4ff6f..3db9601 100644 (file)
@@ -1511,7 +1511,7 @@ gst_rtp_buffer_get_extension_twobytes_header (GstRTPBuffer * rtp,
 }
 
 static gboolean
-get_onebyte_header_end_offset (guint8 * pdata, guint wordlen, guint *offset)
+get_onebyte_header_end_offset (guint8 * pdata, guint wordlen, guint * offset)
 {
   guint bytelen = wordlen * 4;
   guint paddingcount = 0;
@@ -1576,7 +1576,8 @@ gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
 {
   guint16 bits;
   guint8 *pdata = 0;
-  guint wordlen;
+  guint wordlen = 0;
+  guint wordlen_new;
   gboolean has_bit;
   guint extlen, offset = 0;
 
@@ -1598,9 +1599,10 @@ gst_rtp_buffer_add_extension_onebyte_header (GstRTPBuffer * rtp, guint8 id,
   /* the required size of the new extension data */
   extlen = offset + size + 1;
   /* calculate amount of words */
-  wordlen = extlen / 4 + ((extlen % 4) ? 1 : 0);
+  wordlen_new = extlen / 4 + ((extlen % 4) ? 1 : 0);
+  wordlen_new = MAX (wordlen_new, wordlen);
 
-  gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen);
+  gst_rtp_buffer_set_extension_data (rtp, 0xBEDE, wordlen_new);
   gst_rtp_buffer_get_extension_data (rtp, &bits, (gpointer) & pdata, &wordlen);
 
   pdata += offset;
index cdb9224..6377434 100644 (file)
@@ -1814,6 +1814,78 @@ GST_START_TEST (test_rtp_buffer_empty_payload)
 
 GST_END_TEST;
 
+GST_START_TEST (test_rtp_buffer_extension_onebyte_header_full_padding)
+{
+  GstBuffer *buffer;
+  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
+  guint8 *mem;
+  guint size;
+  guint8 *data_out;
+  guint16 bits;
+  guint8 *pdata;
+  guint wordlen = 0;
+  guint8 hdr_buffer_1[2] = { 0x1, 0x1 };
+
+  guint8 rtp_test_buffer[] = {
+    0x90, 0x7c, 0x18, 0xa6,     /* |V=2|P|X|CC|M|PT|sequence number| */
+    0x7a, 0x62, 0x17, 0x0f,     /* |timestamp| */
+    0x70, 0x23, 0x91, 0x38,     /* |synchronization source (SSRC) identifier| */
+    0xbe, 0xde, 0x00, 0x02,     /* |0xBE|0xDE|length=2| */
+    0x00, 0x00, 0x00, 0x00,     /* |0 (pad)|0 (pad)|0 (pad)|0 (pad)| */
+    0x00, 0x00, 0x00, 0x00,     /* |0 (pad)|0 (pad)|0 (pad)|0 (pad)| */
+    0xff, 0xff, 0xff, 0xff      /* |dummy payload| */
+  };
+
+  mem = malloc (sizeof (rtp_test_buffer));
+  fail_unless (mem != NULL);
+  memcpy (mem, rtp_test_buffer, sizeof (rtp_test_buffer));
+  fail_unless_equals_int (memcmp (mem, rtp_test_buffer,
+          sizeof (rtp_test_buffer)), 0);
+
+  buffer = gst_buffer_new_wrapped (mem, sizeof (rtp_test_buffer));
+
+  fail_unless (gst_rtp_buffer_map (buffer, GST_MAP_READ, &rtp));
+
+  fail_unless (gst_rtp_buffer_get_extension_data (&rtp, &bits,
+          (gpointer) & pdata, &wordlen));
+  fail_unless_equals_int (bits, 0xBEDE);
+  fail_unless_equals_int (wordlen, 2);
+  fail_unless_equals_int (pdata[0], 0x0);
+  fail_unless_equals_int (pdata[1], 0x0);
+  fail_unless_equals_int (pdata[2], 0x0);
+  fail_unless_equals_int (pdata[3], 0x0);
+  fail_unless_equals_int (pdata[4], 0x0);
+  fail_unless_equals_int (pdata[5], 0x0);
+  fail_unless_equals_int (pdata[6], 0x0);
+  fail_unless_equals_int (pdata[7], 0x0);
+
+  fail_unless (gst_rtp_buffer_add_extension_onebyte_header (&rtp, 1,
+          hdr_buffer_1, 2));
+  fail_unless (gst_rtp_buffer_get_extension_onebyte_header (&rtp, 1, 0,
+          (gpointer *) & data_out, &size));
+  fail_unless_equals_int (size, 2);
+  fail_unless_equals_int (data_out[0], 0x1);
+  fail_unless_equals_int (data_out[1], 0x1);
+  fail_unless (gst_rtp_buffer_get_extension_data (&rtp, &bits,
+          (gpointer) & pdata, &wordlen));
+  fail_unless_equals_int (bits, 0xBEDE);
+  fail_unless_equals_int (wordlen, 2);
+  fail_unless_equals_int (pdata[0], 0x11);
+  fail_unless_equals_int (pdata[1], 0x1);
+  fail_unless_equals_int (pdata[2], 0x1);
+  fail_unless_equals_int (pdata[3], 0x0);
+  fail_unless_equals_int (pdata[4], 0x0);
+  fail_unless_equals_int (pdata[5], 0x0);
+  fail_unless_equals_int (pdata[6], 0x0);
+  fail_unless_equals_int (pdata[7], 0x0);
+
+  gst_rtp_buffer_unmap (&rtp);
+
+  gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
 
 GST_START_TEST (test_ext_timestamp_basic)
 {
@@ -1939,6 +2011,9 @@ rtp_suite (void)
   tcase_add_test (tc_chain, test_rtp_buffer_get_extension_bytes);
   tcase_add_test (tc_chain, test_rtp_buffer_empty_payload);
 
+  tcase_add_test (tc_chain,
+      test_rtp_buffer_extension_onebyte_header_full_padding);
+
   //tcase_add_test (tc_chain, test_rtp_buffer_list);
 
   tcase_add_test (tc_chain, test_ext_timestamp_basic);