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