[xiph-cvs] cvs commit: ogg/src Makefile.am bitwise.c buffer.c bytewise.c ogginternal.h stream.c sync.c

Monty xiphmont at xiph.org
Fri Mar 21 21:44:52 PST 2003



xiphmont    03/03/22 00:44:52

  Modified:    src      Tag: libogg2-zerocopy Makefile.am bitwise.c
                        buffer.c bytewise.c ogginternal.h stream.c sync.c
  Log:
  Incremental; avoid lost work.

Revision  Changes    Path
No                   revision

<p>No                   revision

<p>1.5.2.2   +1 -1      ogg/src/Makefile.am

Index: Makefile.am
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Makefile.am,v
retrieving revision 1.5.2.1
retrieving revision 1.5.2.2
diff -u -r1.5.2.1 -r1.5.2.2
--- Makefile.am	31 Dec 2002 01:18:02 -0000	1.5.2.1
+++ Makefile.am	22 Mar 2003 05:44:51 -0000	1.5.2.2
@@ -6,7 +6,7 @@
 
 lib_LTLIBRARIES = libogg.la
 
-libogg_la_SOURCES = sync.c stream.c bitwise.c 
+libogg_la_SOURCES = sync.c stream.c bitwise.c bytewise.c
 libogg_la_LDFLAGS = -version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@
 
 debug:

<p><p>1.14.2.12 +25 -40    ogg/src/bitwise.c

Index: bitwise.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/bitwise.c,v
retrieving revision 1.14.2.11
retrieving revision 1.14.2.12
diff -u -r1.14.2.11 -r1.14.2.12
--- bitwise.c	16 Mar 2003 23:31:48 -0000	1.14.2.11
+++ bitwise.c	22 Mar 2003 05:44:51 -0000	1.14.2.12
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: pack variable sized words into an octet stream
-  last mod: $Id: bitwise.c,v 1.14.2.11 2003/03/16 23:31:48 xiphmont Exp $
+  last mod: $Id: bitwise.c,v 1.14.2.12 2003/03/22 05:44:51 xiphmont Exp $
 
  ********************************************************************/
 
@@ -24,12 +24,6 @@
 #include <stdlib.h>
 #include "ogginternal.h"
 
-#ifdef _V_SELFTEST
-#define OGGPACK_CHUNKSIZE 4
-#else
-#define OGGPACK_CHUNKSIZE 128
-#endif
-
 static unsigned long mask[]=
 {0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f,
  0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff,
@@ -39,13 +33,14 @@
  0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff,
  0x3fffffff,0x7fffffff,0xffffffff };
 
-void oggpack_writeinit(oggpack_buffer *b,ogg_buffer_state *oy){
+void oggpack_writeinit(oggpack_buffer *b,ogg_buffer_state *bs){
   memset(b,0,sizeof(*b));
-  b->owner=oy;
+  b->owner=bs;
 }
 
-void oggpackB_writeinit(oggpack_buffer *b,ogg_buffer_state *oy){
-  oggpack_writeinit(b,oy);
+void oggpackB_writeinit(oggpack_buffer *b,ogg_buffer_state *bs){
+  oggpack_writeinit(b,bs);
+  b->owner=bs;
 }
 
 static void _oggpack_extend(oggpack_buffer *b){
@@ -660,7 +655,7 @@
       
 oggpack_buffer o;
 oggpack_buffer r;
-ogg_buffer_state bs;
+ogg_buffer_state *bs;
 ogg_reference *or;
 #define TESTWORDS 4096
 
@@ -686,7 +681,7 @@
   long bytes,i,bitcount=0;
   ogg_reference *or;
 
-  oggpack_writeinit(&o,&bs);
+  oggpack_writeinit(&o,bs);
   for(i=0;i<vals;i++){
     oggpack_write(&o,b[i],bits?bits:ilog(b[i]));
     bitcount+=bits?bits:ilog(b[i]);
@@ -750,7 +745,7 @@
   long bytes,i;
   ogg_reference *or;
 
-  oggpackB_writeinit(&o,&bs);
+  oggpackB_writeinit(&o,bs);
   for(i=0;i<vals;i++)
     oggpackB_write(&o,b[i],bits?bits:ilog(b[i]));
   or=oggpackB_writebuffer(&o);
@@ -871,16 +866,6 @@
     }
   }  
   
-
-}
-
-int bufferlength(ogg_reference *or){
-  int count=0;
-  while(or){
-    count+=or->length;
-    or=or->next;
-  }
-  return count;
 }
 
 void _end_verify(int count){
@@ -1076,7 +1061,7 @@
 
   /* Test read/write together */
   /* Later we test against pregenerated bitstreams */
-  ogg_buffer_init(&bs);
+  bs=ogg_buffer_create();
 
   fprintf(stderr,"\nSmall preclipped packing (LSb): ");
   cliptest(testbuffer1,test1size,0,one,onesize);
@@ -1093,7 +1078,7 @@
   fprintf(stderr,"\n32 bit preclipped packing (LSb): ");
 
   oggpack_writeclear(&o);
-  oggpack_writeinit(&o,&bs);
+  oggpack_writeinit(&o,bs);
   for(i=0;i<test2size;i++)
     oggpack_write(&o,large[i],32);
   or=oggpack_writebuffer(&o);
@@ -1126,7 +1111,7 @@
 
   fprintf(stderr,"\nTesting read past end (LSb): ");
   {
-    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{&bs}};
+    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
     ogg_reference lor={&lob,0,8,0};
 
     oggpack_readinit(&r,&lor);
@@ -1143,7 +1128,7 @@
     }
   }
   {
-    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{&bs}};
+    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
     ogg_reference lor={&lob,0,8,0};
     unsigned long test;
 
@@ -1188,7 +1173,7 @@
 
   fprintf(stderr,"\n32 bit preclipped packing (MSb): ");
 
-  oggpackB_writeinit(&o,&bs);
+  oggpackB_writeinit(&o,bs);
   for(i=0;i<test2size;i++)
     oggpackB_write(&o,large[i],32);
   or=oggpackB_writebuffer(&o);
@@ -1221,7 +1206,7 @@
 
   fprintf(stderr,"\nTesting read past end (MSb): ");
   {
-    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{&bs}};
+    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
     ogg_reference lor={&lob,0,8,0};
     unsigned long test;
 
@@ -1239,7 +1224,7 @@
     }
   }
   {
-    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{&bs}};
+    ogg_buffer lob={"\0\0\0\0\0\0\0\0",8,0,{0}};
     ogg_reference lor={&lob,0,8,0};
     unsigned long test;
     oggpackB_readinit(&r,&lor);
@@ -1274,7 +1259,7 @@
     unsigned char flat[4*TESTWORDS]; /* max possible needed size */
 
     fprintf(stderr,"\rRandomized testing (LSb)... (%ld)   ",10000-i);
-    oggpack_writeinit(&o,&bs);
+    oggpack_writeinit(&o,bs);
 
     /* generate a list of words and lengths */
     /* write the required number of bits out to packbuffer */
@@ -1325,7 +1310,7 @@
         if(or)
           orl=ogg_buffer_extend(orl,ilen+ibegin);
         else
-	  or=orl=ogg_buffer_alloc(&bs,ilen+ibegin);
+	  or=orl=ogg_buffer_alloc(bs,ilen+ibegin);
 
         memcpy(orl->buffer->data+ibegin,ptr,ilen);
        
@@ -1336,7 +1321,7 @@
         ptr+=ilen;
       }
 
-      if(bufferlength(or)!=(bitcount+7)/8){
+      if(ogg_buffer_length(or)!=(bitcount+7)/8){
         fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
         exit(1);
       }
@@ -1356,7 +1341,7 @@
           bitcount+=len[j];
         ogg_buffer_posttruncate(or,((bitcount+7)/8));
 
-	if((count=bufferlength(or))!=(bitcount+7)/8){
+	if((count=ogg_buffer_length(or))!=(bitcount+7)/8){
           fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
           exit(1);
         }
@@ -1465,7 +1450,7 @@
     unsigned char flat[4*TESTWORDS]; /* max possible needed size */
 
     fprintf(stderr,"\rRandomized testing (MSb)... (%ld)   ",10000-i);
-    oggpackB_writeinit(&o,&bs);
+    oggpackB_writeinit(&o,bs);
 
     /* generate a list of words and lengths */
     /* write the required number of bits out to packbuffer */
@@ -1516,7 +1501,7 @@
         if(or)
           orl=ogg_buffer_extend(orl,ilen+ibegin);
         else
-	  or=orl=ogg_buffer_alloc(&bs,ilen+ibegin);
+	  or=orl=ogg_buffer_alloc(bs,ilen+ibegin);
 
         memcpy(orl->buffer->data+ibegin,ptr,ilen);
        
@@ -1527,7 +1512,7 @@
         ptr+=ilen;
       }
 
-      if(bufferlength(or)!=(bitcount+7)/8){
+      if(ogg_buffer_length(or)!=(bitcount+7)/8){
         fprintf(stderr,"\nERROR: buffer length incorrect after build.\n");
         exit(1);
       }
@@ -1547,7 +1532,7 @@
           bitcount+=len[j];
         ogg_buffer_posttruncate(or,((bitcount+7)/8));
 
-	if((count=bufferlength(or))!=(bitcount+7)/8){
+	if((count=ogg_buffer_length(or))!=(bitcount+7)/8){
           fprintf(stderr,"\nERROR: buffer length incorrect after truncate.\n");
           exit(1);
         }
@@ -1647,7 +1632,7 @@
   }
   fprintf(stderr,"\rRandomized testing (MSb)... ok.   \n");
 
-  ogg_buffer_clear(&bs);
+  ogg_buffer_destroy(bs);
   return(0);
 }  
 #endif  /* _V_SELFTEST */

<p><p>1.1.2.8   +63 -32    ogg/src/Attic/buffer.c

Index: buffer.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/buffer.c,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -u -r1.1.2.7 -r1.1.2.8
--- buffer.c	16 Mar 2003 23:31:48 -0000	1.1.2.7
+++ buffer.c	22 Mar 2003 05:44:51 -0000	1.1.2.8
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: centralized fragment buffer management
-  last mod: $Id: buffer.c,v 1.1.2.7 2003/03/16 23:31:48 xiphmont Exp $
+  last mod: $Id: buffer.c,v 1.1.2.8 2003/03/22 05:44:51 xiphmont Exp $
 
  ********************************************************************/
 
@@ -30,38 +30,59 @@
 /* management is here; actual production and consumption of data is
    found in the rest of the libogg code */
 
-void ogg_buffer_init(ogg_buffer_state *bs){
-  memset(bs,0,sizeof(*bs));
+ogg_buffer_state *ogg_buffer_create(void){
+  ogg_buffer_state *bs=_ogg_calloc(1,sizeof(*bs));
   ogg_mutex_init(&bs->mutex);
+  return bs;
 }
 
-void ogg_buffer_clear(ogg_buffer_state *bs){
-#ifdef OGGBUFFER_DEBUG
-  if(bs->outstanding_buffers!=0)
-    fprintf(stderr,"WARNING: Freeing ogg_buffer_state with buffers outstanding.\n");
-  if(bs->outstanding_references!=0)
-    fprintf(stderr,"WARNING: Freeing ogg_buffer_state with buffers outstanding.\n");
-#endif
-
-  ogg_mutex_clear(&bs->mutex);
-  
-  while(bs->unused_buffers){
-    ogg_buffer *b=bs->unused_buffers;
-    bs->unused_buffers=b->ptr.next;
-    if(b->data)_ogg_free(b->data);
-    _ogg_free(b);
-  }
-  while(bs->unused_references){
-    ogg_reference *r=bs->unused_references;
-    bs->unused_references=r->next;
-    _ogg_free(r);
+/* destruction is 'lazy'; there may be memory references outstanding,
+   and yanking the buffer state out from underneath would be
+   antisocial.  Dealloc what is currently unused and have
+   _release_one watch for the stragglers to come in.  When they do,
+   finish destruction. */
+
+/* call the helper while holding lock */
+static void _ogg_buffer_destroy(ogg_buffer_state *bs){
+  ogg_buffer *bt;
+  ogg_reference *rt;
+
+  if(bs->shutdown){
+    bt=bs->unused_buffers;
+    rt=bs->unused_references;
+
+    if(!bs->outstanding){
+      ogg_mutex_unlock(&bs->mutex);
+      ogg_mutex_clear(&bs->mutex);
+      _ogg_free(bs);
+    }else
+      ogg_mutex_unlock(&bs->mutex);
+
+    while(bt){
+      ogg_buffer *b=bt;
+      bt=b->ptr.next;
+      if(b->data)_ogg_free(b->data);
+      _ogg_free(b);
+    }
+    while(rt){
+      ogg_reference *r=rt;
+      rt=r->next;
+      _ogg_free(r);
+    }
   }
 }
 
+void ogg_buffer_destroy(ogg_buffer_state *bs){
+  ogg_mutex_lock(&bs->mutex);
+  bs->shutdown=1;
+  _ogg_buffer_destroy(bs);
+}
+
 static ogg_buffer *_fetch_buffer(ogg_buffer_state *bs,long bytes){
   ogg_buffer    *ob;
   ogg_mutex_lock(&bs->mutex);
-  
+  bs->outstanding++;
+
   /* do we have an unused buffer sitting in the pool? */
   if(bs->unused_buffers){
     ob=bs->unused_buffers;
@@ -81,14 +102,15 @@
     ob->size=bytes;
   }
 
-  ob->ptr.owner=bs;
   ob->refcount=1;
+  ob->ptr.owner=bs;
   return ob;
 }
 
 static ogg_reference *_fetch_ref(ogg_buffer_state *bs){
   ogg_reference *or;
   ogg_mutex_lock(&bs->mutex);
+  bs->outstanding++;
 
   /* do we have an unused reference sitting in the pool? */
   if(bs->unused_references){
@@ -119,7 +141,7 @@
 
 /* enlarge the data buffer in the current link */
 void ogg_buffer_realloc(ogg_reference *or,long bytes){
-  ogg_buffer    *ob=*or->buffer;
+  ogg_buffer    *ob=or->buffer;
   
   /* if the unused buffer is too small, grow it */
   if(ob->size<bytes){
@@ -197,8 +219,7 @@
 
 void ogg_buffer_release_one(ogg_reference *or){
   ogg_buffer *ob=or->buffer;
-  ogg_buffer_state *bs=or->buffer->ptr.owner;
-
+  ogg_buffer_state *bs=ob->ptr.owner;
   ogg_mutex_lock(&bs->mutex);
 
 #ifdef OGGBUFFER_DEBUG
@@ -208,15 +229,17 @@
   
   ob->refcount--;
   if(ob->refcount==0){
-    /* release the fragment back to unused pool */
+    bs->outstanding--; /* for the returned buffer */
     ob->ptr.next=bs->unused_buffers;
     bs->unused_buffers=ob;
   }
-
+  
+  bs->outstanding--; /* for the returned reference */
   or->next=bs->unused_references;
   bs->unused_references=or;
 
-  ogg_mutex_unlock(&bs->mutex);
+  _ogg_buffer_destroy(bs); /* lazy cleanup (if needed) */
+
 }
 
 /* release the references, decrease the refcounts of buffers to which
@@ -264,7 +287,7 @@
   return(or);
 }
 
-/* *head is appened to the front end (head) of *tail; both continue to
+/* *head is appended to the front end (head) of *tail; both continue to
    be valid pointers, with *tail at the tail and *head at the head */
 ogg_reference *ogg_buffer_cat(ogg_reference *tail, ogg_reference *head){
   while(tail->next){
@@ -274,3 +297,11 @@
   return ogg_buffer_walk(head);
 }
 
+long ogg_buffer_length(ogg_reference *or){
+  int count=0;
+  while(or){
+    count+=or->length;
+    or=or->next;
+  }
+  return count;
+}

<p><p>1.1.2.2   +388 -19   ogg/src/Attic/bytewise.c

Index: bytewise.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/bytewise.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- bytewise.c	20 Mar 2003 23:06:39 -0000	1.1.2.1
+++ bytewise.c	22 Mar 2003 05:44:51 -0000	1.1.2.2
@@ -11,7 +11,7 @@
  ********************************************************************
 
   function: byte-aligned access; array-like abstraction over buffers
-  last mod: $Id: bytewise.c,v 1.1.2.1 2003/03/20 23:06:39 xiphmont Exp $
+  last mod: $Id: bytewise.c,v 1.1.2.2 2003/03/22 05:44:51 xiphmont Exp $
 
  ********************************************************************/
 
@@ -28,6 +28,7 @@
     b->headref=b->baseref;
     b->headpos=b->basepos;
     b->headend=b->headpos+b->headref->length;
+    b->headptr=b->headref->buffer->data+b->headref->begin;
   }
 }
 
@@ -36,9 +37,9 @@
   while(pos>=b->headend){
     /* just seek forward */
     b->headpos+=b->headref->length;
-    pos-=b->headref->length;
     b->headref=b->headref->next;
     b->headend=b->headref->length+b->headpos;
+    b->headptr=b->headref->buffer->data+b->headref->begin;
   }
 }
 
@@ -47,33 +48,33 @@
   while(pos>=b->headend){
     if(!b->headref->next){
       /* perhaps just need to extend length field... */
-      if(pos-b->headpos < b->headref->buffer->size-b->headref->buffer->begin){
+      if(pos-b->headpos < b->headref->buffer->size-b->headref->begin){
 
         /* yes, there's space here */
-	b->headref->length=pos-b->headpos;
+	b->headref->length=pos-b->headpos+1;
+	b->headend=b->headpos+b->headref->length;
 
       }else{
 
         /* extend the array and span */
-	pos-=b->headref->length;
         b->headpos+=b->headref->length;	
         b->headref=ogg_buffer_extend(b->headref,OGGPACK_CHUNKSIZE);
-	b->headend=b->headref->buffer->size+b->headpos;
-
+	b->headend=b->headpos;
+	b->headptr=b->headref->buffer->data+b->headref->begin;
       }
 
     }else{
 
       /* just seek forward */
       b->headpos+=b->headref->length;
-      pos-=b->headref->length;
       b->headref=b->headref->next;
       b->headend=b->headref->length+b->headpos;
+      b->headptr=b->headref->buffer->data+b->headref->begin;
     }
   }
 }
 
-static int oggbyte_init(oggbyte_buffer *b,ogg_reference *or,long base,
+int oggbyte_init(oggbyte_buffer *b,ogg_reference *or,long base,
                         ogg_buffer_state *bs){
   memset(b,0,sizeof(*b));
     
@@ -96,13 +97,13 @@
   return(0);
 }
 
-static void oggbyte_set1(oggbyte_buffer *b,unsigned char val,int pos){
+void oggbyte_set1(oggbyte_buffer *b,unsigned char val,int pos){
   _positionB(b,pos);
   _positionFE(b,pos);
   b->headptr[pos-b->headpos]=val;
 }
 
-static void oggbyte_set2(oggbyte_buffer *b,int val,int pos){
+void oggbyte_set2(oggbyte_buffer *b,int val,int pos){
   _positionB(b,pos);
   _positionFE(b,pos);
   b->headptr[pos-b->headpos]=val;
@@ -110,7 +111,7 @@
   b->headptr[pos-b->headpos]=val>>8;
 }
 
-static void oggbyte_set4(oggbyte_buffer *b,ogg_int32_t val,int pos){
+void oggbyte_set4(oggbyte_buffer *b,ogg_uint32_t val,int pos){
   int i;
   _positionB(b,pos);
   for(i=0;i<4;i++){
@@ -121,34 +122,34 @@
   }
 }
 
-static void oggbyte_set8(oggbyte_buffer *b,ogg_int64_t val,int pos){
+void oggbyte_set8(oggbyte_buffer *b,ogg_int64_t val,int pos){
   int i;
   _positionB(b,pos);
   for(i=0;i<8;i++){
-    _positionFE(b,pos+i);
+    _positionFE(b,pos);
     b->headptr[pos-b->headpos]=val;
     val>>=8;
     ++pos;
   }
 }
  
-static unsigned char oggbyte_read1(oggbyte_buffer *b,int pos){
+unsigned char oggbyte_read1(oggbyte_buffer *b,int pos){
   _positionB(b,pos);
   _positionF(b,pos);
   return b->headptr[pos-b->headpos];
 }
 
-static int oggbyte_read2(oggbyte_buffer *b,int pos){
+int oggbyte_read2(oggbyte_buffer *b,int pos){
   int ret;
   _positionB(b,pos);
   _positionF(b,pos);
   ret=b->headptr[pos-b->headpos];
   _positionF(b,++pos);
-  ret|=b->headptr[pos-b->headpos]<<8;
+  return ret|b->headptr[pos-b->headpos]<<8;  
 }
 
-static ogg_int32_t oggbyte_read4(oggbyte_buffer *b,int pos){
-  ogg_int32_t ret;
+ogg_uint32_t oggbyte_read4(oggbyte_buffer *b,int pos){
+  ogg_uint32_t ret;
   _positionB(b,pos);
   _positionF(b,pos);
   ret=b->headptr[pos-b->headpos];
@@ -161,7 +162,7 @@
   return ret;
 }
 
-static ogg_int32_t oggbyte_read8(oggbyte_buffer *b,int pos){
+ogg_int64_t oggbyte_read8(oggbyte_buffer *b,int pos){
   ogg_int64_t ret;
   unsigned char t[7];
   int i;
@@ -179,4 +180,372 @@
 
   return ret;
 }
+
+
+#ifdef _V_SELFTEST
+
+#include <stdio.h>
+#define TESTBYTES 4096
+
+unsigned char ref[TESTBYTES];
+unsigned char work[TESTBYTES];
+ogg_buffer_state *bs;
+
+void _read_linear_test1(ogg_reference *or){
+  oggbyte_buffer obb;
+  int j;
+
+  oggbyte_init(&obb,or,0,0);
+  
+  for(j=0;j<TESTBYTES;j++){
+    unsigned char ret=oggbyte_read1(&obb,j);
+    if(ref[j]!=ret){
+      fprintf(stderr,"\nERROR:  %02x != %02x, position %d\n\n",
+	      ref[j],ret,j);
+      exit(1);
+    }
+  }
+}
+
+void _read_linear_test2(ogg_reference *or){
+  oggbyte_buffer obb;
+  int j;
+
+  oggbyte_init(&obb,or,0,0);
+  for(j=0;j+1<TESTBYTES;j++){
+    int ret=oggbyte_read2(&obb,j);
+    if(ref[j]!=(ret&0xff) || ref[j+1]!=((ret>>8)&0xff)){
+      fprintf(stderr,"\nERROR:  %02x%02x != %04x, position %d\n\n",
+	      ref[j+1],ref[j],ret,j);
+      exit(1);
+    }
+  }
+}
+
+void _read_linear_test4(ogg_reference *or){
+  oggbyte_buffer obb;
+  int j;
+
+  oggbyte_init(&obb,or,0,0);
+
+  for(j=0;j+3<TESTBYTES;j++){
+    ogg_uint32_t ret=oggbyte_read4(&obb,j);
+    if(ref[j]!=(ret&0xff) ||
+       ref[j+1]!=((ret>>8)&0xff) ||
+       ref[j+2]!=((ret>>16)&0xff) ||
+       ref[j+3]!=((ret>>24)&0xff)    ){
+      fprintf(stderr,"\nERROR:  %02x%02x%02x%02x != %08lx, position %d\n\n",
+	      ref[j+3],ref[j+2],ref[j+1],ref[j],
+	      (unsigned long)ret,j);
+      exit(1);
+    }
+  }
+}
+
+void _read_linear_test8(ogg_reference *or){
+  oggbyte_buffer obb;
+  int j;
+
+  oggbyte_init(&obb,or,0,0);
+
+  for(j=0;j+7<TESTBYTES;j++){
+    ogg_int64_t ret=ref[j+7];
+    ret=(ret<<8)|ref[j+6];
+    ret=(ret<<8)|ref[j+5];
+    ret=(ret<<8)|ref[j+4];
+    ret=(ret<<8)|ref[j+3];
+    ret=(ret<<8)|ref[j+2];
+    ret=(ret<<8)|ref[j+1];
+    ret=(ret<<8)|ref[j];
+    
+    if(ret!=oggbyte_read8(&obb,j)){
+      int i;
+      ret=oggbyte_read8(&obb,j);
+      fprintf(stderr,"\nERROR:  %02x%02x%02x%02x%02x%02x%02x%02x != ",
+	      ref[j+7],ref[j+6],ref[j+5],ref[j+4],
+	      ref[j+3],ref[j+2],ref[j+1],ref[j]);
+      for(i=0;i<8;i++){
+	ref[j+i]=ret&0xff;
+	ret>>=8;
+      }
+      fprintf(stderr,"%02x%02x%02x%02x%02x%02x%02x%02x, position %d\n\n",
+	      ref[j+7],ref[j+6],ref[j+5],ref[j+4],
+	      ref[j+3],ref[j+2],ref[j+1],ref[j],
+	      j);
+      exit(1);
+    }
+  }
+}
+
+void _read_seek_test(ogg_reference *or){
+  oggbyte_buffer obb;
+  int i,j,begin=rand()%(TESTBYTES-7);
+  int length=TESTBYTES-begin;
+  unsigned char *lref=ref+begin;
+
+  oggbyte_init(&obb,or,begin,0);
+  
+  for(i=0;i<TESTBYTES;i++){
+    unsigned char ret;
+    j=rand()%length;
+    ret=oggbyte_read1(&obb,j);
+    if(lref[j]!=ret){
+      fprintf(stderr,"\nERROR:  %02x != %02x, position %d\n\n",
+	      lref[j],ret,j);
+      exit(1);
+    }
+  }
+
+  for(i=0;i<TESTBYTES;i++){
+    int ret;
+    j=rand()%(length-1);
+    ret=oggbyte_read2(&obb,j);
+    if(lref[j]!=(ret&0xff) || lref[j+1]!=((ret>>8)&0xff)){
+      fprintf(stderr,"\nERROR:  %02x%02x != %04x, position %d\n\n",
+	      lref[j+1],lref[j],ret,j);
+      exit(1);
+    }
+  }
+
+  for(i=0;i<TESTBYTES;i++){
+    ogg_uint32_t ret;
+    j=rand()%(length-3);
+    ret=oggbyte_read4(&obb,j);
+    if(lref[j]!=(ret&0xff) ||
+       lref[j+1]!=((ret>>8)&0xff) ||
+       lref[j+2]!=((ret>>16)&0xff) ||
+       lref[j+3]!=((ret>>24)&0xff)    ){
+      fprintf(stderr,"\nERROR:  %02x%02x%02x%02x != %08lx, position %d\n\n",
+	      lref[j+3],lref[j+2],lref[j+1],lref[j],
+	      (unsigned long)ret,j);
+      exit(1);
+    }
+  }
+
+  for(i=0;i<TESTBYTES;i++){
+    ogg_int64_t ret;
+    j=rand()%(length-7);
+    ret=lref[j+7];
+    ret=(ret<<8)|lref[j+6];
+    ret=(ret<<8)|lref[j+5];
+    ret=(ret<<8)|lref[j+4];
+    ret=(ret<<8)|lref[j+3];
+    ret=(ret<<8)|lref[j+2];
+    ret=(ret<<8)|lref[j+1];
+    ret=(ret<<8)|lref[j];
+    
+    if(ret!=oggbyte_read8(&obb,j)){
+      int i;
+      ret=oggbyte_read8(&obb,j);
+      fprintf(stderr,"\nERROR:  %02x%02x%02x%02x%02x%02x%02x%02x != ",
+	      lref[j+7],lref[j+6],lref[j+5],lref[j+4],
+	      lref[j+3],lref[j+2],lref[j+1],lref[j]);
+      for(i=0;i<8;i++){
+	lref[j+i]=ret&0xff;
+	ret>>=8;
+      }
+      fprintf(stderr,"%02x%02x%02x%02x%02x%02x%02x%02x, position %d\n\n",
+	      lref[j+7],lref[j+6],lref[j+5],lref[j+4],
+	      lref[j+3],lref[j+2],lref[j+1],lref[j],
+	      j);
+      exit(1);
+    }
+  }
+}
+
+void _head_prep(ogg_reference *head){
+  int count=0;
+  while(head){
+    memset(head->buffer->data,0,head->buffer->size);
+    count+=head->length;
+
+    if(count>TESTBYTES/2+rand()%(TESTBYTES/4)){
+      ogg_buffer_release(head->next);
+      head->next=0;
+      break;
+    }else{
+      head=head->next;
+    }
+  }
+}
+
+void _write_linear_test(ogg_reference *tail){
+  oggbyte_buffer ob;
+  int i;
+
+  _head_prep(tail);
+  oggbyte_init(&ob,tail,0,0);
+  for(i=0;i<TESTBYTES;i++)
+    oggbyte_set1(&ob,ref[i],i);
+  _read_linear_test1(tail);
+  if(ogg_buffer_length(tail)!=TESTBYTES){
+    fprintf(stderr,"\nERROR: oggbyte_set1 extended incorrectly.\n\n");
+    exit(1);
+  }
+
+  _head_prep(tail);
+
+  oggbyte_init(&ob,tail,0,0);
+  for(i=0;i<TESTBYTES;i+=2){
+    unsigned int val=ref[i]|(ref[i+1]<<8);
+    oggbyte_set2(&ob,val,i);
+  }
+  _read_linear_test1(tail);
+  if(ogg_buffer_length(tail)>TESTBYTES){
+    fprintf(stderr,"\nERROR: oggbyte_set2 extended incorrectly.\n\n");
+    exit(1);
+  }
+
+  _head_prep(tail);
+
+  oggbyte_init(&ob,tail,0,0);
+  for(i=0;i<TESTBYTES;i+=4){
+    unsigned long val=ref[i+2]|(ref[i+3]<<8);
+    val=(val<<16)|ref[i]|(ref[i+1]<<8);
+    oggbyte_set4(&ob,val,i);
+  }
+  _read_linear_test1(tail);
+  if(ogg_buffer_length(tail)>TESTBYTES){
+    fprintf(stderr,"\nERROR: oggbyte_set4 extended incorrectly.\n\n");
+    exit(1);
+  }
+
+  _head_prep(tail);
+
+  oggbyte_init(&ob,tail,0,0);
+  for(i=0;i<TESTBYTES;i+=8){
+    ogg_int64_t val=ref[i+6]|(ref[i+7]<<8);
+    val=(val<<16)|ref[i+4]|(ref[i+5]<<8);
+    val=(val<<16)|ref[i+2]|(ref[i+3]<<8);
+    val=(val<<16)|ref[i]|(ref[i+1]<<8);
+    oggbyte_set8(&ob,val,i);
+  }
+  _read_linear_test1(tail);
+  if(ogg_buffer_length(tail)>TESTBYTES){
+    fprintf(stderr,"\nERROR: oggbyte_set8 extended incorrectly.\n\n");
+    exit(1);
+  }
+
+}
+
+void _write_zero_test(void){
+  oggbyte_buffer ob;
+  int i;
+
+  oggbyte_init(&ob,0,0,bs);
+  for(i=0;i<TESTBYTES;i++)
+    oggbyte_set1(&ob,ref[i],i);
+  _read_linear_test1(ob.baseref);
+  if(ogg_buffer_length(ob.baseref)!=TESTBYTES){
+    fprintf(stderr,"\nERROR: oggbyte_set1 extended incorrectly.\n\n");
+    exit(1);
+  }
+}
+
+int main(void){
+  int i,j;
+  bs=ogg_buffer_create();
+
+  /* test all codepaths through randomly generated data set */
+  fprintf(stderr,"\nRandomized testing of byte aligned access abstraction: \n");
+
+  for(i=0;i<1000;i++){
+
+    /* fill reference array */
+    for(j=0;j<TESTBYTES;j++)
+      ref[j]=rand()%TESTBYTES;
+  
+    /* test basic reading using single synthetic reference 1,2,4,8 */
+    fprintf(stderr,"\r\t loops left (%d),  basic read test... ",1000-i);
+    {
+      ogg_buffer ob;
+      ogg_reference or;
+
+      ob.data=ref;
+      ob.size=TESTBYTES;
+      or.buffer=&ob;
+      or.begin=0;
+      or.length=TESTBYTES;
+
+      _read_linear_test1(&or);
+      _read_linear_test2(&or);
+      _read_linear_test4(&or);
+      _read_linear_test8(&or);
+    }
+
+    /* test basic reading using multiple synthetic refs 1,2,4,8 */
+    fprintf(stderr,"\r\t loops left (%d),  fragmented read test... ",1000-i);
+    {
+      ogg_reference *tail=0;
+      ogg_reference *head=0;
+      long count=0;
+      
+      
+      while(count<TESTBYTES){
+	int begin=rand()%32;
+	int length=rand()%32;
+	int pad=rand()%32;
+
+	if(length>TESTBYTES-count)length=TESTBYTES-count;
+
+	if(tail)
+	  head=ogg_buffer_extend(head,begin+length+pad);
+	else
+	  tail=head=ogg_buffer_alloc(bs,begin+length+pad);
+
+	memcpy(head->buffer->data+begin,ref+count,length);
+	head->begin=begin;
+	head->length=length;
+
+	count+=length;
+      }
+
+      _read_linear_test1(tail);
+      _read_linear_test2(tail);
+      _read_linear_test4(tail);
+      _read_linear_test8(tail);
+      /* test reading with random seek using multiple synthetic refs */
+      fprintf(stderr,"\r\t loops left (%d),  nonsequential read test... ",1000-i);
+      _read_seek_test(tail);
+
+      /* test writing, starting at offset zero in already built reference */
+      fprintf(stderr,"\r\t loops left (%d),  linear write test...       ",1000-i);      
+      _write_linear_test(tail);
+
+      ogg_buffer_release(tail);
+    }    
+    
+    /* test writing, init at offset zero in blank reference */
+    fprintf(stderr,"\r\t loops left (%d),  zero-start write test...   ",1000-i);      
+    _write_zero_test();
+    
+    /* test writing, init at random offset in blank ref */
+    fprintf(stderr,"\r\t loops left (%d),  random-start write test...   ",1000-i);      
+    //_write_offset_test();
+
+    /* random writing, init at random offset in blank ref */
+    fprintf(stderr,"\r\t loops left (%d),  random-offset write test...   ",1000-i);      
+    
+
+
+  }
+  fprintf(stderr,"\r\t all tests ok.                                              \n\n");
+  ogg_buffer_destroy(bs);
+  return 0;
+}
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
 

<p><p>1.1.2.8   +72 -36    ogg/src/Attic/ogginternal.h

Index: ogginternal.h
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/ogginternal.h,v
retrieving revision 1.1.2.7
retrieving revision 1.1.2.8
diff -u -r1.1.2.7 -r1.1.2.8
--- ogginternal.h	16 Mar 2003 23:31:48 -0000	1.1.2.7
+++ ogginternal.h	22 Mar 2003 05:44:51 -0000	1.1.2.8
@@ -11,7 +11,7 @@
  ********************************************************************
 
  function: internal/hidden data representation structures
- last mod: $Id: ogginternal.h,v 1.1.2.7 2003/03/16 23:31:48 xiphmont Exp $
+ last mod: $Id: ogginternal.h,v 1.1.2.8 2003/03/22 05:44:51 xiphmont Exp $
 
  ********************************************************************/
 
@@ -23,18 +23,18 @@
 
 struct ogg_buffer_state{
   ogg_buffer    *unused_buffers;
-  int            outstanding_buffers;
-
   ogg_reference *unused_references;
-  int            outstanding_references;
+  int            outstanding;
 
   ogg_mutex_t mutex;
+  int         shutdown;
 };
 
 struct ogg_buffer {
   unsigned char      *data;
   long                size;
   int                 refcount;
+  
   union {
     ogg_buffer_state *owner;
     ogg_buffer       *next;
@@ -58,19 +58,25 @@
   ogg_reference *tail;
 
   /* render the byte/bit counter API constant time */
-  long count;              /* doesn't count the tail */
-  ogg_buffer_state *owner; /* cache preferred pool for write lazy init */
-
+  long              count; /* doesn't count the tail */
+  ogg_buffer_state *owner; /* useful on encode side */
 };
 
-typedef struct{
-  ogg_reference *segment;
-  int            cursor;
-} ogg_buffer_cursor;
+typedef struct oggbyte_buffer {
+  ogg_reference *baseref;
+  long           basepos;
+
+  ogg_reference *headref;
+  unsigned char *headptr;
+  long           headpos;
+  long           headend;
+
+  ogg_buffer_state *owner; /* if it's to be extensible; encode side */
+} oggbyte_buffer;
 
 struct ogg_sync_state {
-  /* encode/decode mem management */
-  ogg_buffer_state  bufferpool;
+  /* decode memory management pool */
+  ogg_buffer_state *bufferpool;
 
   /* stream buffers */
   ogg_reference    *fifo_head;
@@ -89,33 +95,42 @@
 };
 
 struct ogg_stream_state {
+  /* encode memory management pool */
+  ogg_buffer_state *bufferpool;
 
-  long              body_len;
-
-  unsigned char    *header;       /* working space for header encode */
-  int               header_fill;
-
-  int     e_o_s;        /* set when we have buffered the last packet in the
-                           logical bitstream */
-  int     b_o_s;        /* set after we've written the initial page
-                           of a logical bitstream */
-  int     headers;      /* how many setup headers? */
-  long    serialno;
-  long    pageno;
-  ogg_int64_t packetno; /* sequence number for decode; the framing
-                           knows where there's a hole in the data,
-                           but we need coupling so that the codec
-                           (which is in a seperate abstraction
-                           layer) also knows about the gap */
-
-  /* for sync memory management use */
-  struct ogg_sync_state   *sync;
-  struct ogg_stream_state *next;
+  ogg_reference *header_head;
+  ogg_reference *header_tail;
+  ogg_reference *body_head;
+  ogg_reference *body_tail;
+  long           body_fill;
+
+  /* encode-side header build */
+  oggpack_buffer    lacing;
+  int               lacing_fill;
+
+  ogg_reference *returned;
+  ogg_reference *returned_head;
+
+  long           header_len;
+  long           body_len;
+
+  int            e_o_s;    /* set when we have buffered the last
+                              packet in the logical bitstream */
+  int            b_o_s;    /* set after we've written the initial page
+			      of a logical bitstream */
+  int            headers;  /* how many setup headers? */
+  long           serialno;
+  long           pageno;
+  ogg_int64_t    packetno; /* sequence number for decode; the framing
+			      knows where there's a hole in the data,
+			      but we need coupling so that the codec
+			      (which is in a seperate abstraction
+			      layer) also knows about the gap */
 
 };
 
-extern void           ogg_buffer_init(ogg_buffer_state *bs);
-extern void           ogg_buffer_clear(ogg_buffer_state *bs);
+extern ogg_buffer_state *ogg_buffer_create(void);
+extern void           ogg_buffer_destroy(ogg_buffer_state *bs);
 extern ogg_reference *ogg_buffer_alloc(ogg_buffer_state *bs,long bytes);
 extern void           ogg_buffer_realloc(ogg_reference *or,long bytes);
 extern ogg_reference *ogg_buffer_dup(ogg_reference *or,long begin,long length);
@@ -127,6 +142,27 @@
 extern void           ogg_buffer_posttruncate(ogg_reference *or,long pos);
 extern ogg_reference *ogg_buffer_cat(ogg_reference *tail, ogg_reference *head);
 extern ogg_reference *ogg_buffer_walk(ogg_reference *or);
+extern long           ogg_buffer_length(ogg_reference *or);
+
+extern  int           oggbyte_init(oggbyte_buffer *b,ogg_reference *or,
+				   long base,ogg_buffer_state *bs);
+extern void           oggbyte_set1(oggbyte_buffer *b,unsigned char val,
+				   int pos);
+extern void           oggbyte_set2(oggbyte_buffer *b,int val,int pos);
+extern void           oggbyte_set4(oggbyte_buffer *b,ogg_uint32_t val,int pos);
+extern void           oggbyte_set8(oggbyte_buffer *b,ogg_int64_t val,int pos);
+extern unsigned char  oggbyte_read1(oggbyte_buffer *b,int pos);
+extern int            oggbyte_read2(oggbyte_buffer *b,int pos);
+extern ogg_uint32_t   oggbyte_read4(oggbyte_buffer *b,int pos);
+extern ogg_int64_t    oggbyte_read8(oggbyte_buffer *b,int pos);
+
+#ifdef _V_SELFTEST
+#define OGGPACK_CHUNKSIZE 3
+#else
+#define OGGPACK_CHUNKSIZE 128
+#endif
 
 #endif
+
+
 

<p><p>1.1.2.3   +149 -59   ogg/src/Attic/stream.c

Index: stream.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/stream.c,v
retrieving revision 1.1.2.2
retrieving revision 1.1.2.3
diff -u -r1.1.2.2 -r1.1.2.3
--- stream.c	15 Mar 2003 01:26:09 -0000	1.1.2.2
+++ stream.c	22 Mar 2003 05:44:51 -0000	1.1.2.3
@@ -10,9 +10,9 @@
  *                                                                  *
  ********************************************************************
 
- function: code raw packets into framed Ogg stream and
-           decode Ogg streams back into raw packets
- last mod: $Id: stream.c,v 1.1.2.2 2003/03/15 01:26:09 xiphmont Exp $
+ function: code raw packets into framed Ogg logical stream and
+           decode Ogg logical streams back into raw packets
+ last mod: $Id: stream.c,v 1.1.2.3 2003/03/22 05:44:51 xiphmont Exp $
 
  ********************************************************************/
 
@@ -23,81 +23,171 @@
 
 /* A complete description of Ogg framing exists in docs/framing.html */
 
-int ogg_stream_init(ogg_stream_state *os,int serialno){
-  if(os){
-    memset(os,0,sizeof(*os));
-    os->body_storage=16*1024;
-    os->body_data=_ogg_malloc(os->body_storage*sizeof(*os->body_data));
-
-    os->lacing_storage=1024;
-    os->lacing_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->lacing_vals));
-    os->granule_vals=_ogg_malloc(os->lacing_storage*sizeof(*os->granule_vals));
-
-    os->serialno=serialno;
+ogg_stream_state *ogg_stream_create(int serialno){
+  ogg_stream_state *os=_ogg_calloc(1,sizeof(*os));
+  os->watermark=4096;
+  os->serialno=serialno;
+  os->bufferpool=ogg_buffer_create();
+  return os;
+} 
 
-    return(0);
+int ogg_stream_setfill(ogg_stream_state *os,int watermark){
+  if(os){
+    if(watermark>65535)watermark=65535;
+    os->watermark=watermark;
+    return watermark;
   }
-  return(-1);
+  return -1;
 } 
 
+static void _returned_release(ogg_stream_state *os){
+  ogg_buffer_release(os->returned);
+  os->returned=0;
+  ogg_buffer_release(os->returned_body);
+  os->returned_body=0;
+}
+
 /* _clear does not free os, only the non-flat storage within */
-int ogg_stream_clear(ogg_stream_state *os){
+void ogg_stream_destroy(ogg_stream_state *os){
   if(os){
-    if(os->body_data)_ogg_free(os->body_data);
-    if(os->lacing_vals)_ogg_free(os->lacing_vals);
-    if(os->granule_vals)_ogg_free(os->granule_vals);
 
+    _returned_release(os);
+    ogg_buffer_release(os->header_tail);
+    ogg_buffer_release(os->body_tail);
+    ogg_buffer_destroy(os->bufferpool);
     memset(os,0,sizeof(*os));    
+
   }
   return(0);
 } 
 
-/* submit data to the internal buffer of the framing engine */
-int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
-  int lacing_vals=op->bytes/255+1,i;
+/* finish building a header then flush the current packet header and
+   body to the output buffer */
+static void _packet_flush(ogg_stream_state *os,int nextcomplete){
+  oggpack_buffer obp;
+  unsigned char ctemp;
+
+  if(os->lacing_fill){
+    /* construct the header in temp storage */
+    oggpack_writeinit(&opb,&os->bufferpool);
+    
+    oggpack_write(&opb,'O',8);
+    oggpack_write(&opb,'g',8);
+    oggpack_write(&opb,'g',8);
+    oggpack_write(&opb,'S',8);
+    
+    oggpack_write(&opb,0x00,8);   /* 4: stream structure version */
+     
+    ctemp=0x00;
+    if(os->continued)ctemp|=0x01; /* continued packet flag? */
+    if(os->b_o_s==0)ctemp|=0x02;  /* first page flag? */
+    if(os->e_o_s)ctemp|=0x04;     /* last page flag? */
+    oggpack_write(&opb,ctemp,8);  /* 5 */
 
-  if(os->body_returned){
-    /* advance packet data according to the body_returned pointer. We
-       had to keep it around to return a pointer into the buffer last
-       call */
-    
-    os->body_fill-=os->body_returned;
-    if(os->body_fill)
-      memmove(os->body_data,os->body_data+os->body_returned,
-	      os->body_fill);
-    os->body_returned=0;
-  }
- 
-  /* make sure we have the buffer storage */
-  _os_body_expand(os,op->bytes);
-  _os_lacing_expand(os,lacing_vals);
-
-  /* Copy in the submitted packet.  Yes, the copy is a waste; this is
-     the liability of overly clean abstraction for the time being.  It
-     will actually be fairly easy to eliminate the extra copy in the
-     future */
-
-  memcpy(os->body_data+os->body_fill,op->packet,op->bytes);
-  os->body_fill+=op->bytes;
-
-  /* Store lacing vals for this packet */
-  for(i=0;i<lacing_vals-1;i++){
-    os->lacing_vals[os->lacing_fill+i]=255;
-    os->granule_vals[os->lacing_fill+i]=os->granulepos;
-  }
-  os->lacing_vals[os->lacing_fill+i]=(op->bytes)%255;
-  os->granulepos=os->granule_vals[os->lacing_fill+i]=op->granulepos;
+    os->b_o_s=1;
+    
+    /* 64 bits of PCM position */
+    {
+      ogg_int64_t granule_pos=os->granule_pos;
+      for(i=0;i<8;i++){
+	oggpack_write(&opb,(granule_pos&0xff),8);
+	granule_pos>>=8;
+      }
+    }
+    
+    /* 32 bits of stream serial number */
+    oggpack_write(&opb,os->serialno,32);
+    
+    /* 32 bits of page counter (we have both counter and page header
+       because this val can roll over) */
+    if(os->pageno==-1)os->pageno=0; /* because someone called
+				       stream_reset; this would be a
+				       strange thing to do in an
+				       encode stream, but it has
+				       plausible uses */
+    oggpack_write(&opb,os->pageno++,32);
+    
+    /* zero CRC for computation; filled in later */
+    oggpack_write(&opb,0,32);
+    
+    /* segment table size */
+    oggpack_write(&opb,os->lacing_fill,8);
 
-  /* flag the first segment as the beginning of the packet */
-  os->lacing_vals[os->lacing_fill]|= 0x100;
+    /* concatenate header pieces, toss 'em on the fifo */
+    {
+      ogg_reference *header=oggpack_writebuffer(&opb);
+      ogg_buffer_cat(header,oggpack_writebuffer(&os->lacing));
+      
 
-  os->lacing_fill+=lacing_vals;
 
-  /* for the sake of completeness */
-  os->packetno++;
+    /* set pointers in the ogg_page struct */
+    og->header=os->header;
+    og->header_len=os->header_fill=vals+27;
+    og->body=os->body_data+os->body_returned;
+    og->body_len=bytes;
+    
+    /* advance the lacing data and set the body_returned pointer */
+    
+    os->lacing_fill-=vals;
+    memmove(os->lacing_vals,os->lacing_vals+vals,os->lacing_fill*sizeof(*os->lacing_vals));
+    memmove(os->granule_vals,os->granule_vals+vals,os->lacing_fill*sizeof(*os->granule_vals));
+    os->body_returned+=bytes;
+    
+    /* calculate the checksum */
+    
+    ogg_page_checksum_set(og);
+    
+  }
 
+/* submit data to the internal buffer of the framing engine */
+int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){
+  /* get sizing */
+  long bytes=ogg_buffer_length(op->packet);
+  long lacing_vals=bytes/255+1;
+  int  remainder=bytes%255;
+  int  i;
+
+  /* clear out previously returned pages if any */
+  _returned_release(os);
+
+  if(op->e_o_s)return -1;
+  
+  if(!lacing_fill)
+    ogg_buffer_writeinit(os->lacing,os->bufferpool);
+
+  /* concat packet data */
+  if(os->body_head)
+    os->body_head=ogg_buffer_cat(os->body_head,op->packet);
+  else
+    os->body_tail=os->body_head=op->packet;
+
+  /* add lacing vals, but finish/flush packet first if we hit a
+     watermark */
+  for(i=0;i<lacing_vals-1;i++){ /* handle the 255s first */
+    os->body_fill+=255;
+    os->lacing_fill++;
+    ogg_buffer_write(&os->lacing,255,8);
+    
+    if(os->body_fill>=os->watermark)_packet_flush(os,1);
+    if(os->lacing_fill==255)_packet_flush(os,1);
+  }
+
+  /* we know we'll finish this packet on this page; propogate
+     granulepos et al and then finish packet lacing */
+
+  os->body_fill+=remainder;
+  os->lacing_fill++;
+  os->granulepos=op->granulepos;
+  os->packetno++;  /* for the sake of completeness */
   if(op->e_o_s)os->e_o_s=1;
 
+  ogg_buffer_write(&os->lacing,remainder,8);
+
+  if(os->e_o_s || 
+     os->body_fill>=os->watermark ||
+     !os->b_o_s ||
+     os->lacing_fill==255)_packet_flush(os,0);
+  
   return(0);
 }
 

<p><p>1.1.2.4   +81 -177   ogg/src/Attic/sync.c

Index: sync.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/sync.c,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -r1.1.2.3 -r1.1.2.4
--- sync.c	16 Mar 2003 23:31:48 -0000	1.1.2.3
+++ sync.c	22 Mar 2003 05:44:51 -0000	1.1.2.4
@@ -12,7 +12,7 @@
 
  function: decode stream sync and memory management foundation code;
            takes in raw data, spits out packets
- last mod: $Id: sync.c,v 1.1.2.3 2003/03/16 23:31:48 xiphmont Exp $
+ last mod: $Id: sync.c,v 1.1.2.4 2003/03/22 05:44:51 xiphmont Exp $
 
  note: The CRC code is directly derived from public domain code by
  Ross Williams (ross at guest.adelaide.edu.au).  See docs/framing.html
@@ -31,120 +31,48 @@
    handled by physical stream and centralized in the ogg_sync_state
    structure. */
 
-static void _obc_cond_span(ogg_buffer_cursor *obc){
-  while(obc->segment && obc->cursor>=obc->segment->length){
-    obc->cursor-=obc->segment->length;
-    obc->segment=obc->segment->next;
-  }
-}
-
-
-static void _obc_seek(ogg_buffer_cursor *obc,
-		     ogg_reference *fb,
-		     int position){
-  obc->segment=fb;
-  obc->cursor=position;
-}
-
-static void _obc_span(ogg_buffer_cursor *obc){
-  if(obc->segment){
-    obc->segment=obc->segment->next;
-    obc->cursor=0;
-  }
-}
-
-static int _obc_get(ogg_buffer_cursor *obc){
-  _obc_cond_span(obc);
-  if(!obc->segment)return -1;
-  return(obc->segment->buffer->data[obc->segment->begin+obc->cursor++]);
-}
-
-static void _obc_set(ogg_buffer_cursor *obc,unsigned char val){
-  _obc_cond_span(obc);
-  if(!obc->segment)return;
-  obc->segment->buffer->data[obc->segment->begin+obc->cursor++]=val;
-}
-
-static ogg_int64_t _obc_get_int64(ogg_buffer_cursor *obc){
-  ogg_int64_t ret;
-  unsigned char y[7];
-  y[0]=_obc_get(obc);
-  y[1]=_obc_get(obc);
-  y[2]=_obc_get(obc);
-  y[3]=_obc_get(obc);
-  y[4]=_obc_get(obc);
-  y[5]=_obc_get(obc);
-  y[6]=_obc_get(obc);
-  ret =_obc_get(obc);
-  
-  ret =(ret<<8)|y[6];
-  ret =(ret<<8)|y[5];
-  ret =(ret<<8)|y[4];
-  ret =(ret<<8)|y[3];
-  ret =(ret<<8)|y[2];
-  ret =(ret<<8)|y[1];
-  ret =(ret<<8)|y[0];
-  
-  return(ret);
-}
-
-static ogg_uint32_t _obc_get_uint32(ogg_buffer_cursor *obc){
-  ogg_uint32_t ret;
-  unsigned char y[3];
-  y[0]=_obc_get(obc);
-  y[1]=_obc_get(obc);
-  y[2]=_obc_get(obc);
-  ret =_obc_get(obc);
-  ret =(ret<<8)|y[2];
-  ret =(ret<<8)|y[1];
-  ret =(ret<<8)|y[0];
-  
-  return(ret);
-}
-
 int ogg_page_version(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,4);
-  return(_obc_get(&obc));
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read1(&ob,4);
 }
 
 int ogg_page_continued(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,5);
-  return(_obc_get(&obc)&0x01);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read1(&ob,5)&0x01;
 }
 
 int ogg_page_bos(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,5);
-  return(_obc_get(&obc)&0x02);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read1(&ob,5)&0x02;
 }
 
 int ogg_page_eos(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,5);
-  return(_obc_get(&obc)&0x04);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read1(&ob,5)&0x04;
 }
 
 ogg_int64_t ogg_page_granulepos(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,6);
-  return _obc_get_int64(&obc);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read8(&ob,6);
 }
 
 ogg_uint32_t ogg_page_serialno(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,14);
-  return _obc_get_uint32(&obc);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read4(&ob,14);
 }
  
 ogg_uint32_t ogg_page_pageno(ogg_page *og){
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,18);
-  return _obc_get_uint32(&obc);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+  return oggbyte_read4(&ob,18);
 }
 
-
 /* returns the number of packets that are completed on this page (if
    the leading packet is begun on a previous page, but ends on this
    page, it's counted */
@@ -166,12 +94,12 @@
   int i;
   int n;
   int count=0;
-  ogg_buffer_cursor obc;
-  _obc_seek(&obc,og->header,26);
-  
-  n=_obc_get(&obc);
+  oggbyte_buffer ob;
+  oggbyte_init(&ob,og->header,0,0);
+
+  n=oggbyte_read1(&ob,26);
   for(i=0;i<n;i++)
-    if(_obc_get(&obc)<255)count++;
+    if(oggbyte_read1(&ob,27+i)<255)count++;
   return(count);
 }
 
@@ -262,14 +190,14 @@
 ogg_sync_state *ogg_sync_create(void){
   ogg_sync_state *oy=_ogg_calloc(1,sizeof(*oy));
   memset(oy,0,sizeof(*oy));
-  ogg_buffer_init(&oy->bufferpool);
+  oy->bufferpool=ogg_buffer_create();
   return oy;
 }
 
 int ogg_sync_destroy(ogg_sync_state *oy){
   if(oy){
     ogg_sync_reset(oy);
-    ogg_buffer_clear(&oy->bufferpool);
+    ogg_buffer_destroy(oy->bufferpool);
     memset(oy,0,sizeof(*oy));
     _ogg_free(oy);
   }
@@ -304,7 +232,7 @@
 
   /* base case; fifo uninitialized */
   if(!oy->fifo_head){
-    oy->fifo_head=oy->fifo_tail=ogg_buffer_alloc(&oy->bufferpool,bytes);
+    oy->fifo_head=oy->fifo_tail=ogg_buffer_alloc(oy->bufferpool,bytes);
     return oy->fifo_head->buffer->data;
   }
   
@@ -323,7 +251,7 @@
   
   /* current fragment used/full; get new fragment */
   {
-    ogg_reference *new=ogg_buffer_alloc(&oy->bufferpool,bytes);
+    ogg_reference *new=ogg_buffer_alloc(oy->bufferpool,bytes);
     oy->fifo_head->next=new;
     oy->fifo_head=new;
   }
@@ -350,38 +278,32 @@
 */
 
 long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
-  ogg_buffer_cursor page;
-  long              bytes,ret=0;
+  oggbyte_buffer page;
+  long           bytes,ret=0;
 
   _release_returned(oy);
 
   bytes=oy->fifo_fill;
+  oggbyte_init(&page,oy->fifo_tail,oy->fifo_cursor,0);
 
   if(oy->headerbytes==0){
     if(bytes<27)goto sync_out; /* not enough for even a minimal header */
     
     /* verify capture pattern */
-    _obc_seek(&page,oy->fifo_tail,
-	      oy->fifo_cursor);
-    if(_obc_get(&page)!=(int)'O' ||
-       _obc_get(&page)!=(int)'g' ||
-       _obc_get(&page)!=(int)'g' ||
-       _obc_get(&page)!=(int)'S'    ) goto sync_fail;
-
-    _obc_seek(&page,oy->fifo_tail,
-	     oy->fifo_cursor+26);
-    oy->headerbytes=_obc_get(&page)+27;
+    if(oggbyte_read1(&page,0)!=(int)'O' ||
+       oggbyte_read1(&page,1)!=(int)'g' ||
+       oggbyte_read1(&page,2)!=(int)'g' ||
+       oggbyte_read1(&page,3)!=(int)'S'    ) goto sync_fail;
+
+    oy->headerbytes=oggbyte_read1(&page,26)+27;
   }
   if(bytes<oy->headerbytes)goto sync_out; /* not enough for header +
                                              seg table */
-    
   if(oy->bodybytes==0){
     int i;
     /* count up body length in the segment table */
-    _obc_seek(&page,oy->fifo_tail,
-	     oy->fifo_cursor+27);
     for(i=0;i<oy->headerbytes-27;i++)
-      oy->bodybytes+=_obc_get(&page);
+      oy->bodybytes+=oggbyte_read1(&page,27+i);
   }
   
   if(oy->bodybytes+oy->headerbytes>bytes)goto sync_out;
@@ -399,13 +321,8 @@
                      oy->fifo_cursor+oy->headerbytes,
                      oy->bodybytes);
 
-    /* Grab the checksum bytes */
-    unsigned char chksum[4];    
-    _obc_seek(&page,header,22);
-    chksum[0]=_obc_get(&page);
-    chksum[1]=_obc_get(&page);
-    chksum[2]=_obc_get(&page);
-    chksum[3]=_obc_get(&page);
+    /* Grab the checksum bytes; remember all memory is common access */
+    ogg_uint32_t chksum=oggbyte_read4(&page,22);
 
     {
       ogg_page og;
@@ -415,24 +332,14 @@
       ogg_page_checksum_set(&og);
     }
 
-    /* Compare checksums */
-    _obc_seek(&page,header,22);
-    if(chksum[0]!=_obc_get(&page) ||
-       chksum[1]!=_obc_get(&page) ||
-       chksum[2]!=_obc_get(&page) ||
-       chksum[3]!=_obc_get(&page)){
+    /* Compare checksums; memory continues to be common access */
+    if(chksum!=oggbyte_read4(&page,22)){
 
       /* D'oh.  Mismatch! Corrupt page (or miscapture and not a page
          at all). replace the computed checksum with the one actually
-	 read in; remember all the memory is common */
+	 read in; remember all the memory is common access */
 
-      _obc_seek(&page,header,22);
-      _obc_set(&page,chksum[0]);
-      _obc_set(&page,chksum[1]);
-      _obc_set(&page,chksum[2]);
-      _obc_set(&page,chksum[3]);
-      
-      /* Bad checksum. Lose sync. */
+      oggbyte_set4(&page,chksum,22);
       goto sync_fail;
     }
 
@@ -449,8 +356,18 @@
     oy->bodybytes=0;
     oy->fifo_cursor+=ret; /* advance the cursor past the page */
     
-    goto sync_adv;
+    /* release any unneded fragments */
+    while(oy->fifo_tail && oy->fifo_cursor>=oy->fifo_tail->length){
+      ogg_reference *temp=oy->fifo_tail;
+      
+      oy->fifo_tail=temp->next;
+      if(!oy->fifo_tail)oy->fifo_head=0;
+      oy->fifo_cursor-=temp->length;
+      
+      ogg_buffer_release_one(temp);
+    }
   }
+  return ret;
   
  sync_fail:
 
@@ -459,45 +376,37 @@
     oy->bodybytes=0;
     _release_returned(oy); /* would happen on CRC fail */
 
-    _obc_seek(&page,oy->fifo_tail,oy->fifo_cursor+1);
-    _obc_cond_span(&page);
+    oy->fifo_cursor++;
     ret--;
-
+    
     /* search forward through fragments for possible capture */
-    while(page.segment){
+    while(oy->fifo_tail){
       /* invariant: fifo_cursor points to a position in fifo_tail */
-      unsigned char *now=page.segment->buffer->data+
-	page.segment->begin+
-	page.cursor;
+      unsigned char *now=oy->fifo_tail->buffer->data+
+	oy->fifo_tail->begin+
+	oy->fifo_cursor;
       unsigned char *next=
-	memchr(now, 'O', page.segment->length-page.cursor);
+	memchr(now, 'O', oy->fifo_tail->length-oy->fifo_cursor);
       
       if(next){
         /* possible capture in this segment */
         long bytes=next-now;
-	page.cursor+=bytes;
+	oy->fifo_cursor+=bytes;
         ret-=bytes;
         break;
       }else{
         /* no capture.  advance to next segment */
-	ret-=page.segment->length-page.cursor;
-	_obc_span(&page);
-      }
-    }
-    oy->fifo_cursor-=ret;
-  }
+	ogg_reference *temp=oy->fifo_tail;    
 
- sync_adv:
+	ret-=temp->length-oy->fifo_cursor;
+	oy->fifo_cursor=0;
 
-  /* release any unneded fragments */
-  while(oy->fifo_tail && oy->fifo_cursor>=oy->fifo_tail->length){
-    ogg_reference *temp=oy->fifo_tail;
-    
-    oy->fifo_tail=temp->next;
-    if(!oy->fifo_tail)oy->fifo_head=0;
-    oy->fifo_cursor-=temp->length;
-    
-    ogg_buffer_release_one(temp);
+	oy->fifo_tail=temp->next;
+	if(!oy->fifo_tail)oy->fifo_head=0;
+	ogg_buffer_release_one(temp);
+
+      }
+    }
   }
 
  sync_out:
@@ -560,17 +469,14 @@
 
 void ogg_page_checksum_set(ogg_page *og){
   if(og){
-    ogg_buffer_cursor obc;
+    oggbyte_buffer ob;
     ogg_reference *or;
     ogg_uint32_t crc_reg=0;
     int i,j;
 
     /* safety; needed for API behavior, but not framing code */
-    _obc_seek(&obc,og->header,22);
-    _obc_set(&obc,0);
-    _obc_set(&obc,0);
-    _obc_set(&obc,0);
-    _obc_set(&obc,0);
+    oggbyte_init(&ob,og->header,0,0);
+    oggbyte_set4(&ob,0,22);
 
     or=og->header;
     while(or->next){
@@ -590,11 +496,7 @@
       or=or->next;
     }
     
-    _obc_seek(&obc,og->header,22);
-    _obc_set(&obc,crc_reg);
-    _obc_set(&obc,crc_reg>>8);
-    _obc_set(&obc,crc_reg>>16);
-    _obc_set(&obc,crc_reg>>24);
+    oggbyte_set4(&ob,crc_reg,22);
 
   }
 }
@@ -611,6 +513,8 @@
   _release_returned(oy);
 
   /* buffer new */
+  ogg_buffer_mark(og->header);
+  ogg_buffer_mark(og->body);
   if(oy->fifo_head)
     oy->fifo_head=ogg_buffer_cat(oy->fifo_head,og->header);
   else

<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