3 * unit test for RTP RFC 6464 Header Extensions
5 * Copyright (C) <2020-2021> Guillaume Desmottes <guillaume.desmottes@collabora.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
23 #include <gst/check/gstcheck.h>
24 #include <gst/rtp/rtp.h>
25 #include <gst/sdp/gstsdpmessage.h>
26 #include <gst/audio/audio.h>
28 #define URN "urn:ietf:params:rtp-hdrext:ssrc-audio-level"
30 #define SDP "v=0\r\n" \
31 "o=- 123456 2 IN IP4 127.0.0.1 \r\n" \
36 "m=audio 55815 RTP/SAVPF 100\r\n" \
37 "c=IN IP4 1.1.1.1\r\n" \
38 "a=rtpmap:100 opus/48000/2\r\n"
40 #define SDP_NO_VAD SDP \
41 "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
42 #define SDP_VAD_ON SDP \
43 "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level vad=on\r\n"
44 #define SDP_VAD_OFF SDP \
45 "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level vad=off\r\n"
46 #define SDP_VAD_WRONG SDP \
47 "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level vad=badger\r\n"
50 create_caps (const gchar * sdp)
52 GstSDPMessage *message;
54 const GstSDPMedia *media;
57 gst_sdp_message_new (&message);
58 gst_sdp_message_parse_buffer ((guint8 *) sdp, length, message);
59 media = gst_sdp_message_get_media (message, 0);
60 fail_unless (media != NULL);
62 caps = gst_sdp_media_get_caps_from_media (media, 100);
63 gst_sdp_media_attributes_to_caps (media, caps);
64 gst_sdp_message_free (message);
69 check_caps (GstRTPHeaderExtension * ext, gboolean vad)
73 const GValue *arr, *val;
75 caps = gst_caps_new_empty_simple ("application/x-rtp");
76 fail_unless (gst_rtp_header_extension_set_caps_from_attributes (ext, caps));
77 s = gst_caps_get_structure (caps, 0);
79 arr = gst_structure_get_value (s, "extmap-1");
80 fail_unless (arr != NULL);
81 fail_unless (GST_VALUE_HOLDS_ARRAY (arr));
82 fail_unless (gst_value_array_get_size (arr) == 3);
84 val = gst_value_array_get_value (arr, 0);
85 fail_unless_equals_string (g_value_get_string (val), "");
87 val = gst_value_array_get_value (arr, 1);
88 fail_unless_equals_string (g_value_get_string (val), URN);
90 val = gst_value_array_get_value (arr, 2);
92 fail_unless_equals_string (g_value_get_string (val), "vad=on");
94 fail_unless_equals_string (g_value_get_string (val), "vad=off");
97 gst_caps_unref (caps);
100 GST_START_TEST (rtprfc6464_sdp)
102 GstRTPHeaderExtension *ext;
104 gboolean vad = FALSE;
106 ext = gst_rtp_header_extension_create_from_uri (URN);
107 fail_unless (ext != NULL);
108 gst_rtp_header_extension_set_id (ext, 1);
110 /* vad default to on */
111 caps = create_caps (SDP_NO_VAD);
112 fail_unless (gst_rtp_header_extension_set_attributes_from_caps (ext, caps));
113 gst_caps_unref (caps);
114 g_object_get (ext, "vad", &vad, NULL);
116 check_caps (ext, TRUE);
118 /* vad is disabled */
119 caps = create_caps (SDP_VAD_OFF);
120 fail_unless (gst_rtp_header_extension_set_attributes_from_caps (ext, caps));
121 gst_caps_unref (caps);
122 g_object_get (ext, "vad", &vad, NULL);
126 caps = create_caps (SDP_VAD_ON);
127 fail_unless (gst_rtp_header_extension_set_attributes_from_caps (ext, caps));
128 gst_caps_unref (caps);
129 g_object_get (ext, "vad", &vad, NULL);
133 caps = create_caps (SDP_VAD_WRONG);
134 fail_if (gst_rtp_header_extension_set_attributes_from_caps (ext, caps));
135 gst_caps_unref (caps);
137 gst_object_unref (ext);
142 GST_START_TEST (rtprfc6464_one_byte)
144 GstRTPHeaderExtension *ext;
145 GstRTPHeaderExtensionFlags flags;
149 GstAudioLevelMeta *meta;
151 gboolean voice = TRUE;
153 ext = gst_rtp_header_extension_create_from_uri (URN);
154 fail_unless (ext != NULL);
155 gst_rtp_header_extension_set_id (ext, 1);
157 flags = gst_rtp_header_extension_get_supported_flags (ext);
158 fail_unless (flags & GST_RTP_HEADER_EXTENSION_ONE_BYTE);
160 buffer = gst_buffer_new ();
161 meta = gst_buffer_add_audio_level_meta (buffer, level, voice);
163 size = gst_rtp_header_extension_get_max_size (ext, buffer);
164 fail_unless (size > 0);
165 data = g_malloc0 (size);
166 fail_unless (data != NULL);
168 /* Write extension */
170 gst_rtp_header_extension_write (ext, buffer,
171 GST_RTP_HEADER_EXTENSION_ONE_BYTE, buffer, data, size);
172 fail_unless (written == 1);
175 fail_unless (gst_buffer_remove_meta (buffer, (GstMeta *) meta));
176 fail_unless (gst_rtp_header_extension_read (ext,
177 GST_RTP_HEADER_EXTENSION_ONE_BYTE, data, size, buffer));
178 meta = gst_buffer_get_audio_level_meta (buffer);
179 fail_unless (meta != NULL);
180 fail_unless_equals_int (meta->level, level);
181 fail_unless (meta->voice_activity == voice);
184 gst_buffer_unref (buffer);
185 gst_object_unref (ext);
190 GST_START_TEST (rtprfc6464_two_bytes)
192 GstRTPHeaderExtension *ext;
193 GstRTPHeaderExtensionFlags flags;
197 GstAudioLevelMeta *meta;
199 gboolean voice = TRUE;
201 ext = gst_rtp_header_extension_create_from_uri (URN);
202 fail_unless (ext != NULL);
203 gst_rtp_header_extension_set_id (ext, 1);
205 flags = gst_rtp_header_extension_get_supported_flags (ext);
206 fail_unless (flags & GST_RTP_HEADER_EXTENSION_TWO_BYTE);
208 buffer = gst_buffer_new ();
209 meta = gst_buffer_add_audio_level_meta (buffer, level, voice);
211 size = gst_rtp_header_extension_get_max_size (ext, buffer);
212 fail_unless (size > 0);
213 data = g_malloc0 (size);
214 fail_unless (data != NULL);
216 /* Write extension */
218 gst_rtp_header_extension_write (ext, buffer,
219 GST_RTP_HEADER_EXTENSION_TWO_BYTE, buffer, data, size);
220 fail_unless (written == 2);
223 fail_unless (gst_buffer_remove_meta (buffer, (GstMeta *) meta));
224 fail_unless (gst_rtp_header_extension_read (ext,
225 GST_RTP_HEADER_EXTENSION_TWO_BYTE, data, size, buffer));
226 meta = gst_buffer_get_audio_level_meta (buffer);
227 fail_unless (meta != NULL);
228 fail_unless_equals_int (meta->level, level);
229 fail_unless (meta->voice_activity == voice);
232 gst_buffer_unref (buffer);
233 gst_object_unref (ext);
238 GST_START_TEST (rtprfc6464_no_meta)
240 GstRTPHeaderExtension *ext;
245 ext = gst_rtp_header_extension_create_from_uri (URN);
246 fail_unless (ext != NULL);
247 gst_rtp_header_extension_set_id (ext, 1);
249 buffer = gst_buffer_new ();
251 size = gst_rtp_header_extension_get_max_size (ext, buffer);
252 fail_unless (size > 0);
253 data = g_malloc0 (size);
254 fail_unless (data != NULL);
257 gst_rtp_header_extension_write (ext, buffer,
258 GST_RTP_HEADER_EXTENSION_ONE_BYTE, buffer, data, size);
259 fail_unless (written == 0);
262 gst_rtp_header_extension_write (ext, buffer,
263 GST_RTP_HEADER_EXTENSION_TWO_BYTE, buffer, data, size);
264 fail_unless (written == 0);
267 gst_buffer_unref (buffer);
268 gst_object_unref (ext);
274 rtprfc6464_suite (void)
276 Suite *s = suite_create ("rtprfc6464");
277 TCase *tc_chain = tcase_create ("general");
279 suite_add_tcase (s, tc_chain);
281 tcase_add_test (tc_chain, rtprfc6464_sdp);
282 tcase_add_test (tc_chain, rtprfc6464_one_byte);
283 tcase_add_test (tc_chain, rtprfc6464_two_bytes);
284 tcase_add_test (tc_chain, rtprfc6464_no_meta);
289 GST_CHECK_MAIN (rtprfc6464)