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