[xiph-cvs] cvs commit: ogg/src bitwise.c buffer.c bytewise.c ogginternal.h sync.c
Monty
xiphmont at xiph.org
Sun Mar 23 15:40:59 PST 2003
xiphmont 03/03/23 18:40:58
Modified: src Tag: libogg2-zerocopy bitwise.c buffer.c bytewise.c
ogginternal.h sync.c
Log:
Incremental
Revision Changes Path
No revision
<p>No revision
<p>1.14.2.13 +8 -2 ogg/src/bitwise.c
Index: bitwise.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/bitwise.c,v
retrieving revision 1.14.2.12
retrieving revision 1.14.2.13
diff -u -r1.14.2.12 -r1.14.2.13
--- bitwise.c 22 Mar 2003 05:44:51 -0000 1.14.2.12
+++ bitwise.c 23 Mar 2003 23:40:58 -0000 1.14.2.13
@@ -11,7 +11,7 @@
********************************************************************
function: pack variable sized words into an octet stream
- last mod: $Id: bitwise.c,v 1.14.2.12 2003/03/22 05:44:51 xiphmont Exp $
+ last mod: $Id: bitwise.c,v 1.14.2.13 2003/03/23 23:40:58 xiphmont Exp $
********************************************************************/
@@ -1526,7 +1526,13 @@
for(j=0;j<begin;j++)
bitcount+=len[j];
- or=ogg_buffer_pretruncate(or,bitcount/8);
+ /* also exercise the split code */
+ {
+ ogg_reference *temp=or;
+ or=ogg_buffer_split(or,bitcount/8);
+ ogg_buffer_release(temp);
+ }
+
bitoffset=bitcount%=8;
for(;j<begin+ilen;j++)
bitcount+=len[j];
<p><p>1.1.2.9 +70 -13 ogg/src/Attic/buffer.c
Index: buffer.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/buffer.c,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -u -r1.1.2.8 -r1.1.2.9
--- buffer.c 22 Mar 2003 05:44:51 -0000 1.1.2.8
+++ buffer.c 23 Mar 2003 23:40:58 -0000 1.1.2.9
@@ -11,7 +11,7 @@
********************************************************************
function: centralized fragment buffer management
- last mod: $Id: buffer.c,v 1.1.2.8 2003/03/22 05:44:51 xiphmont Exp $
+ last mod: $Id: buffer.c,v 1.1.2.9 2003/03/23 23:40:58 xiphmont Exp $
********************************************************************/
@@ -186,6 +186,74 @@
return ret;
}
+static void _ogg_buffer_mark_one(ogg_reference *or){
+ ogg_buffer_state *bs=or->buffer->ptr.owner;
+ ogg_mutex_lock(&bs->mutex); /* lock now in case someone is mixing
+ pools */
+
+#ifdef OGGBUFFER_DEBUG
+ if(or->buffer->refcount==0)
+ fprintf(stderr,"WARNING: marking buffer fragment with refcount of zero!\n");
+#endif
+
+ or->buffer->refcount++;
+ ogg_mutex_unlock(&bs->mutex);
+}
+
+/* split a reference into two references; on return the passed in
+ pointer points to the first segment (pos of zero disallowed).
+ pointer to the beginning of the secrond reference is returned. If
+ pos is at or past the end of the passed in segment, returns NULL */
+ogg_reference *ogg_buffer_split(ogg_reference *or,long pos){
+
+ /* walk past any preceeding fragments to one of:
+ a) the exact boundary that seps two fragments
+ b) the fragment that needs split somewhere in the middle */
+
+ while(or && pos>or->length){
+ pos-=or->length;
+ or=or->next;
+ }
+
+ if(pos>=or->length){
+ /* exact split, or off the end */
+ if(or->next){
+
+ /* a split */
+ ogg_reference *ret=or->next;
+ or->next=0;
+ return ret;
+
+ }else{
+
+ /* off or at the end */
+ return NULL;
+
+ }
+ }else{
+
+ /* split within a fragment */
+ long lengthA=pos;
+ long beginB=or->begin+pos;
+ long lengthB=or->length-pos;
+
+ /* make a new reference to head the second piece */
+ ogg_reference *ret=_fetch_ref(or->buffer->ptr.owner);
+
+ ret->buffer=or->buffer;
+ ret->begin=beginB;
+ ret->length=lengthB;
+ ret->next=or->next;
+ _ogg_buffer_mark_one(ret);
+
+ /* update the first piece */
+ or->next=0;
+ or->length=lengthA;
+
+ return ret;
+ }
+}
+
/* add a new fragment link to the end of a chain; return ptr to the new link */
ogg_reference *ogg_buffer_extend(ogg_reference *or,long bytes){
if(or){
@@ -201,18 +269,7 @@
/* increase the refcount of the buffers to which the reference points */
void ogg_buffer_mark(ogg_reference *or){
while(or){
- ogg_buffer_state *bs=or->buffer->ptr.owner;
- ogg_mutex_lock(&bs->mutex); /* lock now in case someone is mixing
- pools */
-
-#ifdef OGGBUFFER_DEBUG
- if(or->buffer->refcount==0)
- fprintf(stderr,"WARNING: marking buffer fragment with refcount of zero!\n");
-#endif
-
- or->buffer->refcount++;
- ogg_mutex_unlock(&bs->mutex);
-
+ _ogg_buffer_mark_one(or);
or=or->next;
}
}
<p><p>1.1.2.4 +89 -102 ogg/src/Attic/bytewise.c
Index: bytewise.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/bytewise.c,v
retrieving revision 1.1.2.3
retrieving revision 1.1.2.4
diff -u -r1.1.2.3 -r1.1.2.4
--- bytewise.c 22 Mar 2003 08:11:26 -0000 1.1.2.3
+++ bytewise.c 23 Mar 2003 23:40:58 -0000 1.1.2.4
@@ -11,7 +11,7 @@
********************************************************************
function: byte-aligned access; array-like abstraction over buffers
- last mod: $Id: bytewise.c,v 1.1.2.3 2003/03/22 08:11:26 xiphmont Exp $
+ last mod: $Id: bytewise.c,v 1.1.2.4 2003/03/23 23:40:58 xiphmont Exp $
********************************************************************/
@@ -23,92 +23,102 @@
or botching a fencepost. */
static void _positionB(oggbyte_buffer *b,int pos){
- if(pos<b->headpos){
+ if(pos<b->pos){
/* start at beginning, scan forward */
- b->headref=b->baseref;
- b->headpos=b->basepos;
- b->headend=b->headpos+b->headref->length;
- b->headptr=b->headref->buffer->data+b->headref->begin;
+ b->ref=b->baseref;
+ b->pos=0;
+ b->end=b->pos+b->ref->length;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
}
}
static void _positionF(oggbyte_buffer *b,int pos){
/* scan forward for position */
- while(pos>=b->headend){
+ while(pos>=b->end){
/* just seek forward */
- b->headpos+=b->headref->length;
- b->headref=b->headref->next;
- b->headend=b->headref->length+b->headpos;
- b->headptr=b->headref->buffer->data+b->headref->begin;
+ b->pos+=b->ref->length;
+ b->ref=b->ref->next;
+ b->end=b->ref->length+b->pos;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
}
}
static void _positionFE(oggbyte_buffer *b,int pos){
/* scan forward for position */
- while(pos>=b->headend){
- if(!b->headref->next){
+ while(pos>=b->end){
+ if(!b->ref->next){
/* perhaps just need to extend length field... */
- if(pos-b->headpos < b->headref->buffer->size-b->headref->begin){
+ if(pos-b->pos < b->ref->buffer->size-b->ref->begin){
/* yes, there's space here */
- b->headref->length=pos-b->headpos+1;
- b->headend=b->headpos+b->headref->length;
+ b->ref->length=pos-b->pos+1;
+ b->end=b->pos+b->ref->length;
}else{
- b->headref->length=b->headref->buffer->size-b->headref->begin;
+ b->ref->length=b->ref->buffer->size-b->ref->begin;
/* extend the array and span */
- b->headpos+=b->headref->length;
- b->headref=ogg_buffer_extend(b->headref,OGGPACK_CHUNKSIZE);
- b->headend=b->headpos;
- b->headptr=b->headref->buffer->data+b->headref->begin;
+ b->pos+=b->ref->length;
+ b->ref=ogg_buffer_extend(b->ref,OGGPACK_CHUNKSIZE);
+ b->end=b->pos;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
}
}else{
/* just seek forward */
- b->headpos+=b->headref->length;
- b->headref=b->headref->next;
- b->headend=b->headref->length+b->headpos;
- b->headptr=b->headref->buffer->data+b->headref->begin;
+ b->pos+=b->ref->length;
+ b->ref=b->ref->next;
+ b->end=b->ref->length+b->pos;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
}
}
}
-int oggbyte_init(oggbyte_buffer *b,ogg_reference *or,long base,
- ogg_buffer_state *bs){
+int oggbyte_init(oggbyte_buffer *b,ogg_reference *or,ogg_buffer_state *bs){
memset(b,0,sizeof(*b));
if(!or){
- if(base || !bs)return -1;
+ if(!bs)return -1;
or=ogg_buffer_alloc(bs,OGGPACK_CHUNKSIZE);
+ }else{
+ b->external=1;
}
- /* cheat and use the _position code */
b->owner=bs;
- b->baseref=or;
- b->basepos=0;
- b->headpos=base+1; /* force _position to scan from beginning */
- _positionB(b,base);
- _positionFE(b,base);
- b->baseref=b->headref;
- b->headpos=b->basepos=b->headpos-base;
- b->headend-=base;
+ b->ref=b->baseref=or;
+ b->pos=0;
+ b->end=b->ref->length;
+ b->ptr=b->ref->buffer->data+b->ref->begin;
return(0);
}
+ogg_reference *oggbyte_return_and_reset(oggbyte_buffer *b){
+ if(b->external){
+ ogg_reference *ret=b->baseref;
+ oggbyte_init(b,0,b->owner);
+ return(ret);
+ }
+ return(NULL);
+}
+
+void oggbyte_clear(oggbyte_buffer *b){
+ if(!b->external)ogg_buffer_release(b->baseref);
+ memset(b,0,sizeof(*b));
+}
+
void oggbyte_set1(oggbyte_buffer *b,unsigned char val,int pos){
_positionB(b,pos);
_positionFE(b,pos);
- b->headptr[pos-b->headpos]=val;
+ b->ptr[pos-b->pos]=val;
}
void oggbyte_set2(oggbyte_buffer *b,int val,int pos){
_positionB(b,pos);
_positionFE(b,pos);
- b->headptr[pos-b->headpos]=val;
+ b->ptr[pos-b->pos]=val;
_positionFE(b,++pos);
- b->headptr[pos-b->headpos]=val>>8;
+ b->ptr[pos-b->pos]=val>>8;
}
void oggbyte_set4(oggbyte_buffer *b,ogg_uint32_t val,int pos){
@@ -116,7 +126,7 @@
_positionB(b,pos);
for(i=0;i<4;i++){
_positionFE(b,pos);
- b->headptr[pos-b->headpos]=val;
+ b->ptr[pos-b->pos]=val;
val>>=8;
++pos;
}
@@ -127,7 +137,7 @@
_positionB(b,pos);
for(i=0;i<8;i++){
_positionFE(b,pos);
- b->headptr[pos-b->headpos]=val;
+ b->ptr[pos-b->pos]=val;
val>>=8;
++pos;
}
@@ -136,29 +146,29 @@
unsigned char oggbyte_read1(oggbyte_buffer *b,int pos){
_positionB(b,pos);
_positionF(b,pos);
- return b->headptr[pos-b->headpos];
+ return b->ptr[pos-b->pos];
}
int oggbyte_read2(oggbyte_buffer *b,int pos){
int ret;
_positionB(b,pos);
_positionF(b,pos);
- ret=b->headptr[pos-b->headpos];
+ ret=b->ptr[pos-b->pos];
_positionF(b,++pos);
- return ret|b->headptr[pos-b->headpos]<<8;
+ return ret|b->ptr[pos-b->pos]<<8;
}
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];
+ ret=b->ptr[pos-b->pos];
_positionF(b,++pos);
- ret|=b->headptr[pos-b->headpos]<<8;
+ ret|=b->ptr[pos-b->pos]<<8;
_positionF(b,++pos);
- ret|=b->headptr[pos-b->headpos]<<16;
+ ret|=b->ptr[pos-b->pos]<<16;
_positionF(b,++pos);
- ret|=b->headptr[pos-b->headpos]<<24;
+ ret|=b->ptr[pos-b->pos]<<24;
return ret;
}
@@ -169,11 +179,11 @@
_positionB(b,pos);
for(i=0;i<7;i++){
_positionF(b,pos);
- t[i]=b->headptr[pos++ -b->headpos];
+ t[i]=b->ptr[pos++ -b->pos];
}
_positionF(b,pos);
- ret=b->headptr[pos-b->headpos];
+ ret=b->ptr[pos-b->pos];
for(i=6;i>=0;--i)
ret= ret<<8 | t[i];
@@ -191,16 +201,16 @@
unsigned char work[TESTBYTES];
ogg_buffer_state *bs;
-void _read_linear_test1(ogg_reference *or,int begin){
+void _read_linear_test1(ogg_reference *or){
oggbyte_buffer obb;
int j;
- oggbyte_init(&obb,or,0,0);
- for(j=0;j<TESTBYTES-begin;j++){
- unsigned char ret=oggbyte_read1(&obb,j+begin);
+ oggbyte_init(&obb,or,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+begin);
+ ref[j],ret,j);
exit(1);
}
}
@@ -210,7 +220,7 @@
oggbyte_buffer obb;
int j;
- oggbyte_init(&obb,or,0,0);
+ oggbyte_init(&obb,or,0);
for(j=0;j<TESTBYTES;j++){
if(work[j]){
unsigned char ret=oggbyte_read1(&obb,j);
@@ -227,7 +237,7 @@
oggbyte_buffer obb;
int j;
- oggbyte_init(&obb,or,0,0);
+ oggbyte_init(&obb,or,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)){
@@ -242,7 +252,7 @@
oggbyte_buffer obb;
int j;
- oggbyte_init(&obb,or,0,0);
+ oggbyte_init(&obb,or,0);
for(j=0;j+3<TESTBYTES;j++){
ogg_uint32_t ret=oggbyte_read4(&obb,j);
@@ -262,7 +272,7 @@
oggbyte_buffer obb;
int j;
- oggbyte_init(&obb,or,0,0);
+ oggbyte_init(&obb,or,0);
for(j=0;j+7<TESTBYTES;j++){
ogg_int64_t ret=ref[j+7];
@@ -295,11 +305,11 @@
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;
+ int i,j;
+ int length=TESTBYTES;
+ unsigned char *lref=ref;
- oggbyte_init(&obb,or,begin,0);
+ oggbyte_init(&obb,or,0);
for(i=0;i<TESTBYTES;i++){
unsigned char ret;
@@ -390,10 +400,10 @@
int i;
_head_prep(tail);
- oggbyte_init(&ob,tail,0,0);
+ oggbyte_init(&ob,tail,0);
for(i=0;i<TESTBYTES;i++)
oggbyte_set1(&ob,ref[i],i);
- _read_linear_test1(tail,0);
+ _read_linear_test1(tail);
if(ogg_buffer_length(tail)!=TESTBYTES){
fprintf(stderr,"\nERROR: oggbyte_set1 extended incorrectly.\n\n");
exit(1);
@@ -401,12 +411,12 @@
_head_prep(tail);
- oggbyte_init(&ob,tail,0,0);
+ oggbyte_init(&ob,tail,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,0);
+ _read_linear_test1(tail);
if(ogg_buffer_length(tail)>TESTBYTES){
fprintf(stderr,"\nERROR: oggbyte_set2 extended incorrectly.\n\n");
exit(1);
@@ -414,13 +424,13 @@
_head_prep(tail);
- oggbyte_init(&ob,tail,0,0);
+ oggbyte_init(&ob,tail,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,0);
+ _read_linear_test1(tail);
if(ogg_buffer_length(tail)>TESTBYTES){
fprintf(stderr,"\nERROR: oggbyte_set4 extended incorrectly.\n\n");
exit(1);
@@ -428,7 +438,7 @@
_head_prep(tail);
- oggbyte_init(&ob,tail,0,0);
+ oggbyte_init(&ob,tail,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);
@@ -436,7 +446,7 @@
val=(val<<16)|ref[i]|(ref[i+1]<<8);
oggbyte_set8(&ob,val,i);
}
- _read_linear_test1(tail,0);
+ _read_linear_test1(tail);
if(ogg_buffer_length(tail)>TESTBYTES){
fprintf(stderr,"\nERROR: oggbyte_set8 extended incorrectly.\n\n");
exit(1);
@@ -448,42 +458,23 @@
oggbyte_buffer ob;
int i;
- oggbyte_init(&ob,0,0,bs);
+ oggbyte_init(&ob,0,bs);
for(i=0;i<TESTBYTES;i++)
oggbyte_set1(&ob,ref[i],i);
- _read_linear_test1(ob.baseref,0);
+ _read_linear_test1(ob.baseref);
if(ogg_buffer_length(ob.baseref)!=TESTBYTES){
fprintf(stderr,"\nERROR: oggbyte_set1 extended incorrectly.\n\n");
exit(1);
}
}
-void _write_offset_test(void){
- oggbyte_buffer ob;
- int i;
- int begin=rand()%(TESTBYTES/2);
- ogg_reference *or=ogg_buffer_alloc(bs,0);
-
- oggbyte_init(&ob,or,begin,bs);
- for(i=0;i<TESTBYTES-begin;i++)
- oggbyte_set1(&ob,ref[i],i);
-
- _read_linear_test1(or,begin);
- if(ogg_buffer_length(or)!=TESTBYTES){
- fprintf(stderr,"\nERROR: oggbyte_set1 extended incorrectly.\n\n");
- exit(1);
- }
-
- ogg_buffer_release(or);
-}
-
void _write_seek_test(void){
oggbyte_buffer ob;
int i;
memset(work,0,TESTBYTES);
- oggbyte_init(&ob,0,0,bs);
+ oggbyte_init(&ob,0,bs);
for(i=0;i<TESTBYTES;i++){
int j=rand()%TESTBYTES;
@@ -519,7 +510,7 @@
or.begin=0;
or.length=TESTBYTES;
- _read_linear_test1(&or,0);
+ _read_linear_test1(&or);
_read_linear_test2(&or);
_read_linear_test4(&or);
_read_linear_test8(&or);
@@ -552,7 +543,7 @@
count+=length;
}
- _read_linear_test1(tail,0);
+ _read_linear_test1(tail);
_read_linear_test2(tail);
_read_linear_test4(tail);
_read_linear_test8(tail);
@@ -567,15 +558,11 @@
ogg_buffer_release(tail);
}
- /* test writing, init at offset zero in blank reference */
+ /* test writing, init 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 small 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 */
+ /* random writing, init blank ref */
fprintf(stderr,"\r\t loops left (%d), random-offset write test... ",1000-i);
_write_seek_test();
<p><p>1.1.2.9 +12 -9 ogg/src/Attic/ogginternal.h
Index: ogginternal.h
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/ogginternal.h,v
retrieving revision 1.1.2.8
retrieving revision 1.1.2.9
diff -u -r1.1.2.8 -r1.1.2.9
--- ogginternal.h 22 Mar 2003 05:44:51 -0000 1.1.2.8
+++ ogginternal.h 23 Mar 2003 23:40:58 -0000 1.1.2.9
@@ -11,7 +11,7 @@
********************************************************************
function: internal/hidden data representation structures
- last mod: $Id: ogginternal.h,v 1.1.2.8 2003/03/22 05:44:51 xiphmont Exp $
+ last mod: $Id: ogginternal.h,v 1.1.2.9 2003/03/23 23:40:58 xiphmont Exp $
********************************************************************/
@@ -64,14 +64,14 @@
typedef struct oggbyte_buffer {
ogg_reference *baseref;
- long basepos;
- ogg_reference *headref;
- unsigned char *headptr;
- long headpos;
- long headend;
+ ogg_reference *ref;
+ unsigned char *ptr;
+ long pos;
+ long end;
ogg_buffer_state *owner; /* if it's to be extensible; encode side */
+ int external; /* did baseref come from outside? */
} oggbyte_buffer;
struct ogg_sync_state {
@@ -82,7 +82,6 @@
ogg_reference *fifo_head;
ogg_reference *fifo_tail;
- long fifo_cursor;
long fifo_fill;
ogg_reference *returned_header;
ogg_reference *returned_body;
@@ -105,7 +104,7 @@
long body_fill;
/* encode-side header build */
- oggpack_buffer lacing;
+ oggbyte_buffer header_build;
int lacing_fill;
ogg_reference *returned;
@@ -143,9 +142,12 @@
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 ogg_reference *ogg_buffer_split(ogg_reference *or,long pos);
extern int oggbyte_init(oggbyte_buffer *b,ogg_reference *or,
- long base,ogg_buffer_state *bs);
+ ogg_buffer_state *bs);
+extern void oggbyte_clear(oggbyte_buffer *b);
+extern ogg_reference *oggbyte_return_and_reset(oggbyte_buffer *b);
extern void oggbyte_set1(oggbyte_buffer *b,unsigned char val,
int pos);
extern void oggbyte_set2(oggbyte_buffer *b,int val,int pos);
@@ -163,6 +165,7 @@
#endif
#endif
+
<p><p>1.1.2.5 +78 -98 ogg/src/Attic/sync.c
Index: sync.c
===================================================================
RCS file: /usr/local/cvsroot/ogg/src/Attic/sync.c,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- sync.c 22 Mar 2003 05:44:51 -0000 1.1.2.4
+++ sync.c 23 Mar 2003 23:40:58 -0000 1.1.2.5
@@ -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.4 2003/03/22 05:44:51 xiphmont Exp $
+ last mod: $Id: sync.c,v 1.1.2.5 2003/03/23 23:40:58 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
@@ -33,43 +33,43 @@
int ogg_page_version(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read1(&ob,4);
}
int ogg_page_continued(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read1(&ob,5)&0x01;
}
int ogg_page_bos(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read1(&ob,5)&0x02;
}
int ogg_page_eos(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read1(&ob,5)&0x04;
}
ogg_int64_t ogg_page_granulepos(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read8(&ob,6);
}
ogg_uint32_t ogg_page_serialno(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read4(&ob,14);
}
ogg_uint32_t ogg_page_pageno(ogg_page *og){
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
return oggbyte_read4(&ob,18);
}
@@ -95,7 +95,7 @@
int n;
int count=0;
oggbyte_buffer ob;
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
n=oggbyte_read1(&ob,26);
for(i=0;i<n;i++)
@@ -267,6 +267,23 @@
return 0;
}
+static ogg_uint32_t _checksum(ogg_reference *or, int bytes){
+ ogg_uint32_t crc_reg=0;
+ int j,post;
+
+ while(or->next){
+ unsigned char *data=or->buffer->data+or->begin;
+ post=(bytes<or->length?bytes:or->length);
+ for(j=0;j<post;++j)
+ crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^data[j]];
+ bytes-=j;
+ or=or->next;
+ }
+
+ return crc_reg;
+}
+
+
/* sync the stream. This is meant to be useful for finding page
boundaries.
@@ -275,7 +292,7 @@
0) page not ready; more data (no bytes skipped)
n) page synced at current location; page length n bytes
-*/
+8*/
long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
oggbyte_buffer page;
@@ -284,7 +301,7 @@
_release_returned(oy);
bytes=oy->fifo_fill;
- oggbyte_init(&page,oy->fifo_tail,oy->fifo_cursor,0);
+ oggbyte_init(&page,oy->fifo_tail,0);
if(oy->headerbytes==0){
if(bytes<27)goto sync_out; /* not enough for even a minimal header */
@@ -307,107 +324,73 @@
}
if(oy->bodybytes+oy->headerbytes>bytes)goto sync_out;
-
- /* The whole test page is buffered. Set up the page struct and
- verify the checksum */
- {
- /* set up page return */
- ogg_reference *header=
- ogg_buffer_dup(oy->fifo_tail,
- oy->fifo_cursor,
- oy->headerbytes);
- ogg_reference *body=
- ogg_buffer_dup(oy->fifo_tail,
- oy->fifo_cursor+oy->headerbytes,
- oy->bodybytes);
- /* Grab the checksum bytes; remember all memory is common access */
+ /* we have what appears to be a complete page; last test: verify
+ checksum */
+ {
ogg_uint32_t chksum=oggbyte_read4(&page,22);
-
- {
- ogg_page og;
- og.header=header;
- og.body=body;
-
- ogg_page_checksum_set(&og);
- }
+ oggbyte_set4(&page,0,22);
/* Compare checksums; memory continues to be common access */
- if(chksum!=oggbyte_read4(&page,22)){
-
+ if(chksum!=_checksum(oy->fifo_tail,oy->bodybytes+oy->headerbytes)){
+
/* 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 access */
-
+
oggbyte_set4(&page,chksum,22);
goto sync_fail;
}
+ }
- /* yes, have a whole page all ready to go */
- if(og){
- /* set up page output */
- og->header=header;
- og->body=body;
- }
-
- ret=oy->headerbytes+oy->bodybytes;
- oy->unsynced=0;
- oy->headerbytes=0;
- oy->bodybytes=0;
- oy->fifo_cursor+=ret; /* advance the cursor past the page */
-
- /* 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);
- }
+ /* We have a page. Set up page return. */
+ if(og){
+ /* set up page output */
+ oy->returned_header=og->header=oy->fifo_tail;
+ oy->fifo_tail=ogg_buffer_split(oy->fifo_tail,oy->headerbytes);
+ oy->returned_body=og->body=oy->fifo_tail;
+ oy->fifo_tail=ogg_buffer_split(oy->fifo_tail,oy->bodybytes);
+ }else{
+ /* simply advance */
+ oy->fifo_tail=
+ ogg_buffer_split(oy->fifo_tail,oy->headerbytes+oy->bodybytes);
}
+
+ ret=oy->headerbytes+oy->bodybytes;
+ oy->unsynced=0;
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ if(!oy->fifo_tail)oy->fifo_head=0;
+
return ret;
sync_fail:
- {
- oy->headerbytes=0;
- oy->bodybytes=0;
- _release_returned(oy); /* would happen on CRC fail */
-
- oy->fifo_cursor++;
- ret--;
-
- /* search forward through fragments for possible capture */
- while(oy->fifo_tail){
- /* invariant: fifo_cursor points to a position in fifo_tail */
- unsigned char *now=oy->fifo_tail->buffer->data+
- oy->fifo_tail->begin+
- oy->fifo_cursor;
- unsigned char *next=
- memchr(now, 'O', oy->fifo_tail->length-oy->fifo_cursor);
+ oy->headerbytes=0;
+ oy->bodybytes=0;
+ oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,1);
+ ret--;
+
+ /* search forward through fragments for possible capture */
+ while(oy->fifo_tail){
+ /* invariant: fifo_cursor points to a position in fifo_tail */
+ unsigned char *now=oy->fifo_tail->buffer->data+oy->fifo_tail->begin;
+ unsigned char *next=memchr(now, 'O', oy->fifo_tail->length);
- if(next){
- /* possible capture in this segment */
- long bytes=next-now;
- oy->fifo_cursor+=bytes;
- ret-=bytes;
- break;
- }else{
- /* no capture. advance to next segment */
- ogg_reference *temp=oy->fifo_tail;
-
- ret-=temp->length-oy->fifo_cursor;
- oy->fifo_cursor=0;
-
- oy->fifo_tail=temp->next;
- if(!oy->fifo_tail)oy->fifo_head=0;
- ogg_buffer_release_one(temp);
-
- }
+ if(next){
+ /* possible capture in this segment */
+ long bytes=next-now;
+ oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,bytes);
+ ret-=bytes;
+ break;
+ }else{
+ /* no capture. advance to next segment */
+ long bytes=oy->fifo_tail->length;
+ ret-=bytes;
+ oy->fifo_tail=ogg_buffer_pretruncate(oy->fifo_tail,bytes);
}
}
+ if(!oy->fifo_tail)oy->fifo_head=0;
sync_out:
return(ret);
@@ -457,7 +440,6 @@
_release_returned(oy);
ogg_buffer_release(oy->fifo_tail);
oy->fifo_tail=oy->fifo_head=0;
- oy->fifo_cursor=0;
oy->unsynced=0;
oy->headerbytes=0;
@@ -472,10 +454,10 @@
oggbyte_buffer ob;
ogg_reference *or;
ogg_uint32_t crc_reg=0;
- int i,j;
+ int j;
/* safety; needed for API behavior, but not framing code */
- oggbyte_init(&ob,og->header,0,0);
+ oggbyte_init(&ob,og->header,0);
oggbyte_set4(&ob,0,22);
or=og->header;
@@ -483,7 +465,6 @@
unsigned char *data=or->buffer->data+or->begin;
for(j=0;j<or->length;j++)
crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^data[j]];
- i-=j;
or=or->next;
}
@@ -492,7 +473,6 @@
unsigned char *data=or->buffer->data+or->begin;
for(j=0;j<or->length;j++)
crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^data[j]];
- i-=j;
or=or->next;
}
<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