From f265e5cbd5c0d1a0b611feb0bd50d52cac2436a9 Mon Sep 17 00:00:00 2001 From: Miguel Paris Date: Thu, 20 Feb 2020 17:25:19 +0100 Subject: [PATCH] rtpbuffer: add_extension_onebyte_header: fix the proper wordlen 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 | 10 +++-- tests/check/libs/rtp.c | 75 +++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/rtp/gstrtpbuffer.c b/gst-libs/gst/rtp/gstrtpbuffer.c index 5a4ff6f89c..3db9601be2 100644 --- a/gst-libs/gst/rtp/gstrtpbuffer.c +++ b/gst-libs/gst/rtp/gstrtpbuffer.c @@ -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; diff --git a/tests/check/libs/rtp.c b/tests/check/libs/rtp.c index cdb9224c04..6377434360 100644 --- a/tests/check/libs/rtp.c +++ b/tests/check/libs/rtp.c @@ -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);