1*a58d3d2aSXin Li /* Copyright (c) 2023 Amazon
2*a58d3d2aSXin Li Written by Michael Klingbeil */
3*a58d3d2aSXin Li /*
4*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without
5*a58d3d2aSXin Li modification, are permitted provided that the following conditions
6*a58d3d2aSXin Li are met:
7*a58d3d2aSXin Li
8*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright
9*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer.
10*a58d3d2aSXin Li
11*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright
12*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the
13*a58d3d2aSXin Li documentation and/or other materials provided with the distribution.
14*a58d3d2aSXin Li
15*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*a58d3d2aSXin Li ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*a58d3d2aSXin Li LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18*a58d3d2aSXin Li A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19*a58d3d2aSXin Li OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20*a58d3d2aSXin Li EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21*a58d3d2aSXin Li PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22*a58d3d2aSXin Li PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23*a58d3d2aSXin Li LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24*a58d3d2aSXin Li NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25*a58d3d2aSXin Li SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*a58d3d2aSXin Li */
27*a58d3d2aSXin Li
28*a58d3d2aSXin Li #ifdef HAVE_CONFIG_H
29*a58d3d2aSXin Li #include "config.h"
30*a58d3d2aSXin Li #endif
31*a58d3d2aSXin Li
32*a58d3d2aSXin Li #include <stdio.h>
33*a58d3d2aSXin Li #include <stdlib.h>
34*a58d3d2aSXin Li #include <string.h>
35*a58d3d2aSXin Li #include <time.h>
36*a58d3d2aSXin Li #ifndef _WIN32
37*a58d3d2aSXin Li #include <unistd.h>
38*a58d3d2aSXin Li #else
39*a58d3d2aSXin Li #include <process.h>
40*a58d3d2aSXin Li #define getpid _getpid
41*a58d3d2aSXin Li #endif
42*a58d3d2aSXin Li
43*a58d3d2aSXin Li #include "../src/opus_private.h"
44*a58d3d2aSXin Li #include "test_opus_common.h"
45*a58d3d2aSXin Li
test_extensions_generate_success(void)46*a58d3d2aSXin Li void test_extensions_generate_success(void)
47*a58d3d2aSXin Li {
48*a58d3d2aSXin Li static const opus_extension_data ext[] = {
49*a58d3d2aSXin Li {2, 0, (const unsigned char *)"a", 1},
50*a58d3d2aSXin Li {32, 10, (const unsigned char *)"DRED", 4},
51*a58d3d2aSXin Li {33, 1, (const unsigned char *)"NOT DRED", 8},
52*a58d3d2aSXin Li {3, 4, (const unsigned char *)NULL, 0}
53*a58d3d2aSXin Li };
54*a58d3d2aSXin Li
55*a58d3d2aSXin Li int result;
56*a58d3d2aSXin Li unsigned char packet[32];
57*a58d3d2aSXin Li const unsigned char *p = packet;
58*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, 23+4, ext, 4, 1);
59*a58d3d2aSXin Li expect_true(result == 23+4, "expected length 23+4");
60*a58d3d2aSXin Li
61*a58d3d2aSXin Li /* expect padding */
62*a58d3d2aSXin Li expect_true(p[0] == 1 && p[1] == 1 && p[2] == 1 && p[3] == 1, "expected padding");
63*a58d3d2aSXin Li p += 4;
64*a58d3d2aSXin Li
65*a58d3d2aSXin Li /* extension ID=2 */
66*a58d3d2aSXin Li expect_true((p[0] >> 1) == 2, "expected extension id 2");
67*a58d3d2aSXin Li /* For extension IDs 1 through 31, L=0 means that no data follows the
68*a58d3d2aSXin Li extension, whereas L=1 means that exactly one byte of extension data follows. */
69*a58d3d2aSXin Li expect_true((p[0] & 0x01) == 1, "expected L-bit set");
70*a58d3d2aSXin Li /* content */
71*a58d3d2aSXin Li expect_true(p[1] == 'a', "expected extension content");
72*a58d3d2aSXin Li p += 2;
73*a58d3d2aSXin Li
74*a58d3d2aSXin Li /* next byte should increment the frame count, ID=1, L=0 */
75*a58d3d2aSXin Li expect_true(p[0] == 0x02, "bad frame separator");
76*a58d3d2aSXin Li p += 1;
77*a58d3d2aSXin Li /* extension ID=33 */
78*a58d3d2aSXin Li expect_true((p[0] >> 1) == 33, "expected extension id 33");
79*a58d3d2aSXin Li /* For IDs 32 to 127, L=0 signals that the extension data takes up the
80*a58d3d2aSXin Li rest of the padding, and L=1 signals that a length indicator follows. */
81*a58d3d2aSXin Li expect_true((p[0] & 0x01) == 1, "expected L-bit set");
82*a58d3d2aSXin Li /* content */
83*a58d3d2aSXin Li expect_true(p[1] == ext[2].len, "expected length");
84*a58d3d2aSXin Li p += 2;
85*a58d3d2aSXin Li expect_true(0 == memcmp(p, ext[2].data, ext[2].len), "expected extension content");
86*a58d3d2aSXin Li p += ext[2].len;
87*a58d3d2aSXin Li
88*a58d3d2aSXin Li /* advance to frame 4, increment by 3 */
89*a58d3d2aSXin Li /* next byte should increment the frame count, ID=1, L=1 */
90*a58d3d2aSXin Li expect_true(p[0] == 0x03, "bad frame separator");
91*a58d3d2aSXin Li expect_true(p[1] == 0x03, "bad frame increment");
92*a58d3d2aSXin Li p += 2;
93*a58d3d2aSXin Li /* extension ID=3 */
94*a58d3d2aSXin Li expect_true((p[0] >> 1) == 3, "expected extension id 3");
95*a58d3d2aSXin Li /* For extension IDs 1 through 31, L=0 means that no data follows the
96*a58d3d2aSXin Li extension, whereas L=1 means that exactly one byte of extension data follows. */
97*a58d3d2aSXin Li expect_true((p[0] & 0x01) == 0, "expected L-bit unset");
98*a58d3d2aSXin Li p += 1;
99*a58d3d2aSXin Li
100*a58d3d2aSXin Li /* advance to frame 10, increment by 6 */
101*a58d3d2aSXin Li /* next byte should increment the frame count, ID=1, L=1 */
102*a58d3d2aSXin Li expect_true(p[0] == 0x03, "bad frame separator");
103*a58d3d2aSXin Li expect_true(p[1] == 0x06, "bad frame increment");
104*a58d3d2aSXin Li p += 2;
105*a58d3d2aSXin Li /* extension ID=32 */
106*a58d3d2aSXin Li expect_true((p[0] >> 1) == 32, "expected extension id 32");
107*a58d3d2aSXin Li /* For IDs 32 to 127, L=0 signals that the extension data takes up the
108*a58d3d2aSXin Li rest of the padding */
109*a58d3d2aSXin Li expect_true((p[0] & 0x01) == 0, "expected L-bit unset");
110*a58d3d2aSXin Li p += 1;
111*a58d3d2aSXin Li expect_true(0 == memcmp(p, ext[1].data, ext[1].len), "expected extension content");
112*a58d3d2aSXin Li }
113*a58d3d2aSXin Li
test_extensions_generate_zero(void)114*a58d3d2aSXin Li void test_extensions_generate_zero(void)
115*a58d3d2aSXin Li {
116*a58d3d2aSXin Li int result;
117*a58d3d2aSXin Li unsigned char packet[32];
118*a58d3d2aSXin Li
119*a58d3d2aSXin Li /* zero length packet, zero extensions */
120*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, 0, NULL, 0, 1);
121*a58d3d2aSXin Li expect_true(result == 0, "expected length 0");
122*a58d3d2aSXin Li }
123*a58d3d2aSXin Li
test_extensions_generate_no_padding(void)124*a58d3d2aSXin Li void test_extensions_generate_no_padding(void)
125*a58d3d2aSXin Li {
126*a58d3d2aSXin Li static const opus_extension_data ext[] = {
127*a58d3d2aSXin Li {2, 0, (const unsigned char *)"a", 1},
128*a58d3d2aSXin Li {32, 10, (const unsigned char *)"DRED", 4},
129*a58d3d2aSXin Li {33, 1, (const unsigned char *)"NOT DRED", 8},
130*a58d3d2aSXin Li {3, 4, (const unsigned char *)NULL, 0}
131*a58d3d2aSXin Li };
132*a58d3d2aSXin Li
133*a58d3d2aSXin Li int result;
134*a58d3d2aSXin Li unsigned char packet[32];
135*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
136*a58d3d2aSXin Li expect_true(result == 23, "expected length 23");
137*a58d3d2aSXin Li }
138*a58d3d2aSXin Li
test_extensions_generate_fail(void)139*a58d3d2aSXin Li void test_extensions_generate_fail(void)
140*a58d3d2aSXin Li {
141*a58d3d2aSXin Li static const opus_extension_data ext[] = {
142*a58d3d2aSXin Li {2, 0, (const unsigned char *)"a", 1},
143*a58d3d2aSXin Li {32, 10, (const unsigned char *)"DRED", 4},
144*a58d3d2aSXin Li {33, 1, (const unsigned char *)"NOT DRED", 8},
145*a58d3d2aSXin Li {3, 4, (const unsigned char *)NULL, 0}
146*a58d3d2aSXin Li };
147*a58d3d2aSXin Li
148*a58d3d2aSXin Li int result;
149*a58d3d2aSXin Li unsigned char packet[100];
150*a58d3d2aSXin Li
151*a58d3d2aSXin Li /* buffer too small */
152*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, 4, ext, 4, 1);
153*a58d3d2aSXin Li expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
154*a58d3d2aSXin Li
155*a58d3d2aSXin Li /* invalid id */
156*a58d3d2aSXin Li {
157*a58d3d2aSXin Li static const opus_extension_data id_too_big[] = {
158*a58d3d2aSXin Li {256, 0, (const unsigned char *)"a", 1},
159*a58d3d2aSXin Li };
160*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), id_too_big, 1, 1);
161*a58d3d2aSXin Li expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
162*a58d3d2aSXin Li }
163*a58d3d2aSXin Li
164*a58d3d2aSXin Li /* invalid id */
165*a58d3d2aSXin Li {
166*a58d3d2aSXin Li static const opus_extension_data id_too_small[] = {
167*a58d3d2aSXin Li {1, 0, (const unsigned char *)"a", 1},
168*a58d3d2aSXin Li };
169*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), id_too_small, 1, 1);
170*a58d3d2aSXin Li expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
171*a58d3d2aSXin Li }
172*a58d3d2aSXin Li
173*a58d3d2aSXin Li /* frame index too big */
174*a58d3d2aSXin Li {
175*a58d3d2aSXin Li static const opus_extension_data frame_too_big[] = {
176*a58d3d2aSXin Li {33, 48, (const unsigned char *)"a", 1},
177*a58d3d2aSXin Li };
178*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), frame_too_big, 1, 1);
179*a58d3d2aSXin Li expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
180*a58d3d2aSXin Li }
181*a58d3d2aSXin Li
182*a58d3d2aSXin Li /* size too big for extension IDs 1 through 31 */
183*a58d3d2aSXin Li {
184*a58d3d2aSXin Li static const opus_extension_data size_too_big[] = {
185*a58d3d2aSXin Li {2, 0, (const unsigned char *)"abcd", 4},
186*a58d3d2aSXin Li };
187*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), size_too_big, 1, 1);
188*a58d3d2aSXin Li expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
189*a58d3d2aSXin Li }
190*a58d3d2aSXin Li
191*a58d3d2aSXin Li /* negative size for extension IDs 1 through 31 */
192*a58d3d2aSXin Li {
193*a58d3d2aSXin Li static const opus_extension_data neg_size[] = {
194*a58d3d2aSXin Li {2, 0, NULL, -4},
195*a58d3d2aSXin Li };
196*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), neg_size, 1, 1);
197*a58d3d2aSXin Li expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
198*a58d3d2aSXin Li }
199*a58d3d2aSXin Li
200*a58d3d2aSXin Li /* negative size for extension IDs 32 through 127 */
201*a58d3d2aSXin Li {
202*a58d3d2aSXin Li static const opus_extension_data neg_size_33[] = {
203*a58d3d2aSXin Li {33, 0, NULL, -4},
204*a58d3d2aSXin Li };
205*a58d3d2aSXin Li result = opus_packet_extensions_generate(packet, sizeof(packet), neg_size_33, 1, 1);
206*a58d3d2aSXin Li expect_true(result == OPUS_BAD_ARG, "expected OPUS_BAD_ARG");
207*a58d3d2aSXin Li }
208*a58d3d2aSXin Li }
209*a58d3d2aSXin Li
test_extensions_parse_success(void)210*a58d3d2aSXin Li void test_extensions_parse_success(void)
211*a58d3d2aSXin Li {
212*a58d3d2aSXin Li static const opus_extension_data ext[] = {
213*a58d3d2aSXin Li {2, 0, (const unsigned char *)"a", 1},
214*a58d3d2aSXin Li {32, 10, (const unsigned char *)"DRED", 4},
215*a58d3d2aSXin Li {33, 1, (const unsigned char *)"NOT DRED", 8},
216*a58d3d2aSXin Li {3, 4, (const unsigned char *)NULL, 0}
217*a58d3d2aSXin Li };
218*a58d3d2aSXin Li opus_extension_data ext_out[10];
219*a58d3d2aSXin Li int nb_ext;
220*a58d3d2aSXin Li int len, result;
221*a58d3d2aSXin Li unsigned char packet[32];
222*a58d3d2aSXin Li
223*a58d3d2aSXin Li nb_ext = 10;
224*a58d3d2aSXin Li len = opus_packet_extensions_generate(packet, 32, ext, 4, 1);
225*a58d3d2aSXin Li expect_true(len == 32, "expected length 32");
226*a58d3d2aSXin Li result = opus_packet_extensions_count(packet, len);
227*a58d3d2aSXin Li expect_true(result == 4, "expected opus_packet_extensions_count 4");
228*a58d3d2aSXin Li result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
229*a58d3d2aSXin Li expect_true(nb_ext == 4, "expected 4 extensions");
230*a58d3d2aSXin Li
231*a58d3d2aSXin Li expect_true(ext_out[0].id == 2, "expected id 2");
232*a58d3d2aSXin Li expect_true(ext_out[0].frame == 0, "expected frame 0");
233*a58d3d2aSXin Li expect_true(ext_out[0].len == 1, "expected len 1");
234*a58d3d2aSXin Li expect_true(0 == memcmp(ext_out[0].data, ext[0].data, 1), "expected data");
235*a58d3d2aSXin Li
236*a58d3d2aSXin Li expect_true(ext_out[1].id == 33, "expected id 33");
237*a58d3d2aSXin Li expect_true(ext_out[1].frame == 1, "expected frame 1");
238*a58d3d2aSXin Li expect_true(ext_out[1].len == 8, "expected len 8");
239*a58d3d2aSXin Li expect_true(0 == memcmp(ext_out[1].data, ext[2].data, 8), "expected data");
240*a58d3d2aSXin Li
241*a58d3d2aSXin Li expect_true(ext_out[2].id == 3, "expected id 3");
242*a58d3d2aSXin Li expect_true(ext_out[2].frame == 4, "expected frame 4");
243*a58d3d2aSXin Li expect_true(ext_out[2].len == 0, "expected len 0");
244*a58d3d2aSXin Li
245*a58d3d2aSXin Li expect_true(ext_out[3].id == 32, "expected id 32");
246*a58d3d2aSXin Li expect_true(ext_out[3].frame == 10, "expected frame 10");
247*a58d3d2aSXin Li expect_true(ext_out[3].len == 4, "expected len 4");
248*a58d3d2aSXin Li expect_true(0 == memcmp(ext_out[3].data, ext[1].data, 4), "expected data");
249*a58d3d2aSXin Li }
250*a58d3d2aSXin Li
test_extensions_parse_zero(void)251*a58d3d2aSXin Li void test_extensions_parse_zero(void)
252*a58d3d2aSXin Li {
253*a58d3d2aSXin Li static const opus_extension_data ext[] = {
254*a58d3d2aSXin Li {32, 1, (const unsigned char *)"DRED", 4},
255*a58d3d2aSXin Li };
256*a58d3d2aSXin Li int nb_ext;
257*a58d3d2aSXin Li int len, result;
258*a58d3d2aSXin Li unsigned char packet[32];
259*a58d3d2aSXin Li
260*a58d3d2aSXin Li len = opus_packet_extensions_generate(packet, 32, ext, 1, 1);
261*a58d3d2aSXin Li expect_true(len == 32, "expected length 32");
262*a58d3d2aSXin Li
263*a58d3d2aSXin Li nb_ext = 0;
264*a58d3d2aSXin Li result = opus_packet_extensions_parse(packet, len, NULL, &nb_ext);
265*a58d3d2aSXin Li expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
266*a58d3d2aSXin Li }
267*a58d3d2aSXin Li
test_extensions_parse_fail(void)268*a58d3d2aSXin Li void test_extensions_parse_fail(void)
269*a58d3d2aSXin Li {
270*a58d3d2aSXin Li static const opus_extension_data ext[] = {
271*a58d3d2aSXin Li {2, 0, (const unsigned char *)"a", 1},
272*a58d3d2aSXin Li {33, 1, (const unsigned char *)"NOT DRED", 8},
273*a58d3d2aSXin Li {3, 4, (const unsigned char *)NULL, 0},
274*a58d3d2aSXin Li {32, 10, (const unsigned char *)"DRED", 4}
275*a58d3d2aSXin Li };
276*a58d3d2aSXin Li opus_extension_data ext_out[10];
277*a58d3d2aSXin Li int nb_ext;
278*a58d3d2aSXin Li int len, result;
279*a58d3d2aSXin Li unsigned char packet[32];
280*a58d3d2aSXin Li
281*a58d3d2aSXin Li /* create invalid length */
282*a58d3d2aSXin Li len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
283*a58d3d2aSXin Li packet[4] = 255;
284*a58d3d2aSXin Li nb_ext = 10;
285*a58d3d2aSXin Li result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
286*a58d3d2aSXin Li expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
287*a58d3d2aSXin Li result = opus_packet_extensions_count(packet, len);
288*a58d3d2aSXin Li expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
289*a58d3d2aSXin Li
290*a58d3d2aSXin Li /* create invalid frame increment */
291*a58d3d2aSXin Li nb_ext = 10;
292*a58d3d2aSXin Li len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
293*a58d3d2aSXin Li packet[14] = 255;
294*a58d3d2aSXin Li result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
295*a58d3d2aSXin Li expect_true(result == OPUS_INVALID_PACKET, "expected OPUS_INVALID_PACKET");
296*a58d3d2aSXin Li /* note, opus_packet_extensions_count does not read the invalid frame increment
297*a58d3d2aSXin Li and tells us that we have 4 extensions */
298*a58d3d2aSXin Li result = opus_packet_extensions_count(packet, len);
299*a58d3d2aSXin Li expect_true(result == 4, "expected opus_packet_extensions_count to return 4");
300*a58d3d2aSXin Li
301*a58d3d2aSXin Li /* not enough space */
302*a58d3d2aSXin Li nb_ext = 1;
303*a58d3d2aSXin Li len = opus_packet_extensions_generate(packet, sizeof(packet), ext, 4, 0);
304*a58d3d2aSXin Li result = opus_packet_extensions_parse(packet, len, ext_out, &nb_ext);
305*a58d3d2aSXin Li expect_true(result == OPUS_BUFFER_TOO_SMALL, "expected OPUS_BUFFER_TOO_SMALL");
306*a58d3d2aSXin Li }
307*a58d3d2aSXin Li
308*a58d3d2aSXin Li #define NB_RANDOM_EXTENSIONS 100000000
309*a58d3d2aSXin Li #define MAX_EXTENSION_SIZE 200
310*a58d3d2aSXin Li #define MAX_NB_EXTENSIONS 100
311*a58d3d2aSXin Li
test_random_extensions_parse(void)312*a58d3d2aSXin Li void test_random_extensions_parse(void)
313*a58d3d2aSXin Li {
314*a58d3d2aSXin Li int i;
315*a58d3d2aSXin Li for (i=0;i<NB_RANDOM_EXTENSIONS;i++)
316*a58d3d2aSXin Li {
317*a58d3d2aSXin Li opus_extension_data ext_out[MAX_NB_EXTENSIONS];
318*a58d3d2aSXin Li int nb_ext;
319*a58d3d2aSXin Li unsigned char payload[MAX_EXTENSION_SIZE];
320*a58d3d2aSXin Li int len;
321*a58d3d2aSXin Li int j;
322*a58d3d2aSXin Li int result;
323*a58d3d2aSXin Li len = fast_rand()%(MAX_EXTENSION_SIZE+1);
324*a58d3d2aSXin Li for (j=0;j<len;j++)
325*a58d3d2aSXin Li payload[j] = fast_rand()&0xFF;
326*a58d3d2aSXin Li nb_ext = fast_rand()%(MAX_NB_EXTENSIONS+1);
327*a58d3d2aSXin Li result = opus_packet_extensions_parse(payload, len, ext_out, &nb_ext);
328*a58d3d2aSXin Li expect_true(result == OPUS_OK || result == OPUS_BUFFER_TOO_SMALL || result == OPUS_INVALID_PACKET, "expected OPUS_OK, OPUS_BUFFER_TOO_SMALL or OPUS_INVALID_PACKET");
329*a58d3d2aSXin Li /* Even if parsing fails, check that the extensions that got extracted make sense. */
330*a58d3d2aSXin Li for (j=0;j<nb_ext;j++)
331*a58d3d2aSXin Li {
332*a58d3d2aSXin Li expect_true(ext_out[j].frame >= 0 && ext_out[j].frame < 48, "expected frame between 0 and 47");
333*a58d3d2aSXin Li expect_true(ext_out[j].id >= 2 && ext_out[j].id <= 127, "expected id between 2 and 127");
334*a58d3d2aSXin Li expect_true(ext_out[j].data >= payload && ext_out[j].data+ext_out[j].len <= payload+len, "expected data to be within packet");
335*a58d3d2aSXin Li }
336*a58d3d2aSXin Li }
337*a58d3d2aSXin Li }
338*a58d3d2aSXin Li
test_opus_repacketizer_out_range_impl(void)339*a58d3d2aSXin Li void test_opus_repacketizer_out_range_impl(void)
340*a58d3d2aSXin Li {
341*a58d3d2aSXin Li OpusRepacketizer rp;
342*a58d3d2aSXin Li unsigned char packet[1024];
343*a58d3d2aSXin Li unsigned char packet_out[1024];
344*a58d3d2aSXin Li opus_int16 size[48];
345*a58d3d2aSXin Li const unsigned char *padding;
346*a58d3d2aSXin Li opus_int32 padding_len;
347*a58d3d2aSXin Li opus_extension_data ext_out[10];
348*a58d3d2aSXin Li int i;
349*a58d3d2aSXin Li int nb_ext;
350*a58d3d2aSXin Li int res, len;
351*a58d3d2aSXin Li int first_count = 0, second_count = 0;
352*a58d3d2aSXin Li static const opus_extension_data ext[] = {
353*a58d3d2aSXin Li {33, 0, (const unsigned char *)"abcdefg", 7},
354*a58d3d2aSXin Li {100, 0, (const unsigned char *)"uvwxyz", 6},
355*a58d3d2aSXin Li };
356*a58d3d2aSXin Li
357*a58d3d2aSXin Li opus_repacketizer_init(&rp);
358*a58d3d2aSXin Li
359*a58d3d2aSXin Li memset(packet, 0, sizeof(packet));
360*a58d3d2aSXin Li /* Hybrid Packet with 20 msec frames, Code 3 */
361*a58d3d2aSXin Li packet[0] = (15 << 3) | 3;
362*a58d3d2aSXin Li /* Code 3, padding bit set, 1 frame */
363*a58d3d2aSXin Li packet[1] = 1 << 6 | 1;
364*a58d3d2aSXin Li packet[2] = 0;
365*a58d3d2aSXin Li packet[3] = 0;
366*a58d3d2aSXin Li
367*a58d3d2aSXin Li /* generate 2 extensions, id 33 and 100 */
368*a58d3d2aSXin Li len = opus_packet_extensions_generate(&packet[4], sizeof(packet)-4, ext, 2, 0);
369*a58d3d2aSXin Li /* update the padding length */
370*a58d3d2aSXin Li packet[2] = len;
371*a58d3d2aSXin Li
372*a58d3d2aSXin Li /* concatenate 3 frames */
373*a58d3d2aSXin Li res = opus_repacketizer_cat(&rp, packet, 4+len);
374*a58d3d2aSXin Li /* for the middle frame, no padding, no extensions */
375*a58d3d2aSXin Li packet[1] = 1;
376*a58d3d2aSXin Li res = opus_repacketizer_cat(&rp, packet, 4);
377*a58d3d2aSXin Li /* switch back to extensions for the last frame extensions */
378*a58d3d2aSXin Li packet[1] = 1 << 6 | 1;
379*a58d3d2aSXin Li res = opus_repacketizer_cat(&rp, packet, 4+len);
380*a58d3d2aSXin Li
381*a58d3d2aSXin Li expect_true(rp.nb_frames == 3, "Expected 3 frames");
382*a58d3d2aSXin Li res = opus_repacketizer_out_range_impl(&rp,
383*a58d3d2aSXin Li 0, 3, /* begin, end */
384*a58d3d2aSXin Li packet_out, /* unsigned char *data */
385*a58d3d2aSXin Li sizeof(packet_out), /* opus_int32 maxlen */
386*a58d3d2aSXin Li 0, /*int self_delimited */
387*a58d3d2aSXin Li 0, /* int pad */
388*a58d3d2aSXin Li NULL, /* const opus_extension_data *extensions */
389*a58d3d2aSXin Li 0 /* int nb_extensions */);
390*a58d3d2aSXin Li expect_true(res > 0, "expected valid packet length");
391*a58d3d2aSXin Li
392*a58d3d2aSXin Li /* now verify that we have the expected extensions */
393*a58d3d2aSXin Li res = opus_packet_parse_impl(packet_out, res, 0, NULL, NULL, size,
394*a58d3d2aSXin Li NULL, NULL, &padding, &padding_len);
395*a58d3d2aSXin Li nb_ext = 10;
396*a58d3d2aSXin Li res = opus_packet_extensions_parse(padding, padding_len, ext_out, &nb_ext);
397*a58d3d2aSXin Li expect_true(nb_ext == 4, "Expected 4 extensions");
398*a58d3d2aSXin Li for (i = 0 ; i < nb_ext; i++)
399*a58d3d2aSXin Li {
400*a58d3d2aSXin Li if (ext_out[i].id == 33)
401*a58d3d2aSXin Li {
402*a58d3d2aSXin Li opus_test_assert(ext_out[i].len == ext[0].len);
403*a58d3d2aSXin Li opus_test_assert(0 == memcmp(ext_out[i].data, ext[0].data, ext[0].len));
404*a58d3d2aSXin Li first_count++;
405*a58d3d2aSXin Li }
406*a58d3d2aSXin Li else if (ext_out[i].id == 100)
407*a58d3d2aSXin Li {
408*a58d3d2aSXin Li opus_test_assert(ext_out[i].len == ext[1].len);
409*a58d3d2aSXin Li opus_test_assert(0 == memcmp(ext_out[i].data, ext[1].data, ext[1].len));
410*a58d3d2aSXin Li second_count++;
411*a58d3d2aSXin Li }
412*a58d3d2aSXin Li if (i < 2)
413*a58d3d2aSXin Li opus_test_assert(ext_out[i].frame == 0)
414*a58d3d2aSXin Li else
415*a58d3d2aSXin Li opus_test_assert(ext_out[i].frame == 2)
416*a58d3d2aSXin Li }
417*a58d3d2aSXin Li opus_test_assert(first_count == 2);
418*a58d3d2aSXin Li opus_test_assert(second_count == 2);
419*a58d3d2aSXin Li }
420*a58d3d2aSXin Li
main(int argc,char ** argv)421*a58d3d2aSXin Li int main(int argc, char **argv)
422*a58d3d2aSXin Li {
423*a58d3d2aSXin Li int env_used;
424*a58d3d2aSXin Li char *env_seed;
425*a58d3d2aSXin Li env_used=0;
426*a58d3d2aSXin Li env_seed=getenv("SEED");
427*a58d3d2aSXin Li if(argc>1)iseed=atoi(argv[1]);
428*a58d3d2aSXin Li else if(env_seed)
429*a58d3d2aSXin Li {
430*a58d3d2aSXin Li iseed=atoi(env_seed);
431*a58d3d2aSXin Li env_used=1;
432*a58d3d2aSXin Li }
433*a58d3d2aSXin Li else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
434*a58d3d2aSXin Li Rw=Rz=iseed;
435*a58d3d2aSXin Li
436*a58d3d2aSXin Li fprintf(stderr,"Testing extensions. Random seed: %u (%.4X)\n", iseed, fast_rand() % 65535);
437*a58d3d2aSXin Li if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed);
438*a58d3d2aSXin Li
439*a58d3d2aSXin Li test_extensions_generate_success();
440*a58d3d2aSXin Li test_extensions_generate_zero();
441*a58d3d2aSXin Li test_extensions_generate_no_padding();
442*a58d3d2aSXin Li test_extensions_generate_fail();
443*a58d3d2aSXin Li test_extensions_parse_success();
444*a58d3d2aSXin Li test_extensions_parse_zero();
445*a58d3d2aSXin Li test_extensions_parse_fail();
446*a58d3d2aSXin Li test_random_extensions_parse();
447*a58d3d2aSXin Li test_opus_repacketizer_out_range_impl();
448*a58d3d2aSXin Li fprintf(stderr,"Tests completed successfully.\n");
449*a58d3d2aSXin Li return 0;
450*a58d3d2aSXin Li }
451