[xiph-cvs] cvs commit: Tremor codec_internal.h floor0.c framing.c ivorbisfile.h mdct.c vorbisfile.c

Monty xiphmont at xiph.org
Mon Apr 28 21:03:27 PDT 2003



xiphmont    03/04/29 00:03:27

  Modified:    .        Tag: lowmem-branch codec_internal.h floor0.c
                        framing.c ivorbisfile.h mdct.c vorbisfile.c
  Log:
  Eliminate vorbis_info and codec_setup caching for all links; makes
  seeks more expensive, but does not affect decode speed.
  
  Correct a number of bugs exposed by seeking.

Revision  Changes    Path
No                   revision

<p>No                   revision

<p>1.5.6.8   +2 -0      Tremor/codec_internal.h

Index: codec_internal.h
===================================================================
RCS file: /usr/local/cvsroot/Tremor/codec_internal.h,v
retrieving revision 1.5.6.7
retrieving revision 1.5.6.8
diff -u -r1.5.6.7 -r1.5.6.8
--- codec_internal.h	22 Apr 2003 09:21:35 -0000	1.5.6.7
+++ codec_internal.h	29 Apr 2003 04:03:26 -0000	1.5.6.8
@@ -18,6 +18,8 @@
 #ifndef _V_CODECI_H_
 #define _V_CODECI_H_
 
+#define CHUNKSIZE 1024
+
 #include "codebook.h"
 #include "ivorbiscodec.h"
 

<p><p>1.4.6.9   +0 -10     Tremor/floor0.c

Index: floor0.c
===================================================================
RCS file: /usr/local/cvsroot/Tremor/floor0.c,v
retrieving revision 1.4.6.8
retrieving revision 1.4.6.9
diff -u -r1.4.6.8 -r1.4.6.9
--- floor0.c	23 Apr 2003 21:53:11 -0000	1.4.6.8
+++ floor0.c	29 Apr 2003 04:03:26 -0000	1.4.6.9
@@ -63,16 +63,6 @@
 }
 #endif
 
-#if 0
-static inline ogg_int32_t vorbis_fromdBlook_i(long a){
-  int i=(-a)>>(12-FROMdB2_SHIFT);
-  if(i<0) return 0x7fffffff;
-  if(i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))return 0;
-  
-  return FROMdB_LOOKUP[i>>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK];
-}
-#endif
-
 /* interpolated lookup based cos function, domain 0 to PI only */
 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
 static inline ogg_int32_t vorbis_coslook_i(long a){

<p><p>1.6.2.1   +15 -24    Tremor/framing.c

Index: framing.c
===================================================================
RCS file: /usr/local/cvsroot/Tremor/framing.c,v
retrieving revision 1.6
retrieving revision 1.6.2.1
diff -u -r1.6 -r1.6.2.1
--- framing.c	31 Mar 2003 22:14:09 -0000	1.6
+++ framing.c	29 Apr 2003 04:03:26 -0000	1.6.2.1
@@ -157,19 +157,11 @@
 }
 
 /* duplicate a reference (pointing to the same actual buffer memory)
-   and increment buffer refcount.  If the desired segment begins out
-   of range, NULL is returned; if the desired segment is simply zero
-   length, a zero length ref is returned.  Partial range overlap
-   returns the overlap of the ranges */
-static ogg_reference *ogg_buffer_sub(ogg_reference *or,long begin,long length){
+   and increment buffer refcount.  If the desired segment is zero
+   length, a zero length ref is returned. */
+static ogg_reference *ogg_buffer_sub(ogg_reference *or,long length){
   ogg_reference *ret=0,*head=0;
-
-  /* walk past any preceeding fragments we don't want */
-  while(or && begin>=or->length){
-    begin-=or->length;
-    or=or->next;
-  }
-
+  
   /* duplicate the reference chain; increment refcounts */
   while(or && length){
     ogg_reference *temp=_fetch_ref(or->buffer->ptr.owner);
@@ -179,12 +171,11 @@
       ret=temp;
     head=temp;
     head->buffer=or->buffer;    
-    head->begin=or->begin+begin;
+    head->begin=or->begin;
     head->length=length;
-    if(head->length>or->length-begin)
-      head->length=or->length-begin;
+    if(head->length>or->length)
+      head->length=or->length;
     
-    begin=0;
     length-=head->length;
     or=or->next;
   }
@@ -428,43 +419,43 @@
 
 int ogg_page_version(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header))return -1;
   return oggbyte_read1(&ob,4);
 }
 
 int ogg_page_continued(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header))return -1;
   return oggbyte_read1(&ob,5)&0x01;
 }
 
 int ogg_page_bos(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header))return -1;
   return oggbyte_read1(&ob,5)&0x02;
 }
 
 int ogg_page_eos(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header))return -1;
   return oggbyte_read1(&ob,5)&0x04;
 }
 
 ogg_int64_t ogg_page_granulepos(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header))return -1;
   return oggbyte_read8(&ob,6);
 }
 
 ogg_uint32_t ogg_page_serialno(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header)) return 0xffffffffUL;
   return oggbyte_read4(&ob,14);
 }
  
 ogg_uint32_t ogg_page_pageno(ogg_page *og){
   oggbyte_buffer ob;
-  oggbyte_init(&ob,og->header);
+  if(oggbyte_init(&ob,og->header))return 0xffffffffUL;
   return oggbyte_read4(&ob,18);
 }
 
@@ -1079,7 +1070,7 @@
     _next_lace(&ob,os);
   }else{
     if(op){
-      op->packet=ogg_buffer_sub(os->body_tail,0,os->body_fill&FINMASK);
+      op->packet=ogg_buffer_sub(os->body_tail,os->body_fill&FINMASK);
       op->bytes=os->body_fill&FINMASK;
     }
   }

<p><p>1.3.2.4   +2 -10     Tremor/ivorbisfile.h

Index: ivorbisfile.h
===================================================================
RCS file: /usr/local/cvsroot/Tremor/ivorbisfile.h,v
retrieving revision 1.3.2.3
retrieving revision 1.3.2.4
diff -u -r1.3.2.3 -r1.3.2.4
--- ivorbisfile.h	22 Apr 2003 09:21:35 -0000	1.3.2.3
+++ ivorbisfile.h	29 Apr 2003 04:03:26 -0000	1.3.2.4
@@ -26,8 +26,6 @@
 #include <stdio.h>
 #include "ivorbiscodec.h"
 
-#define CHUNKSIZE 1024
-
 /* The function prototypes for the callbacks are basically the same as for
  * the stdio functions fread, fseek, fclose, ftell. 
  * The one difference is that the FILE * arguments have been replaced with
@@ -45,12 +43,6 @@
   long   (*tell_func)  (void *datasource);
 } ov_callbacks;
 
-#define  NOTOPEN   0
-#define  PARTOPEN  1
-#define  OPENED    2
-#define  STREAMSET 3
-#define  INITSET   4
-
 typedef struct OggVorbis_File {
   void            *datasource; /* Pointer to a FILE *, etc. */
   int              seekable;
@@ -65,8 +57,8 @@
   ogg_int64_t     *dataoffsets;
   ogg_uint32_t    *serialnos;
   ogg_int64_t     *pcmlengths;
-  vorbis_info     *vi;
-  vorbis_comment  *vc;
+  vorbis_info     vi;
+  vorbis_comment  vc;
 
   /* Decoding working state local storage */
   ogg_int64_t      pcm_offset;

<p><p>1.9.6.5   +6 -2      Tremor/mdct.c

Index: mdct.c
===================================================================
RCS file: /usr/local/cvsroot/Tremor/mdct.c,v
retrieving revision 1.9.6.4
retrieving revision 1.9.6.5
diff -u -r1.9.6.4 -r1.9.6.5
--- mdct.c	22 Apr 2003 09:00:49 -0000	1.9.6.4
+++ mdct.c	29 Apr 2003 04:03:27 -0000	1.9.6.5
@@ -13,7 +13,7 @@
 
  function: normalized modified discrete cosine transform
            power of two length transform only [64 <= n ]
- last mod: $Id: mdct.c,v 1.9.6.4 2003/04/22 09:00:49 xiphmont Exp $
+ last mod: $Id: mdct.c,v 1.9.6.5 2003/04/29 04:03:27 xiphmont Exp $
 
  Original algorithm adapted long ago from _The use of multirate filter
  banks for coding of high quality digital audio_, by T. Sporer,
@@ -446,12 +446,14 @@
   r     -= off;
   l     -= off*2;
   start -= off;
+  wR    -= off;
+  wL    += off;
   end   -= n;
   while(r>post){
     l-=2;
     *out = CLIP_TO_15((MULT31(*--r,*--wR) + MULT31(*l,*wL++))>>9);
     out+=step;
-  };
+  }
 
   n      = (end<halfLap?end:halfLap);
   off    = (start<halfLap?start:halfLap);
@@ -460,6 +462,8 @@
   l     += off*2;
   start -= off;
   end   -= n;
+  wR    -= off;
+  wL    += off;
   while(r<post){
     *out = CLIP_TO_15((MULT31(*r++,*--wR) - MULT31(*l,*wL++))>>9);
     out+=step;

<p><p>1.6.2.4   +230 -201  Tremor/vorbisfile.c

Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/Tremor/vorbisfile.c,v
retrieving revision 1.6.2.3
retrieving revision 1.6.2.4
diff -u -r1.6.2.3 -r1.6.2.4
--- vorbisfile.c	22 Apr 2003 09:00:49 -0000	1.6.2.3
+++ vorbisfile.c	29 Apr 2003 04:03:27 -0000	1.6.2.4
@@ -12,7 +12,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.6.2.3 2003/04/22 09:00:49 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.6.2.4 2003/04/29 04:03:27 xiphmont Exp $
 
  ********************************************************************/
 
@@ -28,6 +28,13 @@
 #include "os.h"
 #include "misc.h"
 
+#define  NOTOPEN   0
+#define  PARTOPEN  1
+#define  OPENED    2
+#define  STREAMSET 3 /* serialno and link set, but not to current link */
+#define  LINKSET   4 /* serialno and link set to current link */
+#define  INITSET   5
+
 /* A 'chained bitstream' is a Vorbis bitstream that contains more than
    one logical bitstream arranged end to end (the only form of Ogg
    multiplexing allowed in a Vorbis bitstream; grouping [parallel
@@ -65,10 +72,10 @@
     char *buffer=ogg_sync_bufferin(vf->oy,CHUNKSIZE);
     long bytes=(vf->callbacks.read_func)(buffer,1,CHUNKSIZE,vf->datasource);
     if(bytes>0)ogg_sync_wrote(vf->oy,bytes);
-    if(bytes==0 && errno)return(-1);
-    return(bytes);
+    if(bytes==0 && errno)return -1;
+    return bytes;
   }else
-    return(0);
+    return 0;
 }
 
 /* save a tiny smidge of verbosity to make the code more readable */
@@ -104,7 +111,7 @@
   while(1){
     long more;
 
-    if(boundary>0 && vf->offset>=boundary)return(OV_FALSE);
+    if(boundary>0 && vf->offset>=boundary)return OV_FALSE;
     more=ogg_sync_pageseek(vf->oy,og);
     
     if(more<0){
@@ -113,18 +120,18 @@
     }else{
       if(more==0){
         /* send more paramedics */
-	if(!boundary)return(OV_FALSE);
+	if(!boundary)return OV_FALSE;
         {
           long ret=_get_data(vf);
-	  if(ret==0)return(OV_EOF);
-	  if(ret<0)return(OV_EREAD);
+	  if(ret==0)return OV_EOF;
+	  if(ret<0)return OV_EREAD;
         }
       }else{
         /* got a page.  Return the offset at the page beginning,
            advance the internal offset past the page end */
         ogg_int64_t ret=vf->offset;
         vf->offset+=more;
-	return(ret);
+	return ret;
         
       }
     }
@@ -150,7 +157,7 @@
     _seek_helper(vf,begin);
     while(vf->offset<end){
       ret=_get_next_page(vf,og,end-vf->offset);
-      if(ret==OV_EREAD)return(OV_EREAD);
+      if(ret==OV_EREAD)return OV_EREAD;
       if(ret<0){
         break;
       }else{
@@ -164,9 +171,9 @@
   ret=_get_next_page(vf,og,CHUNKSIZE);
   if(ret<0)
     /* this shouldn't be possible */
-    return(OV_EFAULT);
+    return OV_EFAULT;
 
-  return(offset);
+  return offset;
 }
 
 /* finds each bitstream link one at a time using a bisection search
@@ -197,7 +204,7 @@
     
     _seek_helper(vf,bisect);
     ret=_get_next_page(vf,&og,-1);
-    if(ret==OV_EREAD)return(OV_EREAD);
+    if(ret==OV_EREAD)return OV_EREAD;
     if(ret<0 || ogg_page_serialno(&og)!=currentno){
       endsearched=bisect;
       if(ret>=0)next=ret;
@@ -209,7 +216,7 @@
 
   _seek_helper(vf,next);
   ret=_get_next_page(vf,&og,-1);
-  if(ret==OV_EREAD)return(OV_EREAD);
+  if(ret==OV_EREAD)return OV_EREAD;
   
   if(searched>=end || ret<0){
     ogg_page_release(&og);
@@ -221,17 +228,33 @@
     ret=_bisect_forward_serialno(vf,next,vf->offset,
                                  end,ogg_page_serialno(&og),m+1);
     ogg_page_release(&og);
-    if(ret==OV_EREAD)return(OV_EREAD);
+    if(ret==OV_EREAD)return OV_EREAD;
   }
   
   vf->offsets[m]=begin;
   vf->serialnos[m]=currentno;
-  return(0);
+  return 0;
+}
+
+static int _decode_clear(OggVorbis_File *vf){
+  if(vf->ready_state==INITSET){
+    vorbis_dsp_destroy(vf->vd);
+    vf->vd=0;
+    vf->ready_state=STREAMSET;
+  }
+  
+  if(vf->ready_state>=STREAMSET){
+    vorbis_info_clear(&vf->vi);
+    vorbis_comment_clear(&vf->vc);
+    vf->ready_state=OPENED;
+  }
+  return 0;
 }
 
 /* uses the local ogg_stream storage in vf; this is important for
    non-streaming input sources */
 /* consumes the page that's passed in (if any) */
+/* state is LINKSET upon successful return */
 
 static int _fetch_headers(OggVorbis_File *vf,
                           vorbis_info *vi,
@@ -242,16 +265,17 @@
   ogg_packet op={0,0,0,0,0,0};
   int i,ret;
   
+  if(vf->ready_state>OPENED)_decode_clear(vf);
+
   if(!og_ptr){
     ogg_int64_t llret=_get_next_page(vf,&og,CHUNKSIZE);
-    if(llret==OV_EREAD)return(OV_EREAD);
+    if(llret==OV_EREAD)return OV_EREAD;
     if(llret<0)return OV_ENOTVORBIS;
     og_ptr=&og;
   }
 
   ogg_stream_reset_serialno(vf->os,ogg_page_serialno(og_ptr));
   if(serialno)*serialno=vf->os->serialno;
-  vf->ready_state=STREAMSET;
   
   /* extract the initial header from the first page and verify that the
      Ogg bitstream is in fact Vorbis data */
@@ -283,6 +307,7 @@
 
   ogg_packet_release(&op);
   ogg_page_release(&og);
+  vf->ready_state=LINKSET;
   return 0; 
 
  bail_header:
@@ -295,22 +320,45 @@
   return ret;
 }
 
-/* last step of the OggVorbis_File initialization; get all the
-   vorbis_info structs and PCM positions.  Only called by the seekable
-   initialization (local stream storage is hacked slightly; pay
-   attention to how that's done) */
+/* we no longer preload all vorbis_info (and the associated
+   codec_setup) structs.  Call this to seek and fetch the info from
+   the bitstream, if needed */
+static int _set_link_number(OggVorbis_File *vf,int link){
+  if(link != vf->current_link) _decode_clear(vf);
+  if(vf->ready_state<STREAMSET){
+    _seek_helper(vf,vf->offsets[link]);
+    ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
+    vf->current_serialno=vf->serialnos[link];
+    vf->current_link=link;
+    return _fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL);
+  }
+  return 0;
+}
+
+static int _set_link_number_preserve_pos(OggVorbis_File *vf,int link){
+  ogg_int64_t pos=vf->offset;
+  int ret=_set_link_number(vf,link);
+  if(ret)return ret;
+  _seek_helper(vf,pos);
+  if(pos<vf->offsets[link] || pos>=vf->offsets[link+1])
+    vf->ready_state=STREAMSET;
+  return 0;
+}
+
+/* last step of the OggVorbis_File initialization; get all the offset
+   positions.  Only called by the seekable initialization (local
+   stream storage is hacked slightly; pay attention to how that's
+   done) */
 
 /* this is void and does not propogate errors up because we want to be
    able to open and use damaged bitstreams as well as we can.  Just
    watch out for missing information for links in the OggVorbis_File
    struct */
-static void _prefetch_all_headers(OggVorbis_File *vf, ogg_int64_t dataoffset){
+static void _prefetch_all_offsets(OggVorbis_File *vf, ogg_int64_t dataoffset){
   ogg_page og={0,0,0,0};
   int i;
   ogg_int64_t ret;
   
-  vf->vi=_ogg_realloc(vf->vi,vf->links*sizeof(*vf->vi));
-  vf->vc=_ogg_realloc(vf->vc,vf->links*sizeof(*vf->vc));
   vf->dataoffsets=_ogg_malloc(vf->links*sizeof(*vf->dataoffsets));
   vf->pcmlengths=_ogg_malloc(vf->links*2*sizeof(*vf->pcmlengths));
   
@@ -325,7 +373,7 @@
       /* seek to the location of the initial header */
 
       _seek_helper(vf,vf->offsets[i]);
-      if(_fetch_headers(vf,vf->vi+i,vf->vc+i,NULL,NULL)<0){
+      if(_fetch_headers(vf,&vf->vi,&vf->vc,NULL,NULL)<0){
             vf->dataoffsets[i]=-1;
       }else{
         vf->dataoffsets[i]=vf->offset;
@@ -359,7 +407,7 @@
         ogg_stream_pagein(vf->os,&og);
         while((result=ogg_stream_packetout(vf->os,&op))){
           if(result>0){ /* ignore holes */
-	    long thisblock=vorbis_packet_blocksize(vf->vi+i,&op);
+	    long thisblock=vorbis_packet_blocksize(&vf->vi,&op);
             if(lastblock!=-1)
               accumulated+=(lastblock+thisblock)>>2;
             lastblock=thisblock;
@@ -391,8 +439,8 @@
         ret=_get_prev_page(vf,&og);
         if(ret<0){
           /* this should not be possible */
-	  vorbis_info_clear(vf->vi+i);
-	  vorbis_comment_clear(vf->vc+i);
+	  vorbis_info_clear(&vf->vi);
+	  vorbis_comment_clear(&vf->vc);
           break;
         }
         if(ogg_page_granulepos(&og)!=-1){
@@ -406,17 +454,28 @@
   ogg_page_release(&og);
 }
 
-static void _make_decode_ready(OggVorbis_File *vf){
-  if(vf->ready_state!=STREAMSET)return;
-  if(vf->seekable){
-    vf->vd=vorbis_dsp_create(vf->vi+vf->current_link);
-  }else{
-    vf->vd=vorbis_dsp_create(vf->vi);
-  }    
-  vf->ready_state=INITSET;
-  vf->bittrack=0;
-  vf->samptrack=0;
-  return;
+static int _make_decode_ready(OggVorbis_File *vf){
+  int i;
+  switch(vf->ready_state){
+  case OPENED:
+  case STREAMSET:
+    for(i=0;i<vf->links;i++)
+      if(vf->offsets[i+1]>=vf->offset)break;
+    if(i==vf->links)return -1;
+    i=_set_link_number_preserve_pos(vf,i);
+    if(i)return i;
+    /* fall through */
+  case LINKSET:
+    vf->vd=vorbis_dsp_create(&vf->vi);
+    vf->ready_state=INITSET;
+    vf->bittrack=0;
+    vf->samptrack=0;
+  case INITSET:
+    return 0;
+  default:
+    return -1;
+  }
+  
 }
 
 static int _open_seekable2(OggVorbis_File *vf){
@@ -434,7 +493,7 @@
   /* We get the offset for the last page of the physical bitstream.
      Most OggVorbis files will contain a single logical bitstream */
   end=_get_prev_page(vf,&og);
-  if(end<0)return(end);
+  if(end<0)return end;
 
   /* more than one logical bitstream? */
   tempserialno=ogg_page_serialno(&og);
@@ -444,25 +503,18 @@
 
     /* Chained bitstream. Bisect-search each logical bitstream
        section.  Do so based on serial number only */
-    if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return(OV_EREAD);
+    if(_bisect_forward_serialno(vf,0,0,end+1,serialno,0)<0)return OV_EREAD;
 
   }else{
 
     /* Only one logical bitstream */
-    if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return(OV_EREAD);
+    if(_bisect_forward_serialno(vf,0,end,end+1,serialno,0))return OV_EREAD;
 
   }
 
   /* the initial header memory is referenced by vf after; don't free it */
-  _prefetch_all_headers(vf,dataoffset);
-  return(ov_raw_seek(vf,0));
-}
-
-/* clear out the current logical bitstream decoder */ 
-static void _decode_clear(OggVorbis_File *vf){
-  vorbis_dsp_destroy(vf->vd);
-  vf->vd=0;
-  vf->ready_state=OPENED;
+  _prefetch_all_offsets(vf,dataoffset);
+  return ov_raw_seek(vf,0);
 }
 
 /* fetch and process a packet.  Handles the case where we're at a
@@ -577,11 +629,6 @@
           }
 
           _decode_clear(vf);
-	  
-	  if(!vf->seekable){
-	    vorbis_info_clear(vf->vi);
-	    vorbis_comment_clear(vf->vc);
-	  }
         }
       }
     }
@@ -599,7 +646,7 @@
     */
 
     if(vf->ready_state!=INITSET){ 
-      int link;
+      int link,ret;
 
       if(vf->ready_state<STREAMSET){
         if(vf->seekable){
@@ -615,24 +662,22 @@
                                 leave machine uninitialized */
             goto cleanup;
           }
-	  
+
           vf->current_link=link;
-	  
-	  ogg_stream_reset_serialno(vf->os,vf->current_serialno);
-	  vf->ready_state=STREAMSET;
+	  ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
+	  if(ret) goto cleanup;
           
         }else{
           /* we're streaming */
           /* fetch the three header packets, build the info struct */
           
-	  int ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,&og);
+	  int ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
           if(ret) goto cleanup;
           vf->current_link++;
-	  link=0;
         }
       }
       
-      _make_decode_ready(vf);
+      if(_make_decode_ready(vf)) return OV_EBADLINK;
     }
     ogg_stream_pagein(vf->os,&og);
   }
@@ -645,7 +690,7 @@
 /* if, eg, 64 bit stdio is configured by default, this will build with
    fseek64 */
 static int _fseek64_wrap(FILE *f,ogg_int64_t off,int whence){
-  if(f==NULL)return(-1);
+  if(f==NULL)return -1;
   return fseek(f,off,whence);
 }
 
@@ -682,17 +727,15 @@
   /* No seeking yet; Set up a 'single' (current) logical bitstream
      entry for partial open */
   vf->links=1;
-  vf->vi=_ogg_calloc(vf->links,sizeof(*vf->vi));
-  vf->vc=_ogg_calloc(vf->links,sizeof(*vf->vc));
   vf->os=ogg_stream_create(-1); /* fill in the serialno later */
 
   /* Try to fetch the headers, maintaining all the storage */
-  if((ret=_fetch_headers(vf,vf->vi,vf->vc,&vf->current_serialno,NULL))<0){
+  if((ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,NULL))<0){
     vf->datasource=NULL;
     ov_clear(vf);
   }else if(vf->ready_state < PARTOPEN)
     vf->ready_state=PARTOPEN;
-  return(ret);
+  return ret;
 }
 
 static int _ov_open2(OggVorbis_File *vf){
@@ -704,7 +747,7 @@
       vf->datasource=NULL;
       ov_clear(vf);
     }
-    return(ret);
+    return ret;
   }
   return 0;
 }
@@ -716,16 +759,8 @@
     vorbis_dsp_destroy(vf->vd);
     vf->vd=0;
     ogg_stream_destroy(vf->os);
-    
-    if(vf->vi && vf->links){
-      int i;
-      for(i=0;i<vf->links;i++){
-	vorbis_info_clear(vf->vi+i);
-	vorbis_comment_clear(vf->vc+i);
-      }
-      _ogg_free(vf->vi);
-      _ogg_free(vf->vc);
-    }
+    vorbis_info_clear(&vf->vi);
+    vorbis_comment_clear(&vf->vc);
     if(vf->dataoffsets)_ogg_free(vf->dataoffsets);
     if(vf->pcmlengths)_ogg_free(vf->pcmlengths);
     if(vf->serialnos)_ogg_free(vf->serialnos);
@@ -738,7 +773,7 @@
 #ifdef DEBUG_LEAKS
   _VDBG_dump();
 #endif
-  return(0);
+  return 0;
 }
 
 /* inspects the OggVorbis file and finds/documents all the logical
@@ -790,7 +825,7 @@
 }
   
 int ov_test_open(OggVorbis_File *vf){
-  if(vf->ready_state!=PARTOPEN)return(OV_EINVAL);
+  if(vf->ready_state!=PARTOPEN)return OV_EINVAL;
   return _ov_open2(vf);
 }
 
@@ -814,9 +849,9 @@
    vorbis_info structs */
 
 long ov_bitrate(OggVorbis_File *vf,int i){
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(i>=vf->links)return(OV_EINVAL);
-  if(!vf->seekable && i!=0)return(ov_bitrate(vf,0));
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(i>=vf->links)return OV_EINVAL;
+  if(!vf->seekable && i!=0)return ov_bitrate(vf,0);
   if(i<0){
     ogg_int64_t bits=0;
     int i;
@@ -826,24 +861,24 @@
      * gcc 3.x on x86 miscompiled this at optimisation level 2 and above,
      * so this is slightly transformed to make it work.
      */
-    return(bits*1000/ov_time_total(vf,-1));
+    return bits*1000/ov_time_total(vf,-1);
   }else{
     if(vf->seekable){
       /* return the actual bitrate */
-      return((vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i));
+      return (vf->offsets[i+1]-vf->dataoffsets[i])*8000/ov_time_total(vf,i);
     }else{
       /* return nominal if set */
-      if(vf->vi[i].bitrate_nominal>0){
-	return vf->vi[i].bitrate_nominal;
+      if(vf->vi.bitrate_nominal>0){
+	return vf->vi.bitrate_nominal;
       }else{
-	if(vf->vi[i].bitrate_upper>0){
-	  if(vf->vi[i].bitrate_lower>0){
-	    return (vf->vi[i].bitrate_upper+vf->vi[i].bitrate_lower)/2;
+	if(vf->vi.bitrate_upper>0){
+	  if(vf->vi.bitrate_lower>0){
+	    return (vf->vi.bitrate_upper+vf->vi.bitrate_lower)/2;
           }else{
-	    return vf->vi[i].bitrate_upper;
+	    return vf->vi.bitrate_upper;
           }
         }
-	return(OV_FALSE);
+	return OV_FALSE;
       }
     }
   }
@@ -854,24 +889,23 @@
    EINVAL if stream is only partially open 
 */
 long ov_bitrate_instant(OggVorbis_File *vf){
-  int link=(vf->seekable?vf->current_link:0);
   long ret;
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(vf->samptrack==0)return(OV_FALSE);
-  ret=vf->bittrack/vf->samptrack*vf->vi[link].rate;
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(vf->samptrack==0)return OV_FALSE;
+  ret=vf->bittrack/vf->samptrack*vf->vi.rate;
   vf->bittrack=0;
   vf->samptrack=0;
-  return(ret);
+  return ret;
 }
 
 /* Guess */
 long ov_serialnumber(OggVorbis_File *vf,int i){
-  if(i>=vf->links)return(ov_serialnumber(vf,vf->links-1));
-  if(!vf->seekable && i>=0)return(ov_serialnumber(vf,-1));
+  if(i>=vf->links)return ov_serialnumber(vf,vf->links-1);
+  if(!vf->seekable && i>=0)return ov_serialnumber(vf,-1);
   if(i<0){
-    return(vf->current_serialno);
+    return vf->current_serialno;
   }else{
-    return(vf->serialnos[i]);
+    return vf->serialnos[i];
   }
 }
 
@@ -881,16 +915,16 @@
             or if stream is only partially open
 */
 ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i){
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(!vf->seekable || i>=vf->links)return OV_EINVAL;
   if(i<0){
     ogg_int64_t acc=0;
     int i;
     for(i=0;i<vf->links;i++)
       acc+=ov_raw_total(vf,i);
-    return(acc);
+    return acc;
   }else{
-    return(vf->offsets[i+1]-vf->offsets[i]);
+    return vf->offsets[i+1]-vf->offsets[i];
   }
 }
 
@@ -900,16 +934,16 @@
             length) or only partially open 
 */
 ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i){
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(!vf->seekable || i>=vf->links)return OV_EINVAL;
   if(i<0){
     ogg_int64_t acc=0;
     int i;
     for(i=0;i<vf->links;i++)
       acc+=ov_pcm_total(vf,i);
-    return(acc);
+    return acc;
   }else{
-    return(vf->pcmlengths[i*2+1]);
+    return vf->pcmlengths[i*2+1];
   }
 }
 
@@ -919,16 +953,16 @@
             length) or only partially open 
 */
 ogg_int64_t ov_time_total(OggVorbis_File *vf,int i){
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(!vf->seekable || i>=vf->links)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(!vf->seekable || i>=vf->links)return OV_EINVAL;
   if(i<0){
     ogg_int64_t acc=0;
     int i;
     for(i=0;i<vf->links;i++)
       acc+=ov_time_total(vf,i);
-    return(acc);
+    return acc;
   }else{
-    return(((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi[i].rate);
+    return ((ogg_int64_t)vf->pcmlengths[i*2+1])*1000/vf->vi.rate;
   }
 }
 
@@ -944,11 +978,11 @@
   ogg_page og={0,0,0,0};
   ogg_packet op={0,0,0,0,0,0};
   
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
   if(!vf->seekable)
-    return(OV_ENOSEEK); /* don't dump machine if we can't seek */
+    return OV_ENOSEEK; /* don't dump machine if we can't seek */
 
-  if(pos<0 || pos>vf->end)return(OV_EINVAL);
+  if(pos<0 || pos>vf->end)return OV_EINVAL;
 
   /* don't yet clear out decoding machine (if it's initialized), in
      the case we're in the same link.  Restart the decode lapping, and
@@ -990,8 +1024,8 @@
       
         if(result>0){
 
-	  if(vf->vi[vf->current_link].codec_setup){
-	    thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+	  if(vf->vi.codec_setup){
+	    thisblock=vorbis_packet_blocksize(&vf->vi,&op);
             if(thisblock<0){
               ogg_stream_packetout(vf->os,NULL);
               thisblock=0;
@@ -1031,7 +1065,7 @@
         break;
       }
       
-      /* has our decoding just traversed a bitstream boundary? */
+      /* did we just grab a page from other than current link? */
       if(vf->ready_state>=STREAMSET)
         if(vf->current_serialno!=ogg_page_serialno(&og)){
           _decode_clear(vf); /* clear out stream state */
@@ -1048,11 +1082,14 @@
           goto seek_error; /* sign of a bogus stream.  error out,
                               leave machine uninitialized */
  
-	vf->current_link=link;
-	
+	/* need to initialize machine to this link */
+	{
+	  int ret=_set_link_number_preserve_pos(vf,link);
+	  if(ret) goto seek_error;
+	}
         ogg_stream_reset_serialno(vf->os,vf->current_serialno);
         ogg_stream_reset_serialno(work_os,vf->current_serialno); 
-	vf->ready_state=STREAMSET;
+	
         
       }
     
@@ -1071,7 +1108,7 @@
   ogg_stream_destroy(work_os);
   vf->bittrack=0;
   vf->samptrack=0;
-  return(0);
+  return 0;
 
  seek_error:
   ogg_packet_release(&op);
@@ -1097,9 +1134,9 @@
   ogg_page og={0,0,0,0};
   ogg_packet op={0,0,0,0,0,0};
 
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(!vf->seekable)return(OV_ENOSEEK);
-  if(pos<0 || pos>total)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(!vf->seekable)return OV_ENOSEEK;
+  if(pos<0 || pos>total)return OV_EINVAL;
  
   /* which bitstream section does this pcm offset occur in? */
   for(link=vf->links-1;link>=0;link--){
@@ -1107,6 +1144,16 @@
     if(pos>=total)break;
   }
 
+
+  if(link!=vf->current_link){
+    int ret=_set_link_number(vf,link);
+    if(ret) goto seek_error;
+  }else{
+    vorbis_dsp_restart(vf->vd);
+  }
+
+  ogg_stream_reset_serialno(vf->os,vf->serialnos[link]);
+
   /* search within the logical bitstream for the page with the highest
      pcm_pos preceeding (or equal to) pos.  There is a danger here;
      missing pages or incorrect frame number information in the
@@ -1189,22 +1236,9 @@
       
       if(_get_next_page(vf,&og,-1)<0){
         ogg_page_release(&og);
-	return(OV_EOF); /* shouldn't happen */
+	return OV_EOF; /* shouldn't happen */
       }
 
-      if(link!=vf->current_link){
-	/* Different link; dump entire decode machine */
-	_decode_clear(vf);  
-	
-	vf->current_link=link;
-	vf->current_serialno=ogg_page_serialno(&og);
-	vf->ready_state=STREAMSET;
-	
-      }else{
-	vorbis_dsp_restart(vf->vd);
-      }
-
-      ogg_stream_reset_serialno(vf->os,vf->current_serialno);
       ogg_stream_pagein(vf->os,&og);
 
       /* pull out all but last packet; the one with granulepos */
@@ -1253,7 +1287,7 @@
 
   ogg_page_release(&og);
   ogg_packet_release(&op);
-  return(0);
+  return 0;
   
  seek_error:
 
@@ -1274,8 +1308,8 @@
   ogg_page og={0,0,0,0};
   int thisblock,lastblock=0;
   int ret=ov_pcm_seek_page(vf,pos);
-  if(ret<0)return(ret);
-  _make_decode_ready(vf);
+  if(ret<0)return ret;
+  if(_make_decode_ready(vf))return OV_EBADLINK;
 
   /* discard leading packets we don't need for the lapping of the
      position we want; don't decode them */
@@ -1284,7 +1318,7 @@
 
     int ret=ogg_stream_packetpeek(vf->os,&op);
     if(ret>0){
-      thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+      thisblock=vorbis_packet_blocksize(&vf->vi,&op);
       if(thisblock<0){
         ogg_stream_packetout(vf->os,NULL);
         continue; /* non audio packet */
@@ -1292,7 +1326,7 @@
       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
       
       if(vf->pcm_offset+((thisblock+
-			  vorbis_info_blocksize(vf->vi,1))>>2)>=pos)break;
+			  vorbis_info_blocksize(&vf->vi,1))>>2)>=pos)break;
       
       /* remove the packet from packet queue and track its granulepos */
       ogg_stream_packetout(vf->os,NULL);
@@ -1322,7 +1356,7 @@
       if(vf->current_serialno!=ogg_page_serialno(&og))_decode_clear(vf);
       
       if(vf->ready_state<STREAMSET){
-	int link;
+	int link,ret;
         
         vf->current_serialno=ogg_page_serialno(&og);
         for(link=0;link<vf->links;link++)
@@ -1330,13 +1364,14 @@
         if(link==vf->links){
           ogg_page_release(&og);
           ogg_packet_release(&op);
-	  return(OV_EBADLINK);
+	  return OV_EBADLINK;
         }
+
+
         vf->current_link=link;
-	
-	ogg_stream_reset_serialno(vf->os,vf->current_serialno); 
-	vf->ready_state=STREAMSET;      
-	_make_decode_ready(vf);
+	ret=_fetch_headers(vf,&vf->vi,&vf->vc,&vf->current_serialno,&og);
+	if(ret) return ret;
+	if(_make_decode_ready(vf))return OV_EBADLINK;
         lastblock=0;
       }
 
@@ -1375,9 +1410,9 @@
   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
   ogg_int64_t time_total=ov_time_total(vf,-1);
 
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(!vf->seekable)return(OV_ENOSEEK);
-  if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(!vf->seekable)return OV_ENOSEEK;
+  if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
   
   /* which bitstream section does this time offset occur in? */
   for(link=vf->links-1;link>=0;link--){
@@ -1388,8 +1423,11 @@
 
   /* enough information to convert time offset to pcm offset */
   {
-    ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
-    return(ov_pcm_seek(vf,target));
+    int ret=_set_link_number(vf,link);
+    if(ret)return ret;
+    return 
+      ov_pcm_seek(vf,pcm_total+(milliseconds-time_total)*
+		  vf->vi.rate/1000);
   }
 }
 
@@ -1402,9 +1440,9 @@
   ogg_int64_t pcm_total=ov_pcm_total(vf,-1);
   ogg_int64_t time_total=ov_time_total(vf,-1);
 
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  if(!vf->seekable)return(OV_ENOSEEK);
-  if(milliseconds<0 || milliseconds>time_total)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  if(!vf->seekable)return OV_ENOSEEK;
+  if(milliseconds<0 || milliseconds>time_total)return OV_EINVAL;
   
   /* which bitstream section does this time offset occur in? */
   for(link=vf->links-1;link>=0;link--){
@@ -1415,31 +1453,34 @@
 
   /* enough information to convert time offset to pcm offset */
   {
-    ogg_int64_t target=pcm_total+(milliseconds-time_total)*vf->vi[link].rate/1000;
-    return(ov_pcm_seek_page(vf,target));
+    int ret=_set_link_number(vf,link);
+    if(ret)return ret;
+    return 
+      ov_pcm_seek_page(vf,pcm_total+(milliseconds-time_total)*
+		       vf->vi.rate/1000);
   }
 }
 
 /* tell the current stream offset cursor.  Note that seek followed by
    tell will likely not give the set offset due to caching */
 ogg_int64_t ov_raw_tell(OggVorbis_File *vf){
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  return(vf->offset);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  return vf->offset;
 }
 
 /* return PCM offset (sample) of next PCM sample to be read */
 ogg_int64_t ov_pcm_tell(OggVorbis_File *vf){
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
-  return(vf->pcm_offset);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
+  return vf->pcm_offset;
 }
 
 /* return time offset (milliseconds) of next PCM sample to be read */
 ogg_int64_t ov_time_tell(OggVorbis_File *vf){
-  int link=0;
+  int link=0,ret;
   ogg_int64_t pcm_total=0;
   ogg_int64_t time_total=0;
   
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
   if(vf->seekable){
     pcm_total=ov_pcm_total(vf,-1);
     time_total=ov_time_total(vf,-1);
@@ -1452,7 +1493,7 @@
     }
   }
 
-  return(time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi[link].rate);
+  return time_total+(1000*vf->pcm_offset-pcm_total)/vf->vi.rate;
 }
 
 /*  link:   -1) return the vorbis_info struct for the bitstream section
@@ -1465,37 +1506,25 @@
 
 vorbis_info *ov_info(OggVorbis_File *vf,int link){
   if(vf->seekable){
-    if(link<0)
-      if(vf->ready_state>=STREAMSET)
-	return vf->vi+vf->current_link;
-      else
-      return vf->vi;
-    else
-      if(link>=vf->links)
-	return NULL;
-      else
-	return vf->vi+link;
-  }else{
-    return vf->vi;
+    if(link>=vf->links)return NULL;
+    if(link>=0){
+      int ret=_set_link_number_preserve_pos(vf,link);
+      if(ret)return NULL;
+    }
   }
+  return &vf->vi;
 }
 
 /* grr, strong typing, grr, no templates/inheritence, grr */
 vorbis_comment *ov_comment(OggVorbis_File *vf,int link){
   if(vf->seekable){
-    if(link<0)
-      if(vf->ready_state>=STREAMSET)
-	return vf->vc+vf->current_link;
-      else
-	return vf->vc;
-    else
-      if(link>=vf->links)
-	return NULL;
-      else
-	return vf->vc+link;
-  }else{
-    return vf->vc;
+    if(link>=vf->links)return NULL;
+    if(link>=0){
+      int ret=_set_link_number_preserve_pos(vf,link);
+      if(ret)return NULL;
+    }
   }
+  return &vf->vc;
 }
 
 /* up to this point, everything could more or less hide the multiple
@@ -1531,20 +1560,20 @@
   long samples;
   long channels;
 
-  if(vf->ready_state<OPENED)return(OV_EINVAL);
+  if(vf->ready_state<OPENED)return OV_EINVAL;
 
   while(1){
     if(vf->ready_state==INITSET){
-      channels=ov_info(vf,-1)->channels;
+      channels=vf->vi.channels;
       samples=vorbis_dsp_pcmout(vf->vd,buffer,(bytes_req>>1)/channels);
       if(samples){
         if(samples>0){
           vorbis_dsp_read(vf->vd,samples);
           vf->pcm_offset+=samples;
           if(bitstream)*bitstream=vf->current_link;
-	  return(samples*2*channels);
+	  return samples*2*channels;
         }
-	return(samples);
+	return samples;
       }
     }
 
@@ -1552,9 +1581,9 @@
     {
       int ret=_fetch_and_process_packet(vf,1,1);
       if(ret==OV_EOF)
-	return(0);
+	return 0;
       if(ret<=0)
-	return(ret);
+	return ret;
     }
 
   }

<p><p>--- >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