[xiph-cvs] cvs commit: vorbis/lib block.c psytune.c vorbisfile.c window.c window.h

Monty xiphmont at xiph.org
Tue Mar 4 13:22:12 PST 2003



xiphmont    03/03/04 16:22:11

  Modified:    lib      block.c psytune.c vorbisfile.c window.c window.h
  Log:
  OPtimized case of seeking within a single link; reset decode state
  without dumping decode setup.  Roughly 5-10x faster this way.
  
  Raft of small vorbisfile seek fixes (nearly all to do with exact
  positioning around stream boundaries).

Revision  Changes    Path
1.71      +22 -5     vorbis/lib/block.c

Index: block.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/block.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- block.c	2 Mar 2003 21:32:00 -0000	1.70
+++ block.c	4 Mar 2003 21:22:11 -0000	1.71
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: PCM data vector blocking, windowing and dis/reassembly
- last mod: $Id: block.c,v 1.70 2003/03/02 21:32:00 xiphmont Exp $
+ last mod: $Id: block.c,v 1.71 2003/03/04 21:22:11 xiphmont Exp $
 
  Handle windowing, overlap-add, etc of the PCM vectors.  This is made
  more amusing by Vorbis' current two allowed block sizes.
@@ -186,8 +186,8 @@
   mdct_init(b->transform[1][0],ci->blocksizes[1]);
 
   /* Vorbis I uses only window type 0 */
-  b->window[0]=_vorbis_window(0,ci->blocksizes[0]/2);
-  b->window[1]=_vorbis_window(0,ci->blocksizes[1]/2);
+  b->window[0]=_vorbis_window_create(0,ci->blocksizes[0]/2);
+  b->window[1]=_vorbis_window_create(0,ci->blocksizes[1]/2);
 
   if(encp){ /* encode/decode differ here */
 
@@ -637,13 +637,30 @@
   return(1);
 }
 
-int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
-  _vds_shared_init(v,vi,0);
+int vorbis_synthesis_restart(vorbis_dsp_state *v){
+  vorbis_info *vi=v->vi;
+  codec_setup_info *ci;
+
+  if(!v->backend_state)return -1;
+  if(!vi)return -1;
+  ci=vi->codec_setup;
+  if(!ci)return -1;
 
+  v->centerW=ci->blocksizes[1]/2;
+  v->pcm_current=v->centerW;
+  
   v->pcm_returned=-1;
   v->granulepos=-1;
   v->sequence=-1;
+  v->eofflag=0;
   ((private_state *)(v->backend_state))->sample_count=-1;
+
+  return(0);
+}
+
+int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi){
+  _vds_shared_init(v,vi,0);
+  vorbis_synthesis_restart(v);
 
   return(0);
 }

<p><p>1.20      +2 -2      vorbis/lib/psytune.c

Index: psytune.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/psytune.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- psytune.c	22 Jan 2002 08:06:07 -0000	1.19
+++ psytune.c	4 Mar 2003 21:22:11 -0000	1.20
@@ -12,7 +12,7 @@
 
  function: simple utility that runs audio through the psychoacoustics
            without encoding
- last mod: $Id: psytune.c,v 1.19 2002/01/22 08:06:07 xiphmont Exp $
+ last mod: $Id: psytune.c,v 1.20 2003/03/04 21:22:11 xiphmont Exp $
 
  ********************************************************************/
 
@@ -280,7 +280,7 @@
   flr[1]=_ogg_calloc(framesize/2,sizeof(float));
   buffer=_ogg_malloc(framesize*4);
   buffer2=buffer+framesize*2;
-  window=_vorbis_window(0,framesize,framesize/2,framesize/2);
+  window=_vorbis_window_create(0,framesize,framesize/2,framesize/2);
   mdct_init(&m_look,framesize);
   drft_init(&f_look,framesize);
   _vp_psy_init(&p_look,&_psy_set0,&_psy_set0G,framesize/2,44100);

<p><p>1.67      +72 -29    vorbis/lib/vorbisfile.c

Index: vorbisfile.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/vorbisfile.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- vorbisfile.c	2 Mar 2003 21:32:00 -0000	1.66
+++ vorbisfile.c	4 Mar 2003 21:22:11 -0000	1.67
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: stdio-based convenience library for opening/seeking/decoding
- last mod: $Id: vorbisfile.c,v 1.66 2003/03/02 21:32:00 xiphmont Exp $
+ last mod: $Id: vorbisfile.c,v 1.67 2003/03/04 21:22:11 xiphmont Exp $
 
  ********************************************************************/
 
@@ -444,6 +444,14 @@
   vf->samptrack=0.f;
 }
 
+/* restart the decoder, but don't clear out machine init */
+static void _decode_restart(OggVorbis_File *vf){
+  vorbis_synthesis_restart(&vf->vd);
+  vf->bittrack=0.f;
+  vf->samptrack=0.f;
+}
+
+
 /* fetch and process a packet.  Handles the case where we're at a
    bitstream boundary and dumps the decoding machine.  If the decoding
    machine is unloaded, it loads it.  It also keeps pcm_offset up to
@@ -540,17 +548,22 @@
     }
 
     if(vf->ready_state>=OPENED){
+      int ret;
       if(!readp)return(0);
-      if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* eof. 
-							leave unitialized */
-      /* bitrate tracking; add the header's bytes here, the body bytes
-	 are done by packet above */
+      if((ret=_get_next_page(vf,&og,-1))<0){
+	return(OV_EOF); /* eof. 
+			   leave unitialized */
+      }
+
+	/* bitrate tracking; add the header's bytes here, the body bytes
+	   are done by packet above */
       vf->bittrack+=og.header_len*8;
       
       /* has our decoding just traversed a bitstream boundary? */
       if(vf->ready_state==INITSET){
         if(vf->current_serialno!=ogg_page_serialno(&og)){
-	  if(!spanp)return(OV_EOF);
+	  if(!spanp)
+	    return(OV_EOF);
 
           _decode_clear(vf);
           
@@ -908,6 +921,8 @@
 
 int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos){
   ogg_stream_state work_os;
+  int i;
+  ogg_int64_t count=0;
 
   if(vf->ready_state<OPENED)return(OV_EINVAL);
   if(!vf->seekable)
@@ -915,9 +930,15 @@
 
   if(pos<0 || pos>vf->end)return(OV_EINVAL);
 
-  /* clear out decoding machine state */
+  /* 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
+     let _fetch_and_process_packet deal with a potential bitstream
+     boundary */
   vf->pcm_offset=-1;
-  _decode_clear(vf);
+  ogg_stream_reset_serialno(&vf->os,
+			    vf->current_serialno); /* must set serialno */
+  _decode_restart(vf);
+  //_decode_clear(vf);
   
   _seek_helper(vf,pos);
 
@@ -944,17 +965,25 @@
     int thisblock;
     int eosflag;
 
-    ogg_stream_init(&work_os,-1); /* get the memory ready */
+    ogg_stream_init(&work_os,vf->current_serialno); /* get the memory ready */
+    ogg_stream_reset(&work_os); /* eliminate the spurious OV_HOLE
+                                   return from not necessarily
+                                   starting from the beginning */
 
     while(1){
-      if(vf->ready_state==STREAMSET){
+      if(vf->ready_state>=STREAMSET){
         /* snarf/scan a packet if we can */
         int result=ogg_stream_packetout(&work_os,&op);
       
         if(result>0){
 
-	  if(vf->vi[vf->current_link].codec_setup)
+	  if(vf->vi[vf->current_link].codec_setup){
             thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
+	    if(thisblock<0){
+	      ogg_stream_packetout(&vf->os,NULL);
+	      continue;
+	    }
+	  }
           if(eosflag)
             ogg_stream_packetout(&vf->os,NULL);
           else
@@ -987,11 +1016,11 @@
       }
       
       /* has our decoding just traversed a bitstream boundary? */
-      if(vf->ready_state==STREAMSET)
+      if(vf->ready_state>=STREAMSET)
         if(vf->current_serialno!=ogg_page_serialno(&og)){
-	_decode_clear(vf); /* clear out stream state */
-	ogg_stream_clear(&work_os);
-      }
+	  _decode_clear(vf); /* clear out stream state */
+	  ogg_stream_clear(&work_os);
+	}
 
       if(vf->ready_state<STREAMSET){
         int link;
@@ -1127,17 +1156,26 @@
     {
       ogg_page og;
       ogg_packet op;
-      /* clear out decoding machine state */
-      _decode_clear(vf);  
+      
       /* seek */
       _seek_helper(vf,best);
+      vf->pcm_offset=-1;
       
       if(_get_next_page(vf,&og,-1)<0)return(OV_EOF); /* shouldn't happen */
-      vf->current_serialno=ogg_page_serialno(&og);
-      vf->current_link=link;
       
+      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{
+	_decode_restart(vf);  
+      }
+
       ogg_stream_reset_serialno(&vf->os,vf->current_serialno);
-      vf->ready_state=STREAMSET;
       ogg_stream_pagein(&vf->os,&og);
 
       /* pull out all but last packet; the one with granulepos */
@@ -1148,10 +1186,10 @@
              preceeding page. Keep fetching previous pages until we
              get one with a granulepos or without the 'continued' flag
              set.  Then just use raw_seek for simplicity. */
-
-	  _decode_clear(vf);  
+	  
+	  //_decode_restart(vf);  
           _seek_helper(vf,best);
-
+	  
           while(1){
             result=_get_prev_page(vf,&og);
             if(result<0) goto seek_error;
@@ -1163,9 +1201,9 @@
           }
         }
         if(result<0){
-      result = OV_EBADPACKET; 
-      goto seek_error;
-    }
+	  result = OV_EBADPACKET; 
+	  goto seek_error;
+	}
         if(op.granulepos!=-1){
           vf->pcm_offset=op.granulepos-vf->pcmlengths[vf->current_link*2];
           if(vf->pcm_offset<0)vf->pcm_offset=0;
@@ -1210,7 +1248,10 @@
     int ret=ogg_stream_packetpeek(&vf->os,&op);
     if(ret>0){
       thisblock=vorbis_packet_blocksize(vf->vi+vf->current_link,&op);
-      if(thisblock<0)thisblock=0; /* non audio packet */
+      if(thisblock<0){
+	ogg_stream_packetout(&vf->os,NULL);
+	continue; /* non audio packet */
+      }
       if(lastblock)vf->pcm_offset+=(lastblock+thisblock)>>2;
       
       if(vf->pcm_offset+((thisblock+
@@ -1469,8 +1510,10 @@
     /* suck in another packet */
     {
       int ret=_fetch_and_process_packet(vf,NULL,1,1);
-      if(ret==OV_EOF)return(0);
-      if(ret<=0)return(ret);
+      if(ret==OV_EOF)
+	return(0);
+      if(ret<=0)
+	return(ret);
     }
 
   }

<p><p>1.20      +2 -2      vorbis/lib/window.c

Index: window.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/window.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- window.c	2 Mar 2003 11:45:17 -0000	1.19
+++ window.c	4 Mar 2003 21:22:11 -0000	1.20
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: window functions
- last mod: $Id: window.c,v 1.19 2003/03/02 11:45:17 xiphmont Exp $
+ last mod: $Id: window.c,v 1.20 2003/03/04 21:22:11 xiphmont Exp $
 
  ********************************************************************/
 
@@ -20,7 +20,7 @@
 #include "os.h"
 #include "misc.h"
 
-float *_vorbis_window(int type, int left){
+float *_vorbis_window_create(int type, int left){
   float *ret=_ogg_calloc(left,sizeof(*ret));
   int i;
 

<p><p>1.11      +2 -2      vorbis/lib/window.h

Index: window.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis/lib/window.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- window.h	22 Jan 2002 11:59:00 -0000	1.10
+++ window.h	4 Mar 2003 21:22:11 -0000	1.11
@@ -11,14 +11,14 @@
  ********************************************************************
 
  function: window functions
- last mod: $Id: window.h,v 1.10 2002/01/22 11:59:00 xiphmont Exp $
+ last mod: $Id: window.h,v 1.11 2003/03/04 21:22:11 xiphmont Exp $
 
  ********************************************************************/
 
 #ifndef _V_WINDOW_
 #define _V_WINDOW_
 
-extern float *_vorbis_window(int type,int left);
+extern float *_vorbis_window_create(int type,int left);
 extern void _vorbis_apply_window(float *d,float *window[2],long *blocksizes,
                                  int lW,int W,int nW);
 

<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