[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