diff --git a/subprojects/gst-plugins-base/gst-libs/gst/rtp/gstrtpbuffer.c b/subprojects/gst-plugins-base/gst-libs/gst/rtp/gstrtpbuffer.c index ce3949a6b8..399724d8dd 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/rtp/gstrtpbuffer.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/rtp/gstrtpbuffer.c @@ -833,6 +833,8 @@ ensure_buffers (GstRTPBuffer * rtp) * extension header. If the existing extension data is not large enough, it will * be made larger. * + * Will also shorten the extension data from 1.20. + * * Returns: True if done. */ gboolean @@ -882,6 +884,15 @@ gst_rtp_buffer_set_extension_data (GstRTPBuffer * rtp, guint16 bits, gst_memory_ref (mem); rtp->data[1] = rtp->map[1].data; rtp->size[1] = rtp->map[1].size; + } else if (min_size < rtp->size[1]) { + GstMemory *mem = rtp->map[1].memory; + + gst_memory_ref (mem); + gst_buffer_unmap (rtp->buffer, &rtp->map[1]); + gst_memory_resize (mem, 0, min_size); + gst_memory_map (mem, &rtp->map[1], GST_MAP_READWRITE); + rtp->data[1] = rtp->map[1].data; + rtp->size[1] = rtp->map[1].size; } /* now we can set the extension bit */ diff --git a/subprojects/gst-plugins-base/tests/check/libs/rtp.c b/subprojects/gst-plugins-base/tests/check/libs/rtp.c index 029260d47d..11eec6d0c4 100644 --- a/subprojects/gst-plugins-base/tests/check/libs/rtp.c +++ b/subprojects/gst-plugins-base/tests/check/libs/rtp.c @@ -421,6 +421,87 @@ GST_START_TEST (test_rtp_buffer_set_extension_data) GST_END_TEST; +GST_START_TEST (test_rtp_buffer_set_extension_data_shrink_data) +{ + GstBuffer *buf; + guint16 bits; + guint size; + gpointer pointer; + GstRTPBuffer rtp = GST_RTP_BUFFER_INIT; + guint8 scratch_cmp[4 * 4] = { 0, }; + GstMapInfo info = GST_MAP_INFO_INIT; + gsize i; + + buf = gst_rtp_buffer_new_allocate (20, 0, 0); + gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp); + + fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 270, 4) == TRUE); + fail_unless (gst_rtp_buffer_get_extension (&rtp) == TRUE); + gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer, &size); + GST_MEMDUMP ("", pointer, size * 4); + fail_unless (bits == 270); + fail_unless (size == 4); + for (i = 0; i < size * 4; i++) { + guint8 *bytes = pointer; + bytes[i] = i; + } + memcpy (scratch_cmp, pointer, size * 4); + fail_unless_equals_int64 ((guint64) gst_buffer_get_size (buf), 52); + gst_rtp_buffer_unmap (&rtp); + + /* ensure that the mapped buffer size matches */ + gst_buffer_map (buf, &info, GST_MAP_READ); + GST_MEMDUMP ("", info.data, info.size); + fail_unless_equals_int64 ((guint64) info.size, 52); + gst_buffer_unmap (buf, &info); + + gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp); + /* shrinking the extension data should still succeed and only output the + * relevant data */ + fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 180, 2) == TRUE); + gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer, &size); + GST_MEMDUMP ("", pointer, size * 4); + fail_unless (bits == 180); + fail_unless (size == 2); + fail_unless_equals_int64 ((guint64) gst_buffer_get_size (buf), 44); + for (i = 0; i < 8; i++) { + guint8 *ext_data = pointer; + fail_unless_equals_int_hex (ext_data[i], scratch_cmp[i]); + } + gst_rtp_buffer_unmap (&rtp); + + gst_buffer_map (buf, &info, GST_MAP_READ); + GST_MEMDUMP ("", info.data, info.size); + fail_unless_equals_int64 ((guint64) info.size, 44); + gst_buffer_unmap (buf, &info); + + gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp); + fail_unless (gst_rtp_buffer_set_extension_data (&rtp, 308, 3) == TRUE); + gst_rtp_buffer_get_extension_data (&rtp, &bits, &pointer, &size); + GST_MEMDUMP ("", pointer, size * 4); + fail_unless (bits == 308); + fail_unless (size == 3); + for (i = 0; i < 8; i++) { + guint8 *ext_data = pointer; + fail_unless_equals_int_hex (ext_data[i], scratch_cmp[i]); + } + /* new data will be zero-initialized */ + for (i = 8; i < size * 4; i++) { + guint8 *ext_data = pointer; + fail_unless_equals_int_hex (ext_data[i], 0); + } + fail_unless_equals_int64 ((guint64) gst_buffer_get_size (buf), 48); + gst_rtp_buffer_unmap (&rtp); + + gst_buffer_map (buf, &info, GST_MAP_READ); + GST_MEMDUMP ("", info.data, info.size); + fail_unless_equals_int64 ((guint64) info.size, 48); + gst_buffer_unmap (buf, &info); + gst_buffer_unref (buf); +} + +GST_END_TEST; + #if 0 GST_START_TEST (test_rtp_buffer_list_set_extension) { @@ -2290,6 +2371,7 @@ rtp_suite (void) tcase_add_test (tc_chain, test_rtcp_compound_padding); tcase_add_test (tc_chain, test_rtp_buffer_extlen_wraparound); tcase_add_test (tc_chain, test_rtp_buffer_remove_extension_data); + tcase_add_test (tc_chain, test_rtp_buffer_set_extension_data_shrink_data); return s; }