Commit ae8047b8 authored by Monty's avatar Monty

Fix for bug 577; used a different approach than the submitted patch

(rather than fudging an out of bound result after computation, do it
the right way to begin with)

Add test for fix to seeking_example.


svn path=/trunk/vorbis/; revision=13198
parent 259e1e5d
......@@ -11,7 +11,7 @@
********************************************************************
function: illustrate seeking, and test it too
last mod: $Id: seeking_example.c,v 1.15 2002/07/11 06:40:47 xiphmont Exp $
last mod: $Id$
********************************************************************/
......@@ -25,14 +25,15 @@
# include <fcntl.h>
#endif
void _verify(OggVorbis_File *ov,ogg_int64_t pos,
ogg_int64_t val,ogg_int64_t pcmval,
void _verify(OggVorbis_File *ov,
ogg_int64_t val,ogg_int64_t pcmval,double timeval,
ogg_int64_t pcmlength,
char *bigassbuffer){
int j;
long bread;
char buffer[4096];
int dummy;
ogg_int64_t pos;
/* verify the raw position, the pcm position and position decode */
if(val!=-1 && ov_raw_tell(ov)<val){
......@@ -45,6 +46,11 @@ void _verify(OggVorbis_File *ov,ogg_int64_t pos,
(long)pcmval,(long)ov_pcm_tell(ov));
exit(1);
}
if(timeval!=-1 && ov_time_tell(ov)>timeval){
printf("time position out of tolerance: requested %f, got %f\n",
timeval,ov_time_tell(ov));
exit(1);
}
pos=ov_pcm_tell(ov);
if(pos<0 || pos>pcmlength){
printf("pcm position out of bounds: got %ld\n",(long)pos);
......@@ -73,6 +79,7 @@ int main(){
OggVorbis_File ov;
int i,ret;
ogg_int64_t pcmlength;
double timelength;
char *bigassbuffer;
int dummy;
......@@ -106,6 +113,7 @@ int main(){
does what it claimed, decode the entire file into memory */
fflush(stdout);
pcmlength=ov_pcm_total(&ov,-1);
timelength=ov_time_total(&ov,-1);
bigassbuffer=malloc(pcmlength*2); /* w00t */
i=0;
while(i<pcmlength*2){
......@@ -120,9 +128,6 @@ int main(){
(long)(pcmlength*2-i));
}
/* Exercise all the real seeking cases; ov_raw_seek,
ov_pcm_seek_page and ov_pcm_seek. time seek is just a wrapper
on pcm_seek */
{
ogg_int64_t length=ov.end;
printf("\rtesting raw seeking to random places in %ld bytes....\n",
......@@ -130,7 +135,6 @@ int main(){
for(i=0;i<1000;i++){
ogg_int64_t val=(double)rand()/RAND_MAX*length;
ogg_int64_t pos;
printf("\r\t%d [raw position %ld]... ",i,(long)val);
fflush(stdout);
ret=ov_raw_seek(&ov,val);
......@@ -139,7 +143,7 @@ int main(){
exit(1);
}
_verify(&ov,pos,val,-1,pcmlength,bigassbuffer);
_verify(&ov,val,-1,-1.,pcmlength,bigassbuffer);
}
}
......@@ -151,7 +155,6 @@ int main(){
for(i=0;i<1000;i++){
ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
ogg_int64_t pos;
printf("\r\t%d [pcm position %ld]... ",i,(long)val);
fflush(stdout);
ret=ov_pcm_seek_page(&ov,val);
......@@ -160,20 +163,18 @@ int main(){
exit(1);
}
_verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
_verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
}
}
printf("\r");
{
ogg_int64_t length=ov.end;
printf("testing pcm exact seeking to random places in %ld samples....\n",
(long)pcmlength);
for(i=0;i<1000;i++){
ogg_int64_t val=(double)rand()/RAND_MAX*pcmlength;
ogg_int64_t pos;
printf("\r\t%d [pcm position %ld]... ",i,(long)val);
fflush(stdout);
ret=ov_pcm_seek(&ov,val);
......@@ -187,7 +188,52 @@ int main(){
exit(1);
}
_verify(&ov,pos,-1,val,pcmlength,bigassbuffer);
_verify(&ov,-1,val,-1.,pcmlength,bigassbuffer);
}
}
printf("\r");
{
printf("testing time page seeking to random places in %f seconds....\n",
timelength);
for(i=0;i<1000;i++){
double val=(double)rand()/RAND_MAX*timelength;
printf("\r\t%d [time position %f]... ",i,val);
fflush(stdout);
ret=ov_time_seek_page(&ov,val);
if(ret<0){
printf("seek failed: %d\n",ret);
exit(1);
}
_verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
}
}
printf("\r");
{
printf("testing time exact seeking to random places in %f seconds....\n",
timelength);
for(i=0;i<1000;i++){
double val=(double)rand()/RAND_MAX*timelength;
printf("\r\t%d [time position %f]... ",i,val);
fflush(stdout);
ret=ov_time_seek(&ov,val);
if(ret<0){
printf("seek failed: %d\n",ret);
exit(1);
}
if(ov_time_tell(&ov)<val-1 || ov_time_tell(&ov)>val+1){
printf("Declared position didn't perfectly match request: %f != %f\n",
val,ov_time_tell(&ov));
exit(1);
}
_verify(&ov,-1,-1,val,pcmlength,bigassbuffer);
}
}
......
......@@ -1360,20 +1360,23 @@ int ov_time_seek(OggVorbis_File *vf,double seconds){
/* translate time to PCM position and call ov_pcm_seek */
int link=-1;
ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
double time_total=ov_time_total(vf,-1);
ogg_int64_t pcm_total=0;
double time_total=0.;
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(seconds<0 || seconds>time_total)return(OV_EINVAL);
if(seconds<0)return(OV_EINVAL);
/* which bitstream section does this time offset occur in? */
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link*2+1];
time_total-=ov_time_total(vf,link);
if(seconds>=time_total)break;
for(link=0;link<vf->links;link++){
double addsec = ov_time_total(vf,link);
if(seconds<time_total+addsec)break;
time_total+=addsec;
pcm_total+=vf->pcmlengths[link*2+1];
}
if(link==vf->links)return(OV_EINVAL);
/* enough information to convert time offset to pcm offset */
{
ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
......@@ -1387,20 +1390,23 @@ int ov_time_seek_page(OggVorbis_File *vf,double seconds){
/* translate time to PCM position and call ov_pcm_seek */
int link=-1;
ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
double time_total=ov_time_total(vf,-1);
ogg_int64_t pcm_total=0;
double time_total=0.;
if(vf->ready_state<OPENED)return(OV_EINVAL);
if(!vf->seekable)return(OV_ENOSEEK);
if(seconds<0 || seconds>time_total)return(OV_EINVAL);
if(seconds<0)return(OV_EINVAL);
/* which bitstream section does this time offset occur in? */
for(link=vf->links-1;link>=0;link--){
pcm_total-=vf->pcmlengths[link*2+1];
time_total-=ov_time_total(vf,link);
if(seconds>=time_total)break;
for(link=0;link<vf->links;link++){
double addsec = ov_time_total(vf,link);
if(seconds<time_total+addsec)break;
time_total+=addsec;
pcm_total+=vf->pcmlengths[link*2+1];
}
if(link==vf->links)return(OV_EINVAL);
/* enough information to convert time offset to pcm offset */
{
ogg_int64_t target=pcm_total+(seconds-time_total)*vf->vi[link].rate;
......
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