mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
rtp: also support shrinking the extension data
Currently the extension data length specified in the RTP header would say it was shorter then the data serialised to a packet. When combining the resulting buffer, the underlying memory would still contain the extra (now 0-filled) padding data. This would mean that parsing the resulting RTP packet would potentially start with a number of 0-filled bytes which many RTP formats are not expecting. Such usage is found by e.g. RTP header extension when allocating the maximum buffer (which may be larger than the written size) and shrinking to the required size the data once all the rtp header extension data has been written. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1146>
This commit is contained in:
parent
320bc6362b
commit
b7d4d371f9
2 changed files with 93 additions and 0 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue