Mercurial > hg > sv-dependency-builds
comparison src/opus-1.3/tests/test_opus_decode.c @ 154:4664ac0c1032
Add Opus sources and macOS builds
author | Chris Cannam <cannam@all-day-breakfast.com> |
---|---|
date | Wed, 23 Jan 2019 13:48:08 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
153:84bc3a5ec321 | 154:4664ac0c1032 |
---|---|
1 /* Copyright (c) 2011-2013 Xiph.Org Foundation | |
2 Written by Gregory Maxwell */ | |
3 /* | |
4 Redistribution and use in source and binary forms, with or without | |
5 modification, are permitted provided that the following conditions | |
6 are met: | |
7 | |
8 - Redistributions of source code must retain the above copyright | |
9 notice, this list of conditions and the following disclaimer. | |
10 | |
11 - Redistributions in binary form must reproduce the above copyright | |
12 notice, this list of conditions and the following disclaimer in the | |
13 documentation and/or other materials provided with the distribution. | |
14 | |
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | |
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 */ | |
27 | |
28 #ifdef HAVE_CONFIG_H | |
29 #include "config.h" | |
30 #endif | |
31 | |
32 #include <stdio.h> | |
33 #include <stdlib.h> | |
34 #include <limits.h> | |
35 #include <stdint.h> | |
36 #include <math.h> | |
37 #include <string.h> | |
38 #include <time.h> | |
39 #if (!defined WIN32 && !defined _WIN32) || defined(__MINGW32__) | |
40 #include <unistd.h> | |
41 #else | |
42 #include <process.h> | |
43 #define getpid _getpid | |
44 #endif | |
45 #include "opus.h" | |
46 #include "test_opus_common.h" | |
47 | |
48 #define MAX_PACKET (1500) | |
49 #define MAX_FRAME_SAMP (5760) | |
50 | |
51 int test_decoder_code0(int no_fuzz) | |
52 { | |
53 static const opus_int32 fsv[5]={48000,24000,16000,12000,8000}; | |
54 int err,skip,plen; | |
55 int out_samples,fec; | |
56 int t; | |
57 opus_int32 i; | |
58 OpusDecoder *dec[5*2]; | |
59 opus_int32 decsize; | |
60 OpusDecoder *decbak; | |
61 opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc; | |
62 unsigned char *packet; | |
63 unsigned char modes[4096]; | |
64 short *outbuf_int; | |
65 short *outbuf; | |
66 | |
67 dec_final_range1=dec_final_range2=2; | |
68 | |
69 packet=malloc(sizeof(unsigned char)*MAX_PACKET); | |
70 if(packet==NULL)test_failed(); | |
71 | |
72 outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2); | |
73 for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749; | |
74 outbuf=&outbuf_int[8*2]; | |
75 | |
76 fprintf(stdout," Starting %d decoders...\n",5*2); | |
77 for(t=0;t<5*2;t++) | |
78 { | |
79 int fs=fsv[t>>1]; | |
80 int c=(t&1)+1; | |
81 err=OPUS_INTERNAL_ERROR; | |
82 dec[t] = opus_decoder_create(fs, c, &err); | |
83 if(err!=OPUS_OK || dec[t]==NULL)test_failed(); | |
84 fprintf(stdout," opus_decoder_create(%5d,%d) OK. Copy ",fs,c); | |
85 { | |
86 OpusDecoder *dec2; | |
87 /*The opus state structures contain no pointers and can be freely copied*/ | |
88 dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c)); | |
89 if(dec2==NULL)test_failed(); | |
90 memcpy(dec2,dec[t],opus_decoder_get_size(c)); | |
91 memset(dec[t],255,opus_decoder_get_size(c)); | |
92 opus_decoder_destroy(dec[t]); | |
93 printf("OK.\n"); | |
94 dec[t]=dec2; | |
95 } | |
96 } | |
97 | |
98 decsize=opus_decoder_get_size(1); | |
99 decbak=(OpusDecoder *)malloc(decsize); | |
100 if(decbak==NULL)test_failed(); | |
101 | |
102 for(t=0;t<5*2;t++) | |
103 { | |
104 int factor=48000/fsv[t>>1]; | |
105 for(fec=0;fec<2;fec++) | |
106 { | |
107 opus_int32 dur; | |
108 /*Test PLC on a fresh decoder*/ | |
109 out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec); | |
110 if(out_samples!=120/factor)test_failed(); | |
111 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); | |
112 if(dur!=120/factor)test_failed(); | |
113 | |
114 /*Test on a size which isn't a multiple of 2.5ms*/ | |
115 out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec); | |
116 if(out_samples!=OPUS_BAD_ARG)test_failed(); | |
117 | |
118 /*Test null pointer input*/ | |
119 out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec); | |
120 if(out_samples!=120/factor)test_failed(); | |
121 out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec); | |
122 if(out_samples!=120/factor)test_failed(); | |
123 out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec); | |
124 if(out_samples!=120/factor)test_failed(); | |
125 out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec); | |
126 if(out_samples!=120/factor)test_failed(); | |
127 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); | |
128 if(dur!=120/factor)test_failed(); | |
129 | |
130 /*Zero lengths*/ | |
131 out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec); | |
132 if(out_samples!=120/factor)test_failed(); | |
133 | |
134 /*Zero buffer*/ | |
135 outbuf[0]=32749; | |
136 out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec); | |
137 if(out_samples>0)test_failed(); | |
138 #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3)) | |
139 #pragma GCC diagnostic push | |
140 #pragma GCC diagnostic ignored "-Wnonnull" | |
141 #endif | |
142 out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec); | |
143 #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3)) | |
144 #pragma GCC diagnostic pop | |
145 #endif | |
146 if(out_samples>0)test_failed(); | |
147 if(outbuf[0]!=32749)test_failed(); | |
148 | |
149 /*Invalid lengths*/ | |
150 out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec); | |
151 if(out_samples>=0)test_failed(); | |
152 out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec); | |
153 if(out_samples>=0)test_failed(); | |
154 out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec); | |
155 if(out_samples>=0)test_failed(); | |
156 | |
157 /*Crazy FEC values*/ | |
158 out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2); | |
159 if(out_samples>=0)test_failed(); | |
160 | |
161 /*Reset the decoder*/ | |
162 if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed(); | |
163 } | |
164 } | |
165 fprintf(stdout," dec[all] initial frame PLC OK.\n"); | |
166 | |
167 /*Count code 0 tests*/ | |
168 for(i=0;i<64;i++) | |
169 { | |
170 opus_int32 dur; | |
171 int j,expected[5*2]; | |
172 packet[0]=i<<2; | |
173 packet[1]=255; | |
174 packet[2]=255; | |
175 err=opus_packet_get_nb_channels(packet); | |
176 if(err!=(i&1)+1)test_failed(); | |
177 | |
178 for(t=0;t<5*2;t++){ | |
179 expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1); | |
180 if(expected[t]>2880)test_failed(); | |
181 } | |
182 | |
183 for(j=0;j<256;j++) | |
184 { | |
185 packet[1]=j; | |
186 for(t=0;t<5*2;t++) | |
187 { | |
188 out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0); | |
189 if(out_samples!=expected[t])test_failed(); | |
190 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); | |
191 if(dur!=out_samples)test_failed(); | |
192 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); | |
193 if(t==0)dec_final_range2=dec_final_range1; | |
194 else if(dec_final_range1!=dec_final_range2)test_failed(); | |
195 } | |
196 } | |
197 | |
198 for(t=0;t<5*2;t++){ | |
199 int factor=48000/fsv[t>>1]; | |
200 /* The PLC is run for 6 frames in order to get better PLC coverage. */ | |
201 for(j=0;j<6;j++) | |
202 { | |
203 out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0); | |
204 if(out_samples!=expected[t])test_failed(); | |
205 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); | |
206 if(dur!=out_samples)test_failed(); | |
207 } | |
208 /* Run the PLC once at 2.5ms, as a simulation of someone trying to | |
209 do small drift corrections. */ | |
210 if(expected[t]!=120/factor) | |
211 { | |
212 out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0); | |
213 if(out_samples!=120/factor)test_failed(); | |
214 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); | |
215 if(dur!=out_samples)test_failed(); | |
216 } | |
217 out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0); | |
218 if(out_samples>0)test_failed(); | |
219 } | |
220 } | |
221 fprintf(stdout," dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n"); | |
222 | |
223 if(no_fuzz) | |
224 { | |
225 fprintf(stdout," Skipping many tests which fuzz the decoder as requested.\n"); | |
226 free(decbak); | |
227 for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]); | |
228 printf(" Decoders stopped.\n"); | |
229 | |
230 err=0; | |
231 for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749; | |
232 for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749; | |
233 if(err)test_failed(); | |
234 | |
235 free(outbuf_int); | |
236 free(packet); | |
237 return 0; | |
238 } | |
239 | |
240 { | |
241 /*We only test a subset of the modes here simply because the longer | |
242 durations end up taking a long time.*/ | |
243 static const int cmodes[4]={16,20,24,28}; | |
244 static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u}; | |
245 static const opus_uint32 lres[3]={3285687739u,1481572662,694350475}; | |
246 static const int lmodes[3]={0,4,8}; | |
247 int mode=fast_rand()%4; | |
248 | |
249 packet[0]=cmodes[mode]<<3; | |
250 dec_final_acc=0; | |
251 t=fast_rand()%10; | |
252 | |
253 for(i=0;i<65536;i++) | |
254 { | |
255 int factor=48000/fsv[t>>1]; | |
256 packet[1]=i>>8; | |
257 packet[2]=i&255; | |
258 packet[3]=255; | |
259 out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0); | |
260 if(out_samples!=120/factor)test_failed(); | |
261 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); | |
262 dec_final_acc+=dec_final_range1; | |
263 } | |
264 if(dec_final_acc!=cres[mode])test_failed(); | |
265 fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]); | |
266 | |
267 mode=fast_rand()%3; | |
268 packet[0]=lmodes[mode]<<3; | |
269 dec_final_acc=0; | |
270 t=fast_rand()%10; | |
271 for(i=0;i<65536;i++) | |
272 { | |
273 int factor=48000/fsv[t>>1]; | |
274 packet[1]=i>>8; | |
275 packet[2]=i&255; | |
276 packet[3]=255; | |
277 out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0); | |
278 if(out_samples!=480/factor)test_failed(); | |
279 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); | |
280 dec_final_acc+=dec_final_range1; | |
281 } | |
282 if(dec_final_acc!=lres[mode])test_failed(); | |
283 fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]); | |
284 } | |
285 | |
286 skip=fast_rand()%7; | |
287 for(i=0;i<64;i++) | |
288 { | |
289 int j,expected[5*2]; | |
290 packet[0]=i<<2; | |
291 for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1); | |
292 for(j=2+skip;j<1275;j+=4) | |
293 { | |
294 int jj; | |
295 for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255; | |
296 for(t=0;t<5*2;t++) | |
297 { | |
298 out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0); | |
299 if(out_samples!=expected[t])test_failed(); | |
300 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1)); | |
301 if(t==0)dec_final_range2=dec_final_range1; | |
302 else if(dec_final_range1!=dec_final_range2)test_failed(); | |
303 } | |
304 } | |
305 } | |
306 fprintf(stdout," dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip); | |
307 | |
308 debruijn2(64,modes); | |
309 plen=(fast_rand()%18+3)*8+skip+3; | |
310 for(i=0;i<4096;i++) | |
311 { | |
312 int j,expected[5*2]; | |
313 packet[0]=modes[i]<<2; | |
314 for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen); | |
315 for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255; | |
316 memcpy(decbak,dec[0],decsize); | |
317 if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed(); | |
318 memcpy(decbak,dec[0],decsize); | |
319 if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed(); | |
320 memcpy(decbak,dec[0],decsize); | |
321 if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed(); | |
322 for(t=0;t<5*2;t++) | |
323 { | |
324 opus_int32 dur; | |
325 out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0); | |
326 if(out_samples!=expected[t])test_failed(); | |
327 if(t==0)dec_final_range2=dec_final_range1; | |
328 else if(dec_final_range1!=dec_final_range2)test_failed(); | |
329 if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed(); | |
330 if(dur!=out_samples)test_failed(); | |
331 } | |
332 } | |
333 fprintf(stdout," dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1); | |
334 | |
335 plen=(fast_rand()%18+3)*8+skip+3; | |
336 t=rand()&3; | |
337 for(i=0;i<4096;i++) | |
338 { | |
339 int count,j,expected; | |
340 packet[0]=modes[i]<<2; | |
341 expected=opus_decoder_get_nb_samples(dec[t],packet,plen); | |
342 for(count=0;count<10;count++) | |
343 { | |
344 for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255; | |
345 out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0); | |
346 if(out_samples!=expected)test_failed(); | |
347 } | |
348 } | |
349 fprintf(stdout," dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1); | |
350 | |
351 { | |
352 int tmodes[1]={25<<2}; | |
353 opus_uint32 tseeds[1]={140441}; | |
354 int tlen[1]={157}; | |
355 opus_int32 tret[1]={480}; | |
356 t=fast_rand()&1; | |
357 for(i=0;i<1;i++) | |
358 { | |
359 int j; | |
360 packet[0]=tmodes[i]; | |
361 Rw=Rz=tseeds[i]; | |
362 for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255; | |
363 out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0); | |
364 if(out_samples!=tret[i])test_failed(); | |
365 } | |
366 fprintf(stdout," dec[%3d] pre-selected random packets OK.\n",t); | |
367 } | |
368 | |
369 free(decbak); | |
370 for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]); | |
371 printf(" Decoders stopped.\n"); | |
372 | |
373 err=0; | |
374 for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749; | |
375 for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749; | |
376 if(err)test_failed(); | |
377 | |
378 free(outbuf_int); | |
379 free(packet); | |
380 return 0; | |
381 } | |
382 | |
383 #ifndef DISABLE_FLOAT_API | |
384 void test_soft_clip(void) | |
385 { | |
386 int i,j; | |
387 float x[1024]; | |
388 float s[8] = {0, 0, 0, 0, 0, 0, 0, 0}; | |
389 fprintf(stdout," Testing opus_pcm_soft_clip... "); | |
390 for(i=0;i<1024;i++) | |
391 { | |
392 for (j=0;j<1024;j++) | |
393 { | |
394 x[j]=(j&255)*(1/32.f)-4.f; | |
395 } | |
396 opus_pcm_soft_clip(&x[i],1024-i,1,s); | |
397 for (j=i;j<1024;j++) | |
398 { | |
399 if(x[j]>1.f)test_failed(); | |
400 if(x[j]<-1.f)test_failed(); | |
401 } | |
402 } | |
403 for(i=1;i<9;i++) | |
404 { | |
405 for (j=0;j<1024;j++) | |
406 { | |
407 x[j]=(j&255)*(1/32.f)-4.f; | |
408 } | |
409 opus_pcm_soft_clip(x,1024/i,i,s); | |
410 for (j=0;j<(1024/i)*i;j++) | |
411 { | |
412 if(x[j]>1.f)test_failed(); | |
413 if(x[j]<-1.f)test_failed(); | |
414 } | |
415 } | |
416 opus_pcm_soft_clip(x,0,1,s); | |
417 opus_pcm_soft_clip(x,1,0,s); | |
418 opus_pcm_soft_clip(x,1,1,0); | |
419 opus_pcm_soft_clip(x,1,-1,s); | |
420 opus_pcm_soft_clip(x,-1,1,s); | |
421 opus_pcm_soft_clip(0,1,1,s); | |
422 printf("OK.\n"); | |
423 } | |
424 #endif | |
425 | |
426 int main(int _argc, char **_argv) | |
427 { | |
428 const char * oversion; | |
429 const char * env_seed; | |
430 int env_used; | |
431 | |
432 if(_argc>2) | |
433 { | |
434 fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]); | |
435 return 1; | |
436 } | |
437 | |
438 env_used=0; | |
439 env_seed=getenv("SEED"); | |
440 if(_argc>1)iseed=atoi(_argv[1]); | |
441 else if(env_seed) | |
442 { | |
443 iseed=atoi(env_seed); | |
444 env_used=1; | |
445 } | |
446 else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16); | |
447 Rw=Rz=iseed; | |
448 | |
449 oversion=opus_get_version_string(); | |
450 if(!oversion)test_failed(); | |
451 fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535); | |
452 if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed); | |
453 | |
454 /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data | |
455 into the decoders. This is helpful because garbage data | |
456 may cause the decoders to clip, which angers CLANG IOC.*/ | |
457 test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL); | |
458 #ifndef DISABLE_FLOAT_API | |
459 test_soft_clip(); | |
460 #endif | |
461 | |
462 return 0; | |
463 } |