Commit f945d854 authored by Monty's avatar Monty
Browse files

fixed major bug in ov_open() (well, _bisect_forward_serialno actually)

Monty

svn path=/trunk/vorbis/; revision=163
parent a94b7349
...@@ -46,8 +46,9 @@ int main(){ ...@@ -46,8 +46,9 @@ int main(){
for(i=0;i<ov_streams(&ov);i++){ for(i=0;i<ov_streams(&ov);i++){
vorbis_info *vi=ov_info(&ov,i); vorbis_info *vi=ov_info(&ov,i);
printf("\tlogical bitstream section %d information:\n",i+1); printf("\tlogical bitstream section %d information:\n",i+1);
printf("\t\t%ldHz %d channels serial number=%ld\n", printf("\t\t%ldHz %d channels bitrate %dkbps serial number=%ld\n",
vi->rate,vi->channels,ov_serialnumber(&ov,i)); vi->rate,vi->channels,ov_bitrate(&ov,i)/1000,
ov_serialnumber(&ov,i));
printf("\t\tcompressed length: %ld bytes ",ov_raw_total(&ov,i)); printf("\t\tcompressed length: %ld bytes ",ov_raw_total(&ov,i));
printf(" play time: %lds\n",(long)ov_time_total(&ov,i)); printf(" play time: %lds\n",(long)ov_time_total(&ov,i));
} }
......
...@@ -157,12 +157,12 @@ static void _bisect_forward_serialno(OggVorbis_File *vf, ...@@ -157,12 +157,12 @@ static void _bisect_forward_serialno(OggVorbis_File *vf,
long endsearched=end; long endsearched=end;
long next=end; long next=end;
ogg_page og; ogg_page og;
long ret;
/* the below guards against garbage seperating the last and /* the below guards against garbage seperating the last and
first pages of two links. */ first pages of two links. */
while(searched<endsearched){ while(searched<endsearched){
long bisect; long bisect;
long ret;
if(endsearched-searched<CHUNKSIZE){ if(endsearched-searched<CHUNKSIZE){
bisect=searched; bisect=searched;
...@@ -179,12 +179,16 @@ static void _bisect_forward_serialno(OggVorbis_File *vf, ...@@ -179,12 +179,16 @@ static void _bisect_forward_serialno(OggVorbis_File *vf,
searched=ret+og.header_len+og.body_len; searched=ret+og.header_len+og.body_len;
} }
} }
if(searched>=end){
_seek_helper(vf,next);
ret=_get_next_page(vf,&og,-1);
if(searched>=end || ret==-1){
vf->links=m+1; vf->links=m+1;
vf->offsets=malloc((m+2)*sizeof(long)); vf->offsets=malloc((m+2)*sizeof(long));
vf->offsets[m+1]=searched; vf->offsets[m+1]=searched;
}else{ }else{
_bisect_forward_serialno(vf,next,next, _bisect_forward_serialno(vf,next,vf->offset,
end,ogg_page_serialno(&og),m+1); end,ogg_page_serialno(&og),m+1);
} }
...@@ -246,7 +250,8 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){ ...@@ -246,7 +250,8 @@ static int _fetch_headers(OggVorbis_File *vf,vorbis_info *vi,long *serialno){
vorbis_info structs and PCM positions. Only called by the seekable vorbis_info structs and PCM positions. Only called by the seekable
initialization (local stream storage is hacked slightly; pay initialization (local stream storage is hacked slightly; pay
attention to how that's done) */ attention to how that's done) */
static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first){ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first,
long dataoffset){
ogg_page og; ogg_page og;
int i,ret; int i,ret;
...@@ -261,6 +266,7 @@ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first){ ...@@ -261,6 +266,7 @@ static void _prefetch_all_headers(OggVorbis_File *vf,vorbis_info *first){
saves the waste of grabbing it again */ saves the waste of grabbing it again */
memcpy(vf->vi+i,first,sizeof(vorbis_info)); memcpy(vf->vi+i,first,sizeof(vorbis_info));
memset(first,0,sizeof(vorbis_info)); memset(first,0,sizeof(vorbis_info));
vf->dataoffsets[i]=dataoffset;
}else{ }else{
/* seek to the location of the initial header */ /* seek to the location of the initial header */
...@@ -309,10 +315,12 @@ static int _open_seekable(OggVorbis_File *vf){ ...@@ -309,10 +315,12 @@ static int _open_seekable(OggVorbis_File *vf){
vorbis_info initial; vorbis_info initial;
long serialno,end; long serialno,end;
int ret; int ret;
long dataoffset;
ogg_page og; ogg_page og;
/* is this even vorbis...? */ /* is this even vorbis...? */
ret=_fetch_headers(vf,&initial,&serialno); ret=_fetch_headers(vf,&initial,&serialno);
dataoffset=vf->offset;
ogg_stream_clear(&vf->os); ogg_stream_clear(&vf->os);
if(ret==-1)return(-1); if(ret==-1)return(-1);
...@@ -339,7 +347,7 @@ static int _open_seekable(OggVorbis_File *vf){ ...@@ -339,7 +347,7 @@ static int _open_seekable(OggVorbis_File *vf){
} }
_prefetch_all_headers(vf,&initial); _prefetch_all_headers(vf,&initial,dataoffset);
return(0); return(0);
} }
...@@ -567,17 +575,17 @@ long ov_seekable(OggVorbis_File *vf){ ...@@ -567,17 +575,17 @@ long ov_seekable(OggVorbis_File *vf){
long ov_bitrate(OggVorbis_File *vf,int i){ long ov_bitrate(OggVorbis_File *vf,int i){
if(i>=vf->links)return(-1); if(i>=vf->links)return(-1);
if(!vf->seekable)return(ov_bitrate(vf,0)); if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
if(i<0){ if(i<0){
size64 bits; size64 bits;
int i; int i;
for(i=0;i<vf->links;i++) for(i=0;i<vf->links;i++)
bits+=vf->offsets[i+1]-vf->dataoffsets[i]; bits+=(vf->offsets[i+1]-vf->dataoffsets[i])*8;
return(rint(bits/ov_time_total(vf,-1))); return(rint(bits/ov_time_total(vf,-1)));
}else{ }else{
if(vf->seekable){ if(vf->seekable){
/* return the actual bitrate */ /* return the actual bitrate */
return(rint((vf->offsets[i+1]-vf->dataoffsets[i])/ov_time_total(vf,i))); return(rint((vf->offsets[i+1]-vf->dataoffsets[i])*8/ov_time_total(vf,i)));
}else{ }else{
/* return nominal if set */ /* return nominal if set */
if(vf->vi[i].bitrate_nominal>0){ if(vf->vi[i].bitrate_nominal>0){
......
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