blob: 74508a0e3d4e5e9e0262a1c061127d0035ed5509 [file] [log] [blame]
Gregory Maxwella5ff49e2011-10-26 19:56:00 -04001/* Copyright (c) 2011 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
Jean-Marc Valincb05e7c2012-04-20 16:40:24 -040018 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Gregory Maxwella5ff49e2011-10-26 19:56:00 -040020 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>
Gian-Carlo Pascuttoc0edd632012-07-12 21:40:37 +020039#ifndef _WIN32
Gregory Maxwella5ff49e2011-10-26 19:56:00 -040040#include <unistd.h>
Gian-Carlo Pascuttoc0edd632012-07-12 21:40:37 +020041#endif
Ralph Giles7931a602011-10-28 11:29:41 -070042#include "opus.h"
Gregory Maxwella5ff49e2011-10-26 19:56:00 -040043#include "test_opus_common.h"
44
45#define MAX_PACKET (1500)
Gregory Maxwell8fcfe022011-10-28 22:47:20 -040046#define MAX_FRAME_SAMP (5760)
Gregory Maxwella5ff49e2011-10-26 19:56:00 -040047extern int jackpot;
48
Gregory Maxwella26b2be2011-12-14 02:03:50 -050049int test_decoder_code0(int no_fuzz)
Gregory Maxwella5ff49e2011-10-26 19:56:00 -040050{
51 static const opus_int32 fsv[5]={48000,24000,16000,12000,8000};
52 int err,skip,plen;
53 int out_samples,fec;
54 int t;
55 opus_int32 i;
56 OpusDecoder *dec[5*2];
Gregory Maxwell8fcfe022011-10-28 22:47:20 -040057 opus_int32 decsize;
58 OpusDecoder *decbak;
Gregory Maxwella5ff49e2011-10-26 19:56:00 -040059 opus_uint32 dec_final_range1,dec_final_range2,dec_final_acc;
60 unsigned char *packet;
61 unsigned char modes[4096];
62 short *outbuf_int;
63 short *outbuf;
64
65 dec_final_range1=dec_final_range2=2;
66
67 packet=malloc(sizeof(unsigned char)*MAX_PACKET);
68 if(packet==NULL)test_failed();
69
70 outbuf_int=malloc(sizeof(short)*(MAX_FRAME_SAMP+16)*2);
71 for(i=0;i<(MAX_FRAME_SAMP+16)*2;i++)outbuf_int[i]=32749;
72 outbuf=&outbuf_int[8*2];
73
74 fprintf(stdout," Starting %d decoders...\n",5*2);
75 for(t=0;t<5*2;t++)
76 {
77 int fs=fsv[t>>1];
78 int c=(t&1)+1;
79 err=OPUS_INTERNAL_ERROR;
80 dec[t] = opus_decoder_create(fs, c, &err);
81 if(err!=OPUS_OK || dec[t]==NULL)test_failed();
82 fprintf(stdout," opus_decoder_create(%5d,%d) OK. Copy ",fs,c);
83 {
84 OpusDecoder *dec2;
85 /*The opus state structures contain no pointers and can be freely copied*/
86 dec2=(OpusDecoder *)malloc(opus_decoder_get_size(c));
87 if(dec2==NULL)test_failed();
88 memcpy(dec2,dec[t],opus_decoder_get_size(c));
89 memset(dec[t],255,opus_decoder_get_size(c));
90 opus_decoder_destroy(dec[t]);
91 printf("OK.\n");
92 dec[t]=dec2;
93 }
94 }
95
Gregory Maxwelle699c192011-11-25 23:53:15 -050096 decsize=opus_decoder_get_size(1);
Gregory Maxwell8fcfe022011-10-28 22:47:20 -040097 decbak=(OpusDecoder *)malloc(decsize);
98 if(decbak==NULL)test_failed();
99
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400100 for(t=0;t<5*2;t++)
101 {
102 int factor=48000/fsv[t>>1];
103 for(fec=0;fec<2;fec++)
104 {
105 /*Test PLC on a fresh decoder*/
106 out_samples = opus_decode(dec[t], 0, 0, outbuf, MAX_FRAME_SAMP, fec);
107 if(out_samples!=120/factor)test_failed();
108
109 /*Test null pointer input*/
110 out_samples = opus_decode(dec[t], 0, -1, outbuf, MAX_FRAME_SAMP, fec);
111 if(out_samples!=120/factor)test_failed();
112 out_samples = opus_decode(dec[t], 0, 1, outbuf, MAX_FRAME_SAMP, fec);
113 if(out_samples!=120/factor)test_failed();
114 out_samples = opus_decode(dec[t], 0, 10, outbuf, MAX_FRAME_SAMP, fec);
115 if(out_samples!=120/factor)test_failed();
116 out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, MAX_FRAME_SAMP, fec);
117 if(out_samples!=120/factor)test_failed();
118
119 /*Zero lengths*/
120 out_samples = opus_decode(dec[t], packet, 0, outbuf, MAX_FRAME_SAMP, fec);
121 if(out_samples!=120/factor)test_failed();
122
123 /*Zero buffer*/
124 outbuf[0]=32749;
125 out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);
126 if(out_samples>0)test_failed();
127 out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
128 if(out_samples>0)test_failed();
129 if(outbuf[0]!=32749)test_failed();
130
131 /*Invalid lengths*/
132 out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);
133 if(out_samples>=0)test_failed();
134 out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);
135 if(out_samples>=0)test_failed();
136 out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);
137 if(out_samples>=0)test_failed();
138
139 /*Crazy FEC values*/
140 out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);
141 if(out_samples>=0)test_failed();
142
143 /*Reset the decoder*/
144 if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
145 }
146 }
147 fprintf(stdout," dec[all] initial frame PLC OK.\n");
148
149 /*Count code 0 tests*/
150 for(i=0;i<64;i++)
151 {
152 int j,expected[5*2];
153 packet[0]=i<<2;
154 packet[1]=255;
155 packet[2]=255;
156 err=opus_packet_get_nb_channels(packet);
157 if(err!=(i&1)+1)test_failed();
158
159 for(t=0;t<5*2;t++){
160 expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
161 if(expected[t]>2880)test_failed();
162 }
163
164 for(j=0;j<256;j++)
165 {
166 packet[1]=j;
167 for(t=0;t<5*2;t++)
168 {
169 out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
170 if(out_samples!=expected[t])test_failed();
171 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
172 if(t==0)dec_final_range2=dec_final_range1;
173 else if(dec_final_range1!=dec_final_range2)test_failed();
174 }
175 }
176
177 for(t=0;t<5*2;t++){
178 int factor=48000/fsv[t>>1];
179 /* The PLC is run for 6 frames in order to get better PLC coverage. */
180 for(j=0;j<6;j++)
181 {
182 out_samples = opus_decode(dec[t], 0, 0, outbuf, MAX_FRAME_SAMP, 0);
183 if(out_samples!=expected[t])test_failed();
184 }
185 /* Run the PLC once at 2.5ms, as a simulation of someone trying to
186 do small drift corrections. */
187 if(expected[t]!=120/factor)
188 {
189 out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
190 if(out_samples!=120/factor)test_failed();
191 }
192 out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
193 if(out_samples>0)test_failed();
194 }
195 }
196 fprintf(stdout," dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n");
197
Gregory Maxwell8770b072012-03-06 11:42:40 -0500198 if(no_fuzz)
199 {
200 fprintf(stdout," Skipping many tests which fuzz the decoder as requested.\n");
201 for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
202 printf(" Decoders stopped.\n");
203 free(outbuf_int);
204 free(packet);
205 return 0;
206 }
207
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400208 {
209 /*We only test a subset of the modes here simply because the longer
210 durations end up taking a long time.*/
211 static const int cmodes[4]={16,20,24,28};
212 static const opus_uint32 cres[4]={116290185,2172123586,2172123586,2172123586};
213 static const opus_uint32 lres[3]={3285687739,1481572662,694350475};
214 static const int lmodes[3]={0,4,8};
215 int mode=fast_rand()%4;
216
217 packet[0]=cmodes[mode]<<3;
218 dec_final_acc=0;
219 t=fast_rand()%10;
220
221 for(i=0;i<65536;i++)
222 {
223 int factor=48000/fsv[t>>1];
224 packet[1]=i>>8;
225 packet[2]=i&255;
226 packet[3]=255;
227 out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
228 if(out_samples!=120/factor)test_failed();
229 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
230 dec_final_acc+=dec_final_range1;
231 }
232 if(dec_final_acc!=cres[mode])test_failed();
233 fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]);
234
235 mode=fast_rand()%3;
236 packet[0]=lmodes[mode]<<3;
237 dec_final_acc=0;
238 t=fast_rand()%10;
239 for(i=0;i<65536;i++)
240 {
241 int factor=48000/fsv[t>>1];
242 packet[1]=i>>8;
243 packet[2]=i&255;
244 packet[3]=255;
245 out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
246 if(out_samples!=480/factor)test_failed();
247 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
248 dec_final_acc+=dec_final_range1;
249 }
250 if(dec_final_acc!=lres[mode])test_failed();
251 fprintf(stdout," dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]);
252 }
253
254 skip=fast_rand()%7;
255 for(i=0;i<64;i++)
256 {
257 int j,expected[5*2];
258 packet[0]=i<<2;
259 for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
260 for(j=2+skip;j<1275;j+=4)
261 {
262 int jj;
263 for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;
264 for(t=0;t<5*2;t++)
265 {
266 out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);
267 if(out_samples!=expected[t])test_failed();
268 opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
269 if(t==0)dec_final_range2=dec_final_range1;
270 else if(dec_final_range1!=dec_final_range2)test_failed();
271 }
272 }
273 }
274 fprintf(stdout," dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip);
275
276 debruijn2(64,modes);
277 plen=(fast_rand()%18+3)*8+skip+3;
278 for(i=0;i<4096;i++)
279 {
280 int j,expected[5*2];
281 packet[0]=modes[i]<<2;
282 for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
283 for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
Gregory Maxwell8fcfe022011-10-28 22:47:20 -0400284 memcpy(decbak,dec[0],decsize);
285 if(opus_decode(decbak, packet, plen+1, outbuf, MAX_FRAME_SAMP, 1)!=expected[0])test_failed();
286 memcpy(decbak,dec[0],decsize);
287 if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
288 memcpy(decbak,dec[0],decsize);
289 if(opus_decode(decbak, 0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400290 for(t=0;t<5*2;t++)
291 {
292 out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
293 if(out_samples!=expected[t])test_failed();
294 if(t==0)dec_final_range2=dec_final_range1;
295 else if(dec_final_range1!=dec_final_range2)test_failed();
296 }
297 }
298 fprintf(stdout," dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
299
300 plen=(fast_rand()%18+3)*8+skip+3;
301 t=rand()&3;
302 for(i=0;i<4096;i++)
303 {
304 int count,j,expected;
305 packet[0]=modes[i]<<2;
306 expected=opus_decoder_get_nb_samples(dec[t],packet,plen);
307 for(count=0;count<10;count++)
308 {
309 for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
310 out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
311 if(out_samples!=expected)test_failed();
312 }
313 }
314 fprintf(stdout," dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1);
315
316 {
317 int tmodes[1]={25<<2};
318 opus_uint32 tseeds[1]={140441};
319 int tlen[1]={157};
320 opus_int32 tret[1]={480};
321 t=fast_rand()&1;
322 for(i=0;i<1;i++)
323 {
324 int j;
325 packet[0]=tmodes[i];
326 Rw=Rz=tseeds[i];
327 for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;
328 out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);
329 if(out_samples!=tret[i])test_failed();
330 }
331 fprintf(stdout," dec[%3d] pre-selected random packets OK.\n",t);
332 }
333
Gregory Maxwellf99e3292012-06-01 02:27:36 -0400334 free(decbak);
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400335 for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
336 printf(" Decoders stopped.\n");
337
338 err=0;
339 for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
340 for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
341 if(err)test_failed();
342
343 free(outbuf_int);
344 free(packet);
345 return 0;
346}
347
348int main(int _argc, char **_argv)
349{
350 const char * oversion;
Gregory Maxwelle699c192011-11-25 23:53:15 -0500351 const char * env_seed;
352 int env_used;
353
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400354 if(_argc>2)
355 {
356 fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
357 return 1;
358 }
359
Gregory Maxwelle699c192011-11-25 23:53:15 -0500360 env_used=0;
361 env_seed=getenv("SEED");
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400362 if(_argc>1)iseed=atoi(_argv[1]);
Gregory Maxwelle699c192011-11-25 23:53:15 -0500363 else if(env_seed)
364 {
365 iseed=atoi(env_seed);
366 env_used=1;
367 }
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400368 else iseed=(opus_uint32)time(NULL)^((getpid()&65535)<<16);
369 Rw=Rz=iseed;
370
371 oversion=opus_get_version_string();
372 if(!oversion)test_failed();
373 fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
Gregory Maxwelle699c192011-11-25 23:53:15 -0500374 if(env_used)fprintf(stderr," Random seed set from the environment (SEED=%s).\n", env_seed);
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400375
Gregory Maxwella26b2be2011-12-14 02:03:50 -0500376 /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
377 into the decoders. This is helpful because garbage data
378 may cause the decoders to clip, which angers CLANG IOC.*/
379 test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL);
Gregory Maxwella5ff49e2011-10-26 19:56:00 -0400380
381 return 0;
382}