xref: /aosp_15_r20/external/libopus/tests/test_opus_decode.c (revision a58d3d2adb790c104798cd88c8a3aff4fa8b82cc)
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 #ifndef _WIN32
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 #if defined(ENABLE_OSCE) || defined(ENABLE_DEEP_PLC)
109          opus_decoder_ctl(dec[t], OPUS_SET_COMPLEXITY(fast_rand()%11));
110 #endif
111          /*Test PLC on a fresh decoder*/
112          out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, fec);
113          if(out_samples!=120/factor)test_failed();
114          if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
115          if(dur!=120/factor)test_failed();
116 
117          /*Test on a size which isn't a multiple of 2.5ms*/
118          out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor+2, fec);
119          if(out_samples!=OPUS_BAD_ARG)test_failed();
120 
121          /*Test null pointer input*/
122          out_samples = opus_decode(dec[t], 0, -1, outbuf, 120/factor, fec);
123          if(out_samples!=120/factor)test_failed();
124          out_samples = opus_decode(dec[t], 0, 1, outbuf, 120/factor, fec);
125          if(out_samples!=120/factor)test_failed();
126          out_samples = opus_decode(dec[t], 0, 10, outbuf, 120/factor, fec);
127          if(out_samples!=120/factor)test_failed();
128          out_samples = opus_decode(dec[t], 0, fast_rand(), outbuf, 120/factor, fec);
129          if(out_samples!=120/factor)test_failed();
130          if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
131          if(dur!=120/factor)test_failed();
132 
133          /*Zero lengths*/
134          out_samples = opus_decode(dec[t], packet, 0, outbuf, 120/factor, fec);
135          if(out_samples!=120/factor)test_failed();
136 
137          /*Zero buffer*/
138          outbuf[0]=32749;
139          out_samples = opus_decode(dec[t], packet, 0, outbuf, 0, fec);
140          if(out_samples>0)test_failed();
141 #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
142 #pragma GCC diagnostic push
143 #pragma GCC diagnostic ignored "-Wnonnull"
144 #endif
145          out_samples = opus_decode(dec[t], packet, 0, 0, 0, fec);
146 #if !defined(OPUS_BUILD) && (OPUS_GNUC_PREREQ(4, 6) || (defined(__clang_major__) && __clang_major__ >= 3))
147 #pragma GCC diagnostic pop
148 #endif
149          if(out_samples>0)test_failed();
150          if(outbuf[0]!=32749)test_failed();
151 
152          /*Invalid lengths*/
153          out_samples = opus_decode(dec[t], packet, -1, outbuf, MAX_FRAME_SAMP, fec);
154          if(out_samples>=0)test_failed();
155          out_samples = opus_decode(dec[t], packet, INT_MIN, outbuf, MAX_FRAME_SAMP, fec);
156          if(out_samples>=0)test_failed();
157          out_samples = opus_decode(dec[t], packet, -1, outbuf, -1, fec);
158          if(out_samples>=0)test_failed();
159 
160          /*Crazy FEC values*/
161          out_samples = opus_decode(dec[t], packet, 1, outbuf, MAX_FRAME_SAMP, fec?-1:2);
162          if(out_samples>=0)test_failed();
163 
164          /*Reset the decoder*/
165          if(opus_decoder_ctl(dec[t], OPUS_RESET_STATE)!=OPUS_OK)test_failed();
166       }
167    }
168    fprintf(stdout,"  dec[all] initial frame PLC OK.\n");
169 
170    /*Count code 0 tests*/
171    for(i=0;i<64;i++)
172    {
173       opus_int32 dur;
174       int j,expected[5*2];
175       packet[0]=i<<2;
176       packet[1]=255;
177       packet[2]=255;
178       err=opus_packet_get_nb_channels(packet);
179       if(err!=(i&1)+1)test_failed();
180 
181       for(t=0;t<5*2;t++){
182          expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
183          if(expected[t]>2880)test_failed();
184       }
185 
186       for(j=0;j<256;j++)
187       {
188          packet[1]=j;
189          for(t=0;t<5*2;t++)
190          {
191 #if defined(ENABLE_OSCE) || defined(ENABLE_DEEP_PLC)
192             opus_decoder_ctl(dec[t], OPUS_SET_COMPLEXITY(fast_rand()%11));
193 #endif
194             out_samples = opus_decode(dec[t], packet, 3, outbuf, MAX_FRAME_SAMP, 0);
195             if(out_samples!=expected[t])test_failed();
196             if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
197             if(dur!=out_samples)test_failed();
198             opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
199             if(t==0)dec_final_range2=dec_final_range1;
200             else if(dec_final_range1!=dec_final_range2)test_failed();
201          }
202       }
203 
204       for(t=0;t<5*2;t++){
205          int factor=48000/fsv[t>>1];
206          /* The PLC is run for 6 frames in order to get better PLC coverage. */
207          for(j=0;j<6;j++)
208          {
209 #if defined(ENABLE_OSCE) || defined(ENABLE_DEEP_PLC)
210             opus_decoder_ctl(dec[t], OPUS_SET_COMPLEXITY(fast_rand()%11));
211 #endif
212             out_samples = opus_decode(dec[t], 0, 0, outbuf, expected[t], 0);
213             if(out_samples!=expected[t])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          /* Run the PLC once at 2.5ms, as a simulation of someone trying to
218             do small drift corrections. */
219          if(expected[t]!=120/factor)
220          {
221             out_samples = opus_decode(dec[t], 0, 0, outbuf, 120/factor, 0);
222             if(out_samples!=120/factor)test_failed();
223             if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
224             if(dur!=out_samples)test_failed();
225          }
226          out_samples = opus_decode(dec[t], packet, 2, outbuf, expected[t]-1, 0);
227          if(out_samples>0)test_failed();
228       }
229    }
230    fprintf(stdout,"  dec[all] all 2-byte prefix for length 3 and PLC, all modes (64) OK.\n");
231 
232    if(no_fuzz)
233    {
234       fprintf(stdout,"  Skipping many tests which fuzz the decoder as requested.\n");
235       free(decbak);
236       for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
237       printf("  Decoders stopped.\n");
238 
239       err=0;
240       for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
241       for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
242       if(err)test_failed();
243 
244       free(outbuf_int);
245       free(packet);
246       return 0;
247    }
248 
249    {
250      /*We only test a subset of the modes here simply because the longer
251        durations end up taking a long time.*/
252       static const int cmodes[4]={16,20,24,28};
253       static const opus_uint32 cres[4]={116290185,2172123586u,2172123586u,2172123586u};
254       static const opus_uint32 lres[3]={3285687739u,1481572662,694350475};
255       static const int lmodes[3]={0,4,8};
256       int mode=fast_rand()%4;
257 
258       packet[0]=cmodes[mode]<<3;
259       dec_final_acc=0;
260       t=fast_rand()%10;
261 
262       for(i=0;i<65536;i++)
263       {
264          int factor=48000/fsv[t>>1];
265          packet[1]=i>>8;
266          packet[2]=i&255;
267          packet[3]=255;
268          out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
269          if(out_samples!=120/factor)test_failed();
270          opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
271          dec_final_acc+=dec_final_range1;
272       }
273       if(dec_final_acc!=cres[mode])test_failed();
274       fprintf(stdout,"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,cmodes[mode]);
275 
276       mode=fast_rand()%3;
277       packet[0]=lmodes[mode]<<3;
278       dec_final_acc=0;
279       t=fast_rand()%10;
280       for(i=0;i<65536;i++)
281       {
282          int factor=48000/fsv[t>>1];
283          packet[1]=i>>8;
284          packet[2]=i&255;
285          packet[3]=255;
286          out_samples = opus_decode(dec[t], packet, 4, outbuf, MAX_FRAME_SAMP, 0);
287          if(out_samples!=480/factor)test_failed();
288          opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
289          dec_final_acc+=dec_final_range1;
290       }
291       if(dec_final_acc!=lres[mode])test_failed();
292       fprintf(stdout,"  dec[%3d] all 3-byte prefix for length 4, mode %2d OK.\n",t,lmodes[mode]);
293    }
294 
295    skip=fast_rand()%7;
296    for(i=0;i<64;i++)
297    {
298       int j,expected[5*2];
299       packet[0]=i<<2;
300       for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,1);
301       for(j=2+skip;j<1275;j+=4)
302       {
303          int jj;
304          for(jj=0;jj<j;jj++)packet[jj+1]=fast_rand()&255;
305          for(t=0;t<5*2;t++)
306          {
307 #if defined(ENABLE_OSCE) || defined(ENABLE_DEEP_PLC)
308             opus_decoder_ctl(dec[t], OPUS_SET_COMPLEXITY(fast_rand()%11));
309 #endif
310             out_samples = opus_decode(dec[t], packet, j+1, outbuf, MAX_FRAME_SAMP, 0);
311             if(out_samples!=expected[t])test_failed();
312             opus_decoder_ctl(dec[t], OPUS_GET_FINAL_RANGE(&dec_final_range1));
313             if(t==0)dec_final_range2=dec_final_range1;
314             else if(dec_final_range1!=dec_final_range2)test_failed();
315          }
316       }
317    }
318    fprintf(stdout,"  dec[all] random packets, all modes (64), every 8th size from from %d bytes to maximum OK.\n",2+skip);
319 
320    debruijn2(64,modes);
321    plen=(fast_rand()%18+3)*8+skip+3;
322    for(i=0;i<4096;i++)
323    {
324       int j,expected[5*2];
325       packet[0]=modes[i]<<2;
326       for(t=0;t<5*2;t++)expected[t]=opus_decoder_get_nb_samples(dec[t],packet,plen);
327       for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
328       memcpy(decbak,dec[0],decsize);
329       if(opus_decode(decbak, packet, plen+1, outbuf, expected[0], 1)!=expected[0])test_failed();
330       memcpy(decbak,dec[0],decsize);
331       if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 1)<20)test_failed();
332       memcpy(decbak,dec[0],decsize);
333       if(opus_decode(decbak,  0, 0, outbuf, MAX_FRAME_SAMP, 0)<20)test_failed();
334       for(t=0;t<5*2;t++)
335       {
336          opus_int32 dur;
337 #if defined(ENABLE_OSCE) || defined(ENABLE_DEEP_PLC)
338          opus_decoder_ctl(dec[t], OPUS_SET_COMPLEXITY(fast_rand()%11));
339 #endif
340          out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
341          if(out_samples!=expected[t])test_failed();
342          if(t==0)dec_final_range2=dec_final_range1;
343          else if(dec_final_range1!=dec_final_range2)test_failed();
344          if(opus_decoder_ctl(dec[t], OPUS_GET_LAST_PACKET_DURATION(&dur))!=OPUS_OK)test_failed();
345          if(dur!=out_samples)test_failed();
346       }
347    }
348    fprintf(stdout,"  dec[all] random packets, all mode pairs (4096), %d bytes/frame OK.\n",plen+1);
349 
350    plen=(fast_rand()%18+3)*8+skip+3;
351    t=rand()&3;
352    for(i=0;i<4096;i++)
353    {
354       int count,j,expected;
355       packet[0]=modes[i]<<2;
356       expected=opus_decoder_get_nb_samples(dec[t],packet,plen);
357       for(count=0;count<10;count++)
358       {
359 #if defined(ENABLE_OSCE) || defined(ENABLE_DEEP_PLC)
360          opus_decoder_ctl(dec[t], OPUS_SET_COMPLEXITY(fast_rand()%11));
361 #endif
362          for(j=0;j<plen;j++)packet[j+1]=(fast_rand()|fast_rand())&255;
363          out_samples = opus_decode(dec[t], packet, plen+1, outbuf, MAX_FRAME_SAMP, 0);
364          if(out_samples!=expected)test_failed();
365       }
366    }
367    fprintf(stdout,"  dec[%3d] random packets, all mode pairs (4096)*10, %d bytes/frame OK.\n",t,plen+1);
368 
369    {
370       int tmodes[1]={25<<2};
371       opus_uint32 tseeds[1]={140441};
372       int tlen[1]={157};
373       opus_int32 tret[1]={480};
374       t=fast_rand()&1;
375       for(i=0;i<1;i++)
376       {
377          int j;
378          packet[0]=tmodes[i];
379          Rw=Rz=tseeds[i];
380          for(j=1;j<tlen[i];j++)packet[j]=fast_rand()&255;
381          out_samples=opus_decode(dec[t], packet, tlen[i], outbuf, MAX_FRAME_SAMP, 0);
382          if(out_samples!=tret[i])test_failed();
383       }
384       fprintf(stdout,"  dec[%3d] pre-selected random packets OK.\n",t);
385    }
386 
387    free(decbak);
388    for(t=0;t<5*2;t++)opus_decoder_destroy(dec[t]);
389    printf("  Decoders stopped.\n");
390 
391    err=0;
392    for(i=0;i<8*2;i++)err|=outbuf_int[i]!=32749;
393    for(i=MAX_FRAME_SAMP*2;i<(MAX_FRAME_SAMP+8)*2;i++)err|=outbuf[i]!=32749;
394    if(err)test_failed();
395 
396    free(outbuf_int);
397    free(packet);
398    return 0;
399 }
400 
401 #ifndef DISABLE_FLOAT_API
test_soft_clip(void)402 void test_soft_clip(void)
403 {
404    int i,j;
405    float x[1024];
406    float s[8] = {0, 0, 0, 0, 0, 0, 0, 0};
407    fprintf(stdout,"  Testing opus_pcm_soft_clip... ");
408    for(i=0;i<1024;i++)
409    {
410       for (j=0;j<1024;j++)
411       {
412         x[j]=(j&255)*(1/32.f)-4.f;
413       }
414       opus_pcm_soft_clip(&x[i],1024-i,1,s);
415       for (j=i;j<1024;j++)
416       {
417         if(x[j]>1.f)test_failed();
418         if(x[j]<-1.f)test_failed();
419       }
420    }
421    for(i=1;i<9;i++)
422    {
423       for (j=0;j<1024;j++)
424       {
425         x[j]=(j&255)*(1/32.f)-4.f;
426       }
427       opus_pcm_soft_clip(x,1024/i,i,s);
428       for (j=0;j<(1024/i)*i;j++)
429       {
430         if(x[j]>1.f)test_failed();
431         if(x[j]<-1.f)test_failed();
432       }
433    }
434    opus_pcm_soft_clip(x,0,1,s);
435    opus_pcm_soft_clip(x,1,0,s);
436    opus_pcm_soft_clip(x,1,1,0);
437    opus_pcm_soft_clip(x,1,-1,s);
438    opus_pcm_soft_clip(x,-1,1,s);
439    opus_pcm_soft_clip(0,1,1,s);
440    printf("OK.\n");
441 }
442 #endif
443 
main(int _argc,char ** _argv)444 int main(int _argc, char **_argv)
445 {
446    const char * oversion;
447    const char * env_seed;
448    int env_used;
449 
450    if(_argc>2)
451    {
452       fprintf(stderr,"Usage: %s [<seed>]\n",_argv[0]);
453       return 1;
454    }
455 
456    env_used=0;
457    env_seed=getenv("SEED");
458    if(_argc>1)iseed=atoi(_argv[1]);
459    else if(env_seed)
460    {
461       iseed=atoi(env_seed);
462       env_used=1;
463    }
464    else iseed=(opus_uint32)time(NULL)^(((opus_uint32)getpid()&65535)<<16);
465    Rw=Rz=iseed;
466 
467    oversion=opus_get_version_string();
468    if(!oversion)test_failed();
469    fprintf(stderr,"Testing %s decoder. Random seed: %u (%.4X)\n", oversion, iseed, fast_rand() % 65535);
470    if(env_used)fprintf(stderr,"  Random seed set from the environment (SEED=%s).\n", env_seed);
471 
472    /*Setting TEST_OPUS_NOFUZZ tells the tool not to send garbage data
473      into the decoders. This is helpful because garbage data
474      may cause the decoders to clip, which angers CLANG IOC.*/
475    test_decoder_code0(getenv("TEST_OPUS_NOFUZZ")!=NULL);
476 #ifndef DISABLE_FLOAT_API
477    test_soft_clip();
478 #endif
479 
480    return 0;
481 }
482