ref: efbca3a1457b3519c82a9cb9f1ee23d902c5a15d
parent: 3c7191a95f14df6a0d88649024c453807ec99c6b
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Wed Sep 19 10:13:18 EDT 2012
A couple of seeking_example improvements. 1) Check for allocation failure and fall back to merely scanning a file for consistent timestamps instead of loading it to RAM. 2) Report holes, but do not quit scanning/loading unless they cause a discontinuity in the timestamps.
--- a/examples/seeking_example.c
+++ b/examples/seeking_example.c
@@ -152,7 +152,7 @@
"expected %i, got %i.\n",lj,li);
exit(EXIT_FAILURE);
}
- _bigassbuffer+=op_channel_count(_of,lj)*duration;
+ if(_bigassbuffer!=NULL)_bigassbuffer+=op_channel_count(_of,lj)*duration;
}
duration=op_pcm_total(_of,li);
if(pcm_offset+nsamples>duration){
@@ -161,22 +161,24 @@
exit(EXIT_FAILURE);
}
nchannels=op_channel_count(_of,li);
- for(i=0;i<nsamples*nchannels;i++){
- if(!MATCH(buffer[i],_bigassbuffer[pcm_offset*nchannels+i])){
- fprintf(stderr,"\nData after seek doesn't match declared PCM "
- "position: mismatch %G\n",
- (double)buffer[i]-_bigassbuffer[pcm_offset*nchannels+i]);
- for(i=0;i<duration-nsamples;i++){
- int j;
- for(j=0;j<nsamples*nchannels;j++){
- if(!MATCH(buffer[j],_bigassbuffer[i*nchannels+j]))break;
+ if(_bigassbuffer!=NULL){
+ for(i=0;i<nsamples*nchannels;i++){
+ if(!MATCH(buffer[i],_bigassbuffer[pcm_offset*nchannels+i])){
+ fprintf(stderr,"\nData after seek doesn't match declared PCM "
+ "position: mismatch %G\n",
+ (double)buffer[i]-_bigassbuffer[pcm_offset*nchannels+i]);
+ for(i=0;i<duration-nsamples;i++){
+ int j;
+ for(j=0;j<nsamples*nchannels;j++){
+ if(!MATCH(buffer[j],_bigassbuffer[i*nchannels+j]))break;
+ }
+ if(j==nsamples*nchannels){
+ fprintf(stderr,"\nData after seek appears to match position %li.\n",
+ (long)i);
+ }
}
- if(j==nsamples*nchannels){
- fprintf(stderr,"\nData after seek appears to match position %li.\n",
- (long)i);
- }
+ exit(EXIT_FAILURE);
}
- exit(EXIT_FAILURE);
}
}
#if defined(OP_WRITE_SEEK_SAMPLES)
@@ -258,6 +260,7 @@
}
if(op_seekable(of)){
op_sample *bigassbuffer;
+ op_sample smallerbuffer[120*48*8];
ogg_int64_t size;
ogg_int64_t pcm_print_offset;
ogg_int64_t pcm_offset;
@@ -265,6 +268,7 @@
ogg_int64_t nsamples;
ogg_int64_t si;
opus_int32 bitrate;
+ int saw_hole;
int nlinks;
int ret;
int li;
@@ -281,6 +285,10 @@
nsamples+=op_pcm_total(of,li)*op_channel_count(of,li);
}
bigassbuffer=_ogg_malloc(sizeof(*bigassbuffer)*nsamples);
+ if(bigassbuffer==NULL){
+ fprintf(stderr,
+ "Buffer allocation failed. Seek offset detection disabled.\n");
+ }
pcm_offset=op_pcm_tell(of);
if(pcm_offset!=0){
fprintf(stderr,"Initial PCM offset was not 0, got %li instead.!\n",
@@ -289,14 +297,30 @@
}
pcm_print_offset=pcm_offset-48000;
bitrate=0;
+ saw_hole=0;
for(si=0;si<nsamples;){
ogg_int64_t next_pcm_offset;
opus_int32 next_bitrate;
- ret=op_read_native(of,bigassbuffer+si,OP_MIN(120*48*8,nsamples-si),&li);
- if(ret<=0){
- fprintf(stderr,"Failed to read PCM data: %i\n",ret);
+ op_sample *buf;
+ int buf_size;
+ buf=bigassbuffer==NULL?smallerbuffer:bigassbuffer+si;
+ buf_size=(int)OP_MIN(nsamples-si,
+ (int)(sizeof(smallerbuffer)/sizeof(*smallerbuffer))),
+ ret=op_read_native(of,buf,buf_size,&li);
+ if(ret==OP_HOLE){
+ /*Only warn once in a row.*/
+ if(saw_hole)continue;
+ saw_hole=1;
+ /*This is just a warning.
+ As long as the timestamps are still contiguous we're okay.*/
+ fprintf(stderr,"\nHole in PCM data at sample %li\n",(long)pcm_offset);
+ continue;
+ }
+ else if(ret<=0){
+ fprintf(stderr,"\nFailed to read PCM data: %i\n",ret);
exit(EXIT_FAILURE);
}
+ saw_hole=0;
/*If we have gaps in the PCM positions, seeking is not likely to work
near them.*/
next_pcm_offset=op_pcm_tell(of);
@@ -310,8 +334,8 @@
if(pcm_offset>=pcm_print_offset+48000){
next_bitrate=op_bitrate_instant(of);
if(next_bitrate>=0)bitrate=next_bitrate;
- fprintf(stderr,"\rLoading... [%li left] (%0.3f kbps) ",
- nsamples-si,bitrate/1000.0);
+ fprintf(stderr,"\r%s... [%li left] (%0.3f kbps) ",
+ bigassbuffer==NULL?"Scanning":"Loading",nsamples-si,bitrate/1000.0);
pcm_print_offset=pcm_offset;
}
}
@@ -396,6 +420,7 @@
nreal_seeks,nreal_seeks/(double)NSEEK_TESTS);
nreal_seeks=0;
fprintf(stderr,"OK.\n");
+ _ogg_free(bigassbuffer);
}
else{
fprintf(stderr,"Input was not seekable.\n");