/******************************************************************** * * * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 * * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * * * ********************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif /*For fileno()*/ #if !defined(_POSIX_SOURCE) # define _POSIX_SOURCE 1 #endif #include #include #include #include #include #include #if defined(_WIN32) # include "win32utf8.h" # undef fileno # define fileno _fileno #endif /*Use shorts, they're smaller.*/ #if !defined(OP_FIXED_POINT) # define OP_FIXED_POINT (1) #endif #if defined(OP_FIXED_POINT) typedef opus_int16 op_sample; # define op_read_native op_read /*TODO: The convergence after 80 ms of preroll is far from exact. Our comparison is very rough. Need to find some way to do this better.*/ # define MATCH_TOL (16384) # define ABS(_x) ((_x)<0?-(_x):(_x)) # define MATCH(_a,_b) (ABS((_a)-(_b))_pcm_offset){ fprintf(stderr,"\nPCM position out of tolerance: requested %li, " "got %li.\n",(long)_pcm_offset,(long)pcm_offset); nfailures++; } if(pcm_offset<0||pcm_offset>_pcm_length){ fprintf(stderr,"\nPCM position out of bounds: got %li.\n", (long)pcm_offset); nfailures++; } nsamples=op_read_native(_of,buffer,sizeof(buffer)/sizeof(*buffer),&li); if(nsamples<0){ fprintf(stderr,"\nFailed to read PCM data after seek: %i\n",nsamples); nfailures++; li=op_current_link(_of); } for(lj=0;ljduration){ fprintf(stderr,"\nPCM data after seek exceeded link duration: " "limit %li, got %li.\n",(long)duration,(long)(pcm_offset+nsamples)); nfailures++; } nchannels=op_channel_count(_of,li); if(_bigassbuffer!=NULL){ for(i=0;i\n",_argv[0]); return EXIT_FAILURE; } memset(&cb,0,sizeof(cb)); if(strcmp(_argv[1],"-")==0)fp=op_fdopen(&cb,fileno(stdin),"rb"); else{ /*Try to treat the argument as a URL.*/ fp=op_url_stream_create(&cb,_argv[1], OP_SSL_SKIP_CERTIFICATE_CHECK(1),NULL); /*Fall back assuming it's a regular file name.*/ if(fp==NULL)fp=op_fopen(&cb,_argv[1],"rb"); } if(cb.seek!=NULL){ real_seek=cb.seek; cb.seek=seek_stat_counter; } of=op_open_callbacks(fp,&cb,NULL,0,NULL); if(of==NULL){ fprintf(stderr,"Failed to open file '%s'.\n",_argv[1]); return EXIT_FAILURE; } if(op_seekable(of)){ op_sample *bigassbuffer; ogg_int64_t size; ogg_int64_t pcm_offset; ogg_int64_t pcm_length; ogg_int64_t nsamples; long max_seeks; int nlinks; int ret; int li; int i; /*Because we want to do sample-level verification that the seek does what it claimed, decode the entire file into memory.*/ nlinks=op_link_count(of); fprintf(stderr,"Opened file containing %i links with %li seeks " "(%0.3f per link).\n",nlinks,nreal_seeks,nreal_seeks/(double)nlinks); /*Reset the seek counter.*/ nreal_seeks=0; nsamples=0; for(li=0;li=pcm_print_offset+48000){ next_bitrate=op_bitrate_instant(of); if(next_bitrate>=0)bitrate=next_bitrate; fprintf(stderr,"\r%s... [%li left] (%0.3f kbps) ", bigassbuffer==NULL?"Scanning":"Loading",nsamples-si,bitrate/1000.0); pcm_print_offset=pcm_offset; } } ret=op_read_native(of,smallerbuffer,8,&li); if(ret<0){ fprintf(stderr,"Failed to read PCM data: %i\n",ret); nfailures++; } if(ret>0){ fprintf(stderr,"Read too much PCM data!\n"); nfailures++; } } #endif pcm_length=op_pcm_total(of,-1); size=op_raw_total(of,-1); fprintf(stderr,"\rLoaded (%0.3f kbps average). \n", op_bitrate(of,-1)/1000.0); fprintf(stderr,"Testing raw seeking to random places in %li bytes...\n", (long)size); max_seeks=0; for(i=0;imax_seeks?nseeks_tmp:max_seeks; } fprintf(stderr,"\rTotal seek operations: %li (%.3f per raw seek, %li maximum).\n", nreal_seeks,nreal_seeks/(double)NSEEK_TESTS,max_seeks); nreal_seeks=0; fprintf(stderr,"Testing exact PCM seeking to random places in %li " "samples (",(long)pcm_length); print_duration(stderr,pcm_length); fprintf(stderr,")...\n"); max_seeks=0; for(i=0;imax_seeks?nseeks_tmp:max_seeks; } fprintf(stderr,"\rTotal seek operations: %li (%.3f per exact seek, %li maximum).\n", nreal_seeks,nreal_seeks/(double)NSEEK_TESTS,max_seeks); nreal_seeks=0; fprintf(stderr,"OK.\n"); _ogg_free(bigassbuffer); } else{ fprintf(stderr,"Input was not seekable.\n"); exit(EXIT_FAILURE); } op_free(of); if(nfailures>0){ fprintf(stderr,"FAILED: %li failure conditions encountered.\n",nfailures); } return nfailures!=0?EXIT_FAILURE:EXIT_SUCCESS; }