Commit change to libvorbis that returns correct timestamp for granule
authorMonty <xiphmont@xiph.org>
Sun, 24 Oct 2010 04:50:46 +0000 (04:50 +0000)
committerMonty <xiphmont@xiph.org>
Sun, 24 Oct 2010 04:50:46 +0000 (04:50 +0000)
positions with high bit set.

Make two 'better safe than sorry' changes in vorbisfile that clamp
pcmoffsets entries to being strictly >=0.

svn path=/trunk/vorbis/; revision=17562

lib/info.c
lib/vorbisfile.c

index ec24672..8b3d06c 100644 (file)
@@ -645,9 +645,18 @@ int vorbis_analysis_headerout(vorbis_dsp_state *v,
 }
 
 double vorbis_granule_time(vorbis_dsp_state *v,ogg_int64_t granulepos){
-  if(granulepos>=0)
+  if(granulepos == -1) return -1;
+
+  /* We're not guaranteed a 64 bit unsigned type everywhere, so we
+     have to put the unsigned granpo in a signed type. */
+  if(granulepos>=0){
     return((double)granulepos/v->vi->rate);
-  return(-1);
+  }else{
+    ogg_int64_t granuleoff=0xffffffff;
+    granuleoff<<=31;
+    granuleoff|=0x7ffffffff;
+    return(((double)granulepos+2+granuleoff+granuleoff)/v->vi->rate);
+  }
 }
 
 const char *vorbis_version_string(void){
index 029226c..1c9f3a6 100644 (file)
@@ -451,8 +451,9 @@ static ogg_int64_t _initial_pcmoffset(OggVorbis_File *vf, vorbis_info *vi){
     }
   }
 
-  /* less than zero?  This is a stream with samples trimmed off
-     the beginning, a normal occurrence; set the offset to zero */
+  /* less than zero?  Either a corrupt file or a stream with samples
+     trimmed off the beginning, a normal occurrence; in both cases set
+     the offset to zero */
   if(accumulated<0)accumulated=0;
 
   return accumulated;
@@ -513,7 +514,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
 
     vf->offsets[m+1]=end;
     vf->offsets[m]=begin;
-    vf->pcmlengths[m*2+1]=endgran;
+    vf->pcmlengths[m*2+1]=(endgran<0?0:endgran);
 
   }else{
 
@@ -590,7 +591,7 @@ static int _bisect_forward_serialno(OggVorbis_File *vf,
     vf->pcmlengths[m*2+1]=searchgran;
     vf->pcmlengths[m*2+2]=pcmoffset;
     vf->pcmlengths[m*2+3]-=pcmoffset;
-
+    if(vf->pcmlengths[m*2+3]<0)vf->pcmlengths[m*2+3]=0;
   }
   return(0);
 }
@@ -649,6 +650,7 @@ static int _open_seekable2(OggVorbis_File *vf){
   vf->dataoffsets[0]=dataoffset;
   vf->pcmlengths[0]=pcmoffset;
   vf->pcmlengths[1]-=pcmoffset;
+  if(vf->pcmlengths[1]<0)vf->pcmlengths[1]=0;
 
   return(ov_raw_seek(vf,dataoffset));
 }