ref: 167822cf5a7146637412af72496650d8a419cc23
parent: 5e36109d000194ca3a0a37582796ffe17c95f4e5
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Sat Sep 22 11:08:02 EDT 2012
Small speed-up to op_bisect_forward_serialno(). Try to guess that the next link will be approximately the average size of all previous links, for files with many links. This cuts off 6-17% of the seeks. Also remove a variable that was left unused after 5e36109d.
--- a/src/opusfile.c
+++ b/src/opusfile.c
@@ -808,7 +808,6 @@
const ogg_uint32_t *_serialnos,int _nserialnos,OggOpusLink *_link,
ogg_int64_t _end_gp,ogg_uint32_t _end_serialno,opus_int64 _offset,
ogg_int64_t *_total_duration){
- opus_int64 offset;
ogg_int64_t total_duration;
ogg_int64_t duration;
ogg_uint32_t cur_serialno;
@@ -889,6 +888,7 @@
for(;;){
opus_int64 data_offset;
opus_int64 end_searched;
+ opus_int64 bisect;
opus_int64 next;
opus_int64 last;
int sri;
@@ -918,15 +918,32 @@
end_searched=next=_sr[sri-1].offset;
if(sri<nsr)_searched=_sr[sri].offset+_sr[sri].size;
nsr=sri;
+ bisect=-1;
+ /*If we've already found the end of at least one link, try to pick the
+ first bisection point at twice the average link size.
+ This is a good choice for files with lots of links that are all about the
+ same size.*/
+ if(nlinks>1){
+ opus_int64 last_offset;
+ opus_int64 avg_link_size;
+ opus_int64 upper_limit;
+ last_offset=links[nlinks-1].offset;
+ avg_link_size=last_offset/(nlinks-1);
+ upper_limit=end_searched-OP_CHUNK_SIZE-avg_link_size;
+ if(OP_LIKELY(last_offset>_searched-avg_link_size)
+ &&OP_LIKELY(last_offset<upper_limit)){
+ bisect=last_offset+avg_link_size;
+ if(OP_LIKELY(bisect<upper_limit))bisect+=avg_link_size;
+ }
+ }
/*We guard against garbage separating the last and first pages of two
links below.*/
while(_searched<end_searched){
- opus_int64 bisect;
- if(OP_UNLIKELY(end_searched-_searched<OP_CHUNK_SIZE))bisect=_searched;
/*TODO: We might be able to do a better job estimating the start of
subsequent links by assuming its initial PCM offset is 0 and using two
sightings of the same stream to estimate a bitrate.*/
- else bisect=_searched+(end_searched-_searched>>1);
+ if(bisect==-1)bisect=_searched+(end_searched-_searched>>1);
+ if(OP_UNLIKELY(bisect-_searched<OP_CHUNK_SIZE))bisect=_searched;
ret=op_seek_helper(_of,bisect);
if(OP_UNLIKELY(ret<0))return ret;
last=op_get_next_page(_of,&og,_of->end);
@@ -947,6 +964,7 @@
}
}
else _searched=_of->offset;
+ bisect=-1;
}
/*Bisection point found.
Get the final granule position of the previous link, assuming