Commit 89198b34 authored by Michael Smith's avatar Michael Smith
Browse files

Oops. Previous commit was of the wrong (not cleaned up) version. Sorry.

svn path=/trunk/vorbis/; revision=1277
parent 30955db4
......@@ -11,7 +11,7 @@
********************************************************************
function: stdio-based convenience library for opening/seeking/decoding
last mod: $Id: vorbisfile.c,v 1.38 2001/02/14 13:12:15 msmith Exp $
last mod: $Id: vorbisfile.c,v 1.39 2001/02/14 13:24:29 msmith Exp $
********************************************************************/
......@@ -847,42 +847,28 @@ int ov_raw_seek(OggVorbis_File *vf,long pos){
return OV_EBADLINK;
}
int ov_raw_seek2(OggVorbis_File *vf,long pos, int offset, int link){
int flag=0;
if(!vf->seekable)return(OV_ENOSEEK); /* don't dump machine if we can't seek */
int ov_raw_seek_fast(OggVorbis_File *vf, long pos, int offset, int link) {
int ret;
ogg_page og;
if(!vf->seekable)return(OV_ENOSEEK); /* Don't dump machine, this is ok. */
if(pos<0 || pos>vf->offsets[vf->links])return(OV_EINVAL);
/* clear out decoding machine state */
/* Clear decode state */
vf->pcm_offset=-1;
_decode_clear(vf);
// ogg_stream_clear(&vf->os);
// vf->decode_ready=0;
// vf->bittrack=0.f;
// vf->samptrack=0.f;
/* seek */
/* Do the seek */
_seek_helper(vf,pos);
/* we need to make sure the pcm_offset is set. We use the
_fetch_packet helper to process one packet with readp set, then
call it until it returns '0' with readp not set (the last packet
from a page has the 'granulepos' field set, and that's how the
helper updates the offset */
{
int ret;
ogg_page og;
ret=_get_next_page(vf,&og,vf->offsets[link+1]-vf->offset);
if( ret < 0 )
return ret;
vf->pcm_offset = offset;
}
ret = _get_next_page(vf,&og,vf->offsets[link+1]-vf->offset);
if(ret<0)
return ret;
vf->pcm_offset = offset;
return 0;
}
/* Page granularity seek (faster than sample granularity because we
don't do the last bit of decode to find a specific sample).
......@@ -908,85 +894,88 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
missing pages or incorrect frame number information in the
bitstream could make our task impossible. Account for that (it
would be an error condition) */
/* Faster/more intelligent version from Nicholas Vinen */
#if 1
// HB (Nicholas Vinen)
// I think this should be much faster.
{
ogg_int64_t target=pos-total;
long end=vf->offsets[link+1];
long begin=vf->offsets[link];
ogg_int64_t endtime = vf->pcmlengths[link];
ogg_int64_t begintime = 0;
ogg_int64_t begintime=0;
long best=begin;
ogg_page og;
while(begin<end){
while(begin<end) {
long bisect;
if(end-begin<CHUNKSIZE){
if(end-begin < CHUNKSIZE)
bisect=begin;
}else{
//take a (pretty decent) guess.
bisect=begin + (target-begintime)*(end-begin)/(endtime-begintime) - CHUNKSIZE;
else {
/* Make an intelligent guess */
bisect=begin+(target-begintime)*(end-begin)/
(endtime-begintime) - CHUNKSIZE;
if(bisect<=begin)
bisect=begin+1;
}
TryAgain:
again:
_seek_helper(vf,bisect);
ret=_get_next_page(vf,&og,end-bisect);
switch(ret){
case OV_FALSE: case OV_EOF:
if(bisect==begin+1)
goto found_it;
if(bisect==0)
ret=_get_next_page(vf,&og, end-bisect);
if(ret == OV_FALSE || ret==OV_EOF)
{
if(bisect==begin+1)
goto found;
if(bisect==0)
goto seek_error;
bisect-=CHUNKSIZE;
bisect -= CHUNKSIZE;
if(bisect<=begin)
bisect=begin+1;
goto TryAgain;
case OV_EREAD:
goto seek_error;
default:
{
ogg_int64_t granulepos=ogg_page_granulepos(&og);
if(granulepos<target){
best=ret; /* raw offset of packet with granulepos */
begin=vf->offset; /* raw offset of next packet */
begintime=granulepos;
if(target-begintime<2000) { //less than 1s before we hit the right page.
bisect=begin+1;
goto TryAgain;
}
}else{
if(bisect<=begin+1)
goto found_it;
if(end==vf->offset){
//we're pretty close - we'd be stuck in an endless loop otherwise...
bisect-=CHUNKSIZE;
goto TryAgain; //sorry, I like gotos :)
}
end=vf->offset;
endtime=granulepos;
goto again;
}
else if(ret==OV_EREAD) goto seek_error;
else
{
ogg_int64_t granulepos=ogg_page_granulepos(&og);
if(granulepos<target){
best=ret; /* Raw offset of current page */
begin=vf->offset; /* Raw offset of next packet */
begintime=granulepos;
/* Assume that if we're within half a second of
* our target, it'll be faster to scan directly
* forward. */
if(target-begintime<vf->vi->rate/2) {
bisect=begin+1;
goto again;
}
}
else {
if(bisect<=begin+1)
goto found;
if(end==vf->offset){
/* near the end, try just back from here */
bisect-=CHUNKSIZE;
goto again;
}
end=vf->offset;
endtime=granulepos;
}
}
}
/* found our page. seek to it (call raw_seek). */
found_it:
if(link!=vf->current_link){
/* Found the relevent page. Seek to it */
found:
if(link != vf->current_link){
if((ret=ov_raw_seek(vf,best)))goto seek_error;
} else {
if((ret=ov_raw_seek2(vf,best,begintime,link)))goto seek_error;
if((ret=ov_raw_seek_fast(vf,best,begintime,link)))goto seek_error;
}
}
#else
#if 0
{
ogg_int64_t target=pos-total;
long end=vf->offsets[link+1];
......@@ -1029,7 +1018,7 @@ int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos){
if((ret=ov_raw_seek(vf,best)))goto seek_error;
}
#endif
/* verify result */
if(vf->pcm_offset>=pos || pos>ov_pcm_total(vf,-1)){
ret=OV_EFAULT;
......@@ -1057,8 +1046,6 @@ int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
float **pcm;
long target=pos-vf->pcm_offset;
long samples=vorbis_synthesis_pcmout(&vf->vd,&pcm);
if( samples == 0 )
break;
if(samples>target)samples=target;
vorbis_synthesis_read(&vf->vd,samples);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment