[xiph-cvs] cvs commit: vorbis/lib vorbisfile.c
Michael Smith
msmith at xiph.org
Wed Feb 14 05:24:30 PST 2001
msmith 01/02/14 05:24:29
Modified: lib vorbisfile.c
Log:
Oops. Previous commit was of the wrong (not cleaned up) version. Sorry.
Revision Changes Path
1.39 +67 -80 vorbis/lib/vorbisfile.c
Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisfile.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- vorbisfile.c 2001/02/14 13:12:15 1.38
+++ vorbisfile.c 2001/02/14 13:24:29 1.39
@@ -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 @@
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 @@
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 @@
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 @@
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);
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list