• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
test_decoder_code0(int no_fuzz)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
test_soft_clip(void)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 
main(int _argc,char ** _argv)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 }
464