☠☠ backed out by 8b2f4c1f0d67 ☠ ☠ | |
author | Matthew Gregan <kinetik@flim.org> |
Thu, 10 Jun 2010 16:13:10 +1200 | |
changeset 43447 | 9b49ef1d36dd98cadd77f3e293eb1d01266855f1 |
parent 43446 | 8cc8e86e725ac50c27c6c4be809b53b9a0758744 |
child 43448 | 8b2f4c1f0d67881157eed67fd7c1fd83eb695783 |
push id | 13713 |
push user | cpearce@mozilla.com |
push date | Thu, 10 Jun 2010 04:13:31 +0000 |
treeherder | mozilla-central@9b49ef1d36dd [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 559344 |
milestone | 1.9.3a5pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/media/libogg/CHANGES +++ b/media/libogg/CHANGES @@ -1,8 +1,15 @@ +Version 1.2.0 (2010 March 25) + +* Alter default flushing behavior to span less often and use larger page + sizes when packet sizes are large. +* Build fixes for additional compilers +* Documentation updates + Version 1.1.4 (2009 June 24) * New async error reporting mechanism. Calls made after a fatal error are now safely handled in the event an error code is ignored * Added allocation checks useful to some embedded applications * fix possible read past end of buffer when reading 0 bits * Updates to API documentation * Build fixes
--- a/media/libogg/README_MOZILLA +++ b/media/libogg/README_MOZILLA @@ -1,10 +1,10 @@ The source from this directory was copied from the libogg subversion repository using the update.sh script. The only changes made were those applied by update.sh and the addition/upate of Makefile.in files for the Mozilla build system. -The svn revision number used was r16911. +The svn revision number used was r17270. The int-types.patch address a bug that config_types.h generated from Linux platform can't be used on OpenSolaris directly see Mozilla bug 449754
--- a/media/libogg/include/ogg/ogg.h +++ b/media/libogg/include/ogg/ogg.h @@ -6,17 +6,17 @@ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: toplevel libogg include - last mod: $Id: ogg.h 16051 2009-05-27 05:00:06Z xiphmont $ + last mod: $Id: ogg.h 17098 2010-03-29 05:35:11Z gmaxwell $ ********************************************************************/ #ifndef _OGG_H #define _OGG_H #ifdef __cplusplus extern "C" { #endif @@ -154,16 +154,17 @@ extern long oggpackB_bits(oggpack_buffe extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); /* Ogg BITSTREAM PRIMITIVES: encoding **************************/ extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count, long e_o_s, ogg_int64_t granulepos); extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); /* Ogg BITSTREAM PRIMITIVES: decoding **************************/ extern int ogg_sync_init(ogg_sync_state *oy); extern int ogg_sync_clear(ogg_sync_state *oy); extern int ogg_sync_reset(ogg_sync_state *oy); extern int ogg_sync_destroy(ogg_sync_state *oy);
--- a/media/libogg/include/ogg/os_types.h +++ b/media/libogg/include/ogg/os_types.h @@ -6,29 +6,42 @@ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: #ifdef jail to whip a few platforms into the UNIX ideal. - last mod: $Id: os_types.h 16649 2009-10-25 00:49:58Z ds $ + last mod: $Id: os_types.h 17270 2010-06-04 06:01:33Z xiphmont $ ********************************************************************/ #ifndef _OS_TYPES_H #define _OS_TYPES_H /* make it easy on the folks that want to compile the libs with a different malloc than stdlib */ #define _ogg_malloc malloc #define _ogg_calloc calloc #define _ogg_realloc realloc #define _ogg_free free +/* get non-brittle portable type-based MIN/MAX. Assumes 2's-complement + math */ +#define TYPE_HALF_MAX_SIGNED(type) \ + ((typeof(type))1 << (sizeof(type)*8-2)) +#define TYPE_MAX_SIGNED(type) \ + (TYPE_HALF_MAX_SIGNED(type) - 1 + TYPE_HALF_MAX_SIGNED(type)) +#define TYPE_MIN_SIGNED(type) \ + (-1 - TYPE_MAX_SIGNED(type)) +#define TYPE_MIN(type) \ + ((typeof(type))-1 < 1?TYPE_MIN_SIGNED(type):(typeof(type))0) +#define TYPE_MAX(type) \ + ((typeof(type))~TYPE_MIN(type)) + #if defined(_WIN32) # if defined(__CYGWIN__) # include <stdint.h> typedef int16_t ogg_int16_t; typedef uint16_t ogg_uint16_t; typedef int32_t ogg_int32_t; typedef uint32_t ogg_uint32_t;
--- a/media/libogg/src/ogg_bitwise.c +++ b/media/libogg/src/ogg_bitwise.c @@ -1,22 +1,22 @@ /******************************************************************** * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: packing variable sized words into an octet stream - last mod: $Id: bitwise.c 16051 2009-05-27 05:00:06Z xiphmont $ + last mod: $Id: bitwise.c 17270 2010-06-04 06:01:33Z xiphmont $ ********************************************************************/ /* We're 'LSb' endian; if we write a word but read individual bits, then we'll read the lsb first */ #include <string.h> #include <stdlib.h> @@ -75,24 +75,23 @@ void oggpackB_writetrunc(oggpack_buffer b->endbit=bits; b->endbyte=bytes; *b->ptr&=mask8B[bits]; } } /* Takes only up to 32 bits. */ void oggpack_write(oggpack_buffer *b,unsigned long value,int bits){ - if(b->endbyte+4>=b->storage){ + if(bits<0 || bits>32) goto err; + if(b->endbyte>=b->storage-4){ void *ret; if(!b->ptr)return; + if(b->storage>TYPE_MAX(b->storage)-BUFFER_INCREMENT) goto err; ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); - if(!ret){ - oggpack_writeclear(b); - return; - } + if(!ret) goto err; b->buffer=ret; b->storage+=BUFFER_INCREMENT; b->ptr=b->buffer+b->endbyte; } value&=mask[bits]; bits+=b->endbit; @@ -112,28 +111,30 @@ void oggpack_write(oggpack_buffer *b,uns } } } } b->endbyte+=bits/8; b->ptr+=bits/8; b->endbit=bits&7; + return; + err: + oggpack_writeclear(b); } /* Takes only up to 32 bits. */ void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits){ - if(b->endbyte+4>=b->storage){ + if(bits<0 || bits>32) goto err; + if(b->endbyte>=b->storage-4){ void *ret; if(!b->ptr)return; + if(b->storage>TYPE_MAX(b->storage)-BUFFER_INCREMENT) goto err; ret=_ogg_realloc(b->buffer,b->storage+BUFFER_INCREMENT); - if(!ret){ - oggpack_writeclear(b); - return; - } + if(!ret) goto err; b->buffer=ret; b->storage+=BUFFER_INCREMENT; b->ptr=b->buffer+b->endbyte; } value=(value&mask[bits])<<(32-bits); bits+=b->endbit; @@ -153,16 +154,19 @@ void oggpackB_write(oggpack_buffer *b,un } } } } b->endbyte+=bits/8; b->ptr+=bits/8; b->endbit=bits&7; + return; + err: + oggpack_writeclear(b); } void oggpack_writealign(oggpack_buffer *b){ int bits=8-b->endbit; if(bits<8) oggpack_write(b,0,bits); } @@ -188,39 +192,40 @@ static void oggpack_writecopy_helper(ogg int i; /* unaligned copy. Do it the hard way. */ for(i=0;i<bytes;i++) w(b,(unsigned long)(ptr[i]),8); }else{ /* aligned block copy */ if(b->endbyte+bytes+1>=b->storage){ void *ret; - if(!b->ptr)return; + if(!b->ptr) goto err; + if(b->endbyte+bytes+BUFFER_INCREMENT>b->storage) goto err; b->storage=b->endbyte+bytes+BUFFER_INCREMENT; ret=_ogg_realloc(b->buffer,b->storage); - if(!ret){ - oggpack_writeclear(b); - return; - } + if(!ret) goto err; b->buffer=ret; b->ptr=b->buffer+b->endbyte; } memmove(b->ptr,source,bytes); b->ptr+=bytes; b->endbyte+=bytes; *b->ptr=0; } if(bits){ if(msb) w(b,(unsigned long)(ptr[bytes]>>(8-bits)),bits); else w(b,(unsigned long)(ptr[bytes]),bits); } + return; + err: + oggpack_writeclear(b); } void oggpack_writecopy(oggpack_buffer *b,void *source,long bits){ oggpack_writecopy_helper(b,source,bits,oggpack_write,0); } void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits){ oggpack_writecopy_helper(b,source,bits,oggpackB_write,1); @@ -254,25 +259,30 @@ void oggpack_readinit(oggpack_buffer *b, void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes){ oggpack_readinit(b,buf,bytes); } /* Read in bits without advancing the bitptr; bits <= 32 */ long oggpack_look(oggpack_buffer *b,int bits){ unsigned long ret; - unsigned long m=mask[bits]; + unsigned long m; + if(bits<0 || bits>32) return -1; + m=mask[bits]; bits+=b->endbit; - if(b->endbyte+4>=b->storage){ + if(b->endbyte >= b->storage-4){ /* not the main path */ - if(b->endbyte*8+bits>b->storage*8)return(-1); + if(b->endbyte > b->storage-((bits+7)>>3)) return -1; + /* special case to avoid reading b->ptr[0], which might be past the end of + the buffer; also skips some useless accounting */ + else if(!bits)return(0L); } - + ret=b->ptr[0]>>b->endbit; if(bits>8){ ret|=b->ptr[1]<<(8-b->endbit); if(bits>16){ ret|=b->ptr[2]<<(16-b->endbit); if(bits>24){ ret|=b->ptr[3]<<(24-b->endbit); if(bits>32 && b->endbit) @@ -283,23 +293,27 @@ long oggpack_look(oggpack_buffer *b,int return(m&ret); } /* Read in bits without advancing the bitptr; bits <= 32 */ long oggpackB_look(oggpack_buffer *b,int bits){ unsigned long ret; int m=32-bits; + if(m<0 || m>32) return -1; bits+=b->endbit; - if(b->endbyte+4>=b->storage){ + if(b->endbyte >= b->storage-4){ /* not the main path */ - if(b->endbyte*8+bits>b->storage*8)return(-1); + if(b->endbyte > b->storage-((bits+7)>>3)) return -1; + /* special case to avoid reading b->ptr[0], which might be past the end of + the buffer; also skips some useless accounting */ + else if(!bits)return(0L); } - + ret=b->ptr[0]<<(24+b->endbit); if(bits>8){ ret|=b->ptr[1]<<(16+b->endbit); if(bits>16){ ret|=b->ptr[2]<<(8+b->endbit); if(bits>24){ ret|=b->ptr[3]<<(b->endbit); if(bits>32 && b->endbit) @@ -317,19 +331,28 @@ long oggpack_look1(oggpack_buffer *b){ long oggpackB_look1(oggpack_buffer *b){ if(b->endbyte>=b->storage)return(-1); return((b->ptr[0]>>(7-b->endbit))&1); } void oggpack_adv(oggpack_buffer *b,int bits){ bits+=b->endbit; + + if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; + b->ptr+=bits/8; b->endbyte+=bits/8; b->endbit=bits&7; + return; + + overflow: + b->ptr=NULL; + b->endbyte=b->storage; + b->endbit=1; } void oggpackB_adv(oggpack_buffer *b,int bits){ oggpack_adv(b,bits); } void oggpack_adv1(oggpack_buffer *b){ if(++(b->endbit)>7){ @@ -341,129 +364,140 @@ void oggpack_adv1(oggpack_buffer *b){ void oggpackB_adv1(oggpack_buffer *b){ oggpack_adv1(b); } /* bits <= 32 */ long oggpack_read(oggpack_buffer *b,int bits){ long ret; - unsigned long m=mask[bits]; + unsigned long m; + if(bits<0 || bits>32) goto err; + m=mask[bits]; bits+=b->endbit; - if(b->endbyte+4>=b->storage){ + if(b->endbyte >= b->storage-4){ /* not the main path */ - ret=-1L; - if(b->endbyte*8+bits>b->storage*8)goto overflow; + if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; + /* special case to avoid reading b->ptr[0], which might be past the end of + the buffer; also skips some useless accounting */ + else if(!bits)return(0L); } - + ret=b->ptr[0]>>b->endbit; if(bits>8){ ret|=b->ptr[1]<<(8-b->endbit); if(bits>16){ ret|=b->ptr[2]<<(16-b->endbit); if(bits>24){ ret|=b->ptr[3]<<(24-b->endbit); if(bits>32 && b->endbit){ ret|=b->ptr[4]<<(32-b->endbit); } } } } ret&=m; - - overflow: - b->ptr+=bits/8; b->endbyte+=bits/8; b->endbit=bits&7; - return(ret); + return ret; + + overflow: + err: + b->ptr=NULL; + b->endbyte=b->storage; + b->endbit=1; + return -1L; } /* bits <= 32 */ long oggpackB_read(oggpack_buffer *b,int bits){ long ret; long m=32-bits; - + + if(m<0 || m>32) goto err; bits+=b->endbit; if(b->endbyte+4>=b->storage){ /* not the main path */ - ret=-1L; - if(b->endbyte*8+bits>b->storage*8)goto overflow; + if(b->endbyte > b->storage-((bits+7)>>3)) goto overflow; /* special case to avoid reading b->ptr[0], which might be past the end of the buffer; also skips some useless accounting */ else if(!bits)return(0L); } - + ret=b->ptr[0]<<(24+b->endbit); if(bits>8){ ret|=b->ptr[1]<<(16+b->endbit); if(bits>16){ ret|=b->ptr[2]<<(8+b->endbit); if(bits>24){ ret|=b->ptr[3]<<(b->endbit); if(bits>32 && b->endbit) ret|=b->ptr[4]>>(8-b->endbit); } } } ret=((ret&0xffffffffUL)>>(m>>1))>>((m+1)>>1); - - overflow: b->ptr+=bits/8; b->endbyte+=bits/8; b->endbit=bits&7; - return(ret); + return ret; + + overflow: + err: + b->ptr=NULL; + b->endbyte=b->storage; + b->endbit=1; + return -1L; } long oggpack_read1(oggpack_buffer *b){ long ret; - - if(b->endbyte>=b->storage){ - /* not the main path */ - ret=-1L; - goto overflow; - } + if(b->endbyte >= b->storage) goto overflow; ret=(b->ptr[0]>>b->endbit)&1; - - overflow: b->endbit++; if(b->endbit>7){ b->endbit=0; b->ptr++; b->endbyte++; } - return(ret); + return ret; + + overflow: + b->ptr=NULL; + b->endbyte=b->storage; + b->endbit=1; + return -1L; } long oggpackB_read1(oggpack_buffer *b){ long ret; - - if(b->endbyte>=b->storage){ - /* not the main path */ - ret=-1L; - goto overflow; - } + if(b->endbyte >= b->storage) goto overflow; ret=(b->ptr[0]>>(7-b->endbit))&1; - - overflow: b->endbit++; if(b->endbit>7){ b->endbit=0; b->ptr++; b->endbyte++; } - return(ret); + return ret; + + overflow: + b->ptr=NULL; + b->endbyte=b->storage; + b->endbit=1; + return -1L; } long oggpack_bytes(oggpack_buffer *b){ return(b->endbyte+(b->endbit+7)/8); } long oggpack_bits(oggpack_buffer *b){ return(b->endbyte*8+b->endbit); @@ -687,29 +721,29 @@ int main(void){ cliptest(testbuffer2,test2size,17,five,fivesize); fprintf(stderr,"ok."); fprintf(stderr,"\nSingle bit unclipped packing (LSb): "); cliptest(testbuffer3,test3size,1,six,sixsize); fprintf(stderr,"ok."); fprintf(stderr,"\nTesting read past end (LSb): "); - oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8); + oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); for(i=0;i<64;i++){ if(oggpack_read(&r,1)!=0){ fprintf(stderr,"failed; got -1 prematurely.\n"); exit(1); } } if(oggpack_look(&r,1)!=-1 || oggpack_read(&r,1)!=-1){ fprintf(stderr,"failed; read past end without -1.\n"); exit(1); } - oggpack_readinit(&r,"\0\0\0\0\0\0\0\0",8); + oggpack_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); if(oggpack_read(&r,30)!=0 || oggpack_read(&r,16)!=0){ fprintf(stderr,"failed 2; got -1 prematurely.\n"); exit(1); } if(oggpack_look(&r,18)!=0 || oggpack_look(&r,18)!=0){ fprintf(stderr,"failed 3; got -1 prematurely.\n"); @@ -773,29 +807,29 @@ int main(void){ cliptestB(testbuffer2,test2size,17,fiveB,fivesize); fprintf(stderr,"ok."); fprintf(stderr,"\nSingle bit unclipped packing (MSb): "); cliptestB(testbuffer3,test3size,1,sixB,sixsize); fprintf(stderr,"ok."); fprintf(stderr,"\nTesting read past end (MSb): "); - oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8); + oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); for(i=0;i<64;i++){ if(oggpackB_read(&r,1)!=0){ fprintf(stderr,"failed; got -1 prematurely.\n"); exit(1); } } if(oggpackB_look(&r,1)!=-1 || oggpackB_read(&r,1)!=-1){ fprintf(stderr,"failed; read past end without -1.\n"); exit(1); } - oggpackB_readinit(&r,"\0\0\0\0\0\0\0\0",8); + oggpackB_readinit(&r,(unsigned char *)"\0\0\0\0\0\0\0\0",8); if(oggpackB_read(&r,30)!=0 || oggpackB_read(&r,16)!=0){ fprintf(stderr,"failed 2; got -1 prematurely.\n"); exit(1); } if(oggpackB_look(&r,18)!=0 || oggpackB_look(&r,18)!=0){ fprintf(stderr,"failed 3; got -1 prematurely.\n");
--- a/media/libogg/src/ogg_framing.c +++ b/media/libogg/src/ogg_framing.c @@ -1,23 +1,23 @@ /******************************************************************** * * - * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. * * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * * by the Xiph.Org Foundation http://www.xiph.org/ * * * ******************************************************************** function: code raw packets into framed OggSquish stream and decode Ogg streams back into raw packets - last mod: $Id: framing.c 16051 2009-05-27 05:00:06Z xiphmont $ + last mod: $Id: framing.c 17269 2010-06-04 05:39:45Z xiphmont $ note: The CRC code is directly derived from public domain code by Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html for details. ********************************************************************/ #include <stdlib.h> @@ -361,69 +361,79 @@ int ogg_stream_iovecin(ogg_stream_state int ogg_stream_packetin(ogg_stream_state *os,ogg_packet *op){ ogg_iovec_t iov; iov.iov_base = op->packet; iov.iov_len = op->bytes; return ogg_stream_iovecin(os, &iov, 1, op->e_o_s, op->granulepos); } -/* This will flush remaining packets into a page (returning nonzero), - even if there is not enough data to trigger a flush normally - (undersized page). If there are no packets or partial packets to - flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will - try to flush a normal sized page like ogg_stream_pageout; a call to - ogg_stream_flush does not guarantee that all packets have flushed. - Only a return value of 0 from ogg_stream_flush indicates all packet - data is flushed into pages. - - since ogg_stream_flush will flush the last page in a stream even if - it's undersized, you almost certainly want to use ogg_stream_pageout - (and *not* ogg_stream_flush) unless you specifically need to flush - an page regardless of size in the middle of a stream. */ - -int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ +/* Conditionally flush a page; force==0 will only flush nominal-size + pages, force==1 forces us to flush a page regardless of page size + so long as there's any data available at all. */ +static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int nfill){ int i; int vals=0; int maxvals=(os->lacing_fill>255?255:os->lacing_fill); int bytes=0; long acc=0; ogg_int64_t granule_pos=-1; - if(ogg_stream_check(os)) return 0; - if(maxvals==0)return 0; - + if(ogg_stream_check(os)) return(0); + if(maxvals==0) return(0); + /* construct a page */ /* decide how many segments to include */ - + /* If this is the initial header case, the first page must only include the initial header packet */ if(os->b_o_s==0){ /* 'initial header page' case */ granule_pos=0; for(vals=0;vals<maxvals;vals++){ if((os->lacing_vals[vals]&0x0ff)<255){ vals++; break; } } }else{ + + /* The extra packets_done, packet_just_done logic here attempts to do two things: + 1) Don't unneccessarily span pages. + 2) Unless necessary, don't flush pages if there are less than four packets on + them; this expands page size to reduce unneccessary overhead if incoming packets + are large. + These are not necessary behaviors, just 'always better than naive flushing' + without requiring an application to explicitly request a specific optimized + behavior. We'll want an explicit behavior setup pathway eventually as well. */ + + int packets_done=0; + int packet_just_done=0; for(vals=0;vals<maxvals;vals++){ - if(acc>4096)break; + if(acc>nfill && packet_just_done>=8){ + force=1; + break; + } acc+=os->lacing_vals[vals]&0x0ff; - if((os->lacing_vals[vals]&0xff)<255) + if((os->lacing_vals[vals]&0xff)<255){ granule_pos=os->granule_vals[vals]; + packet_just_done=++packets_done; + }else + packet_just_done=0; } + if(vals==255)force=1; } - + + if(!force) return(0); + /* construct the header in temp storage */ memcpy(os->header,"OggS",4); - + /* stream structure version */ os->header[4]=0x00; - + /* continued packet flag? */ os->header[5]=0x00; if((os->lacing_vals[0]&0x100)==0)os->header[5]|=0x01; /* first page flag? */ if(os->b_o_s==0)os->header[5]|=0x02; /* last page flag? */ if(os->e_o_s && os->lacing_fill==vals)os->header[5]|=0x04; os->b_o_s=1; @@ -485,34 +495,62 @@ int ogg_stream_flush(ogg_stream_state *o /* calculate the checksum */ ogg_page_checksum_set(og); /* done */ return(1); } +/* This will flush remaining packets into a page (returning nonzero), + even if there is not enough data to trigger a flush normally + (undersized page). If there are no packets or partial packets to + flush, ogg_stream_flush returns 0. Note that ogg_stream_flush will + try to flush a normal sized page like ogg_stream_pageout; a call to + ogg_stream_flush does not guarantee that all packets have flushed. + Only a return value of 0 from ogg_stream_flush indicates all packet + data is flushed into pages. + + since ogg_stream_flush will flush the last page in a stream even if + it's undersized, you almost certainly want to use ogg_stream_pageout + (and *not* ogg_stream_flush) unless you specifically need to flush + an page regardless of size in the middle of a stream. */ + +int ogg_stream_flush(ogg_stream_state *os,ogg_page *og){ + return ogg_stream_flush_i(os,og,1,4096); +} /* This constructs pages from buffered packet segments. The pointers returned are to static buffers; do not free. The returned buffers are good only until the next call (using the same ogg_stream_state) */ int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og){ + int force=0; if(ogg_stream_check(os)) return 0; if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ - os->body_fill-os->body_returned > 4096 ||/* 'page nominal size' case */ - os->lacing_fill>=255 || /* 'segment table full' case */ - (os->lacing_fill&&!os->b_o_s)){ /* 'initial header page' case */ - - return(ogg_stream_flush(os,og)); - } - - /* not enough data to construct a page and not end of stream */ - return 0; + (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */ + force=1; + + return(ogg_stream_flush_i(os,og,force,4096)); +} + +/* Like the above, but an argument is provided to adjust the nominal +page size for applications which are smart enough to provide their +own delay based flushing */ + +int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill){ + int force=0; + if(ogg_stream_check(os)) return 0; + + if((os->e_o_s&&os->lacing_fill) || /* 'were done, now flush' case */ + (os->lacing_fill&&!os->b_o_s)) /* 'initial header page' case */ + force=1; + + return(ogg_stream_flush_i(os,og,force,nfill)); } int ogg_stream_eos(ogg_stream_state *os){ if(ogg_stream_check(os)) return 1; return os->e_o_s; } /* DECODING PRIMITIVES: packet streaming layer **********************/ @@ -929,17 +967,17 @@ static int _packetout(ogg_stream_state * if(!op && !adv)return(1); /* just using peek as an inexpensive way to ask if there's a whole packet waiting */ /* Gather the whole packet. We'll have no holes or a partial packet */ { int size=os->lacing_vals[ptr]&0xff; - int bytes=size; + long bytes=size; int eos=os->lacing_vals[ptr]&0x200; /* last packet of the stream? */ int bos=os->lacing_vals[ptr]&0x100; /* first packet of the stream? */ while(size==255){ int val=os->lacing_vals[++ptr]; size=val&0xff; if(val&0x200)eos=0x200; bytes+=size; @@ -979,27 +1017,27 @@ void ogg_packet_clear(ogg_packet *op) { } #ifdef _V_SELFTEST #include <stdio.h> ogg_stream_state os_en, os_de; ogg_sync_state oy; -void checkpacket(ogg_packet *op,int len, int no, int pos){ +void checkpacket(ogg_packet *op,long len, int no, long pos){ long j; static int sequence=0; static int lastno=0; if(op->bytes!=len){ - fprintf(stderr,"incorrect packet length!\n"); + fprintf(stderr,"incorrect packet length (%ld != %ld)!\n",op->bytes,len); exit(1); } if(op->granulepos!=pos){ - fprintf(stderr,"incorrect packet position!\n"); + fprintf(stderr,"incorrect packet granpos (%ld != %ld)!\n",(long)op->granulepos,pos); exit(1); } /* packet number just follows sequence/gap; adjust the input number for that */ if(no==0){ sequence=0; }else{ @@ -1156,28 +1194,83 @@ const int head1_4[] = {0x4f,0x67,0x67,0x 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0}; const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x01,0x02,0x03,0x04,1,0,0,0, - 0x54,0x05,0x51,0xc8, - 17, + 0xf8,0x3c,0x19,0x79, + 255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255}; + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255}; const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05, 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,2,0,0,0, - 0xc8,0xc3,0xcb,0xed, - 5, - 10,255,4,255,0}; + 0x38,0xe6,0xb6,0x28, + 6, + 255,220,255,4,255,0}; + + +/* spill expansion test */ +const int head1_4b[] = {0x4f,0x67,0x67,0x53,0,0x02, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0,0,0,0, + 0xff,0x7b,0x23,0x17, + 1, + 0}; +const int head2_4b[] = {0x4f,0x67,0x67,0x53,0,0x00, + 0x07,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,1,0,0,0, + 0xe6,0x54,0xfe,0x7d, + 27, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,10,255,4,255,0,0,0,0,0,0}; + + +const int head3_4b[] = {0x4f,0x67,0x67,0x53,0,0x04, + 0x07,0x24,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,2,0,0,0, + 0x77,0x62,0xe0,0x12, + 1, + 0}; /* page with the 255 segment limit */ const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0}; @@ -1234,59 +1327,152 @@ const int head1_6[] = {0x4f,0x67,0x67,0x 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0}; const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00, 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, - 0x3c,0xd9,0x4d,0x3f, - 17, - 100,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255}; + 0x68,0x22,0x7c,0x3d, + 255, + 100, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255}; const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0x01,0x02,0x03,0x04,2,0,0,0, - 0x01,0xd2,0xe5,0xe5, - 17, + 0xf4,0x87,0xba,0xf3, + 255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255,255}; + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255}; const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05, 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,3,0,0,0, - 0xef,0xdd,0x88,0xde, - 7, - 255,255,75,255,4,255,0}; + 0xf7,0x2f,0x6c,0x60, + 5, + 254,255,4,255,0}; /* packet that overspans over an entire page */ const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,0,0,0,0, 0xff,0x7b,0x23,0x17, 1, 0}; const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00, 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,1,0,0,0, - 0x3c,0xd9,0x4d,0x3f, - 17, - 100,255,255,255,255,255,255,255,255, - 255,255,255,255,255,255,255,255}; + 0x68,0x22,0x7c,0x3d, + 255, + 100, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255, + 255,255,255,255,255,255}; const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05, 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00, 0x01,0x02,0x03,0x04,2,0,0,0, 0xd4,0xe0,0x60,0xe5, - 1,0}; + 1, + 0}; -void test_pack(const int *pl, const int **headers, int byteskip, +void test_pack(const int *pl, const int **headers, int byteskip, int pageskip, int packetskip){ unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */ long inptr=0; long outptr=0; long deptr=0; long depacket=0; long granule_pos=7,pageno=0; int i,j,packets,pageout=pageskip; @@ -1369,17 +1555,17 @@ void test_pack(const int *pl, const int ogg_sync_wrote(&oy,next-buf); while(1){ int ret=ogg_sync_pageout(&oy,&og_de); if(ret==0)break; if(ret<0)continue; /* got a page. Happy happy. Verify that it's good. */ - fprintf(stderr,"(%ld), ",pageout); + fprintf(stderr,"(%d), ",pageout); check_page(data+deptr,headers[pageout],&og_de); deptr+=og_de.body_len; pageout++; /* submit it to deconstitution */ ogg_stream_pagein(&os_de,&og_de); @@ -1468,57 +1654,67 @@ int main(void){ /* Exercise each code path in the framing code. Also verify that the checksums are working. */ { /* 17 only */ const int packets[]={17, -1}; const int *headret[]={head1_0,NULL}; - + fprintf(stderr,"testing single page encoding... "); test_pack(packets,headret,0,0,0); } { /* 17, 254, 255, 256, 500, 510, 600 byte, pad */ const int packets[]={17, 254, 255, 256, 500, 510, 600, -1}; const int *headret[]={head1_1,head2_1,NULL}; - + fprintf(stderr,"testing basic page encoding... "); test_pack(packets,headret,0,0,0); } { /* nil packets; beginning,middle,end */ const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1}; const int *headret[]={head1_2,head2_2,NULL}; - + fprintf(stderr,"testing basic nil packets... "); test_pack(packets,headret,0,0,0); } { /* large initial packet */ const int packets[]={4345,259,255,-1}; const int *headret[]={head1_3,head2_3,NULL}; - + fprintf(stderr,"testing initial-packet lacing > 4k... "); test_pack(packets,headret,0,0,0); } { - /* continuing packet test */ - const int packets[]={0,4345,259,255,-1}; + /* continuing packet test; with page spill expansion, we have to + overflow the lacing table. */ + const int packets[]={0,65500,259,255,-1}; const int *headret[]={head1_4,head2_4,head3_4,NULL}; - + fprintf(stderr,"testing single packet page span... "); test_pack(packets,headret,0,0,0); } + { + /* spill expand packet test */ + const int packets[]={0,4345,259,255,0,0,0,0,0,0,-1}; + const int *headret[]={head1_4b,head2_4b,head3_4b,NULL}; + + fprintf(stderr,"testing page spill expansion... "); + test_pack(packets,headret,0,0,0); + } + /* page with the 255 segment limit */ { const int packets[]={0,10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, 10,10,10,10,10,10,10,10, @@ -1552,48 +1748,48 @@ int main(void){ const int *headret[]={head1_5,head2_5,head3_5,NULL}; fprintf(stderr,"testing max packet segments... "); test_pack(packets,headret,0,0,0); } { /* packet that overspans over an entire page */ - const int packets[]={0,100,9000,259,255,-1}; + const int packets[]={0,100,130049,259,255,-1}; const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; fprintf(stderr,"testing very large packets... "); test_pack(packets,headret,0,0,0); } { /* test for the libogg 1.1.1 resync in large continuation bug found by Josh Coalson) */ - const int packets[]={0,100,9000,259,255,-1}; + const int packets[]={0,100,130049,259,255,-1}; const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL}; fprintf(stderr,"testing continuation resync in very large packets... "); test_pack(packets,headret,100,2,3); } { /* term only page. why not? */ - const int packets[]={0,100,4080,-1}; + const int packets[]={0,100,64770,-1}; const int *headret[]={head1_7,head2_7,head3_7,NULL}; fprintf(stderr,"testing zero data page (1 nil packet)... "); test_pack(packets,headret,0,0,0); } { /* build a bunch of pages for testing */ unsigned char *data=_ogg_malloc(1024*1024); - int pl[]={0,100,4079,2956,2057,76,34,912,0,234,1000,1000,1000,300,-1}; + int pl[]={0, 0,0,0,0,1,1,98,4079, 0,0,0,0,1,1,2954,2057, 0,0,0,0,76,34,912,0,234,1000,1000, 1000,300,-1}; int inptr=0,i,j; ogg_page og[5]; ogg_stream_reset(&os_en); for(i=0;pl[i]!=-1;i++){ ogg_packet op; int len=pl[i]; @@ -1644,27 +1840,47 @@ int main(void){ ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); /* do we get the expected results/packets? */ if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,0,0,0); if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,100,1,-1); + checkpacket(&test,0,1,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,2,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,3,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,4,-1); if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,4079,2,3000); + checkpacket(&test,1,5,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,1,6,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,98,7,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,4079,8,9000); if(ogg_stream_packetout(&os_de,&test)!=-1){ fprintf(stderr,"Error: loss of page did not return error\n"); exit(1); } if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,76,5,-1); + checkpacket(&test,0,17,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,18,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,19,-1); if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,34,6,-1); + checkpacket(&test,0,20,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,76,21,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,34,22,-1); fprintf(stderr,"ok.\n"); } /* Test lost pages on pagein/packetout: rollback with continuation */ { ogg_page temp; ogg_packet test; @@ -1687,81 +1903,107 @@ int main(void){ ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); ogg_sync_pageout(&oy,&temp); /* skip */ ogg_sync_pageout(&oy,&temp); ogg_stream_pagein(&os_de,&temp); /* do we get the expected results/packets? */ - + if(ogg_stream_packetout(&os_de,&test)!=1)error(); checkpacket(&test,0,0,0); if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,100,1,-1); + checkpacket(&test,0,1,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,2,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,3,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,4,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,1,5,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,1,6,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,98,7,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,4079,8,9000); if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,4079,2,3000); + checkpacket(&test,0,9,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,10,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,11,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,0,12,-1); if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,2956,3,4000); + checkpacket(&test,1,13,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,1,14,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,2954,15,-1); + if(ogg_stream_packetout(&os_de,&test)!=1)error(); + checkpacket(&test,2057,16,17000); if(ogg_stream_packetout(&os_de,&test)!=-1){ fprintf(stderr,"Error: loss of page did not return error\n"); exit(1); } if(ogg_stream_packetout(&os_de,&test)!=1)error(); - checkpacket(&test,300,13,14000); + checkpacket(&test,300,29,30000); fprintf(stderr,"ok.\n"); } - + /* the rest only test sync */ { ogg_page og_de; /* Test fractional page inputs: incomplete capture */ fprintf(stderr,"Testing sync on partial inputs... "); ogg_sync_reset(&oy); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, 3); ogg_sync_wrote(&oy,3); if(ogg_sync_pageout(&oy,&og_de)>0)error(); - + /* Test fractional page inputs: incomplete fixed header */ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3, 20); ogg_sync_wrote(&oy,20); if(ogg_sync_pageout(&oy,&og_de)>0)error(); - + /* Test fractional page inputs: incomplete header */ memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23, 5); ogg_sync_wrote(&oy,5); if(ogg_sync_pageout(&oy,&og_de)>0)error(); - + /* Test fractional page inputs: incomplete body */ - + memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28, og[1].header_len-28); ogg_sync_wrote(&oy,og[1].header_len-28); if(ogg_sync_pageout(&oy,&og_de)>0)error(); - + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000); ogg_sync_wrote(&oy,1000); if(ogg_sync_pageout(&oy,&og_de)>0)error(); - + memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000, og[1].body_len-1000); ogg_sync_wrote(&oy,og[1].body_len-1000); if(ogg_sync_pageout(&oy,&og_de)<=0)error(); - + fprintf(stderr,"ok.\n"); } /* Test fractional page inputs: page + incomplete capture */ { ogg_page og_de; fprintf(stderr,"Testing sync on 1+partial inputs... "); - ogg_sync_reset(&oy); + ogg_sync_reset(&oy); memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header, og[1].header_len); ogg_sync_wrote(&oy,og[1].header_len); memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body, og[1].body_len); ogg_sync_wrote(&oy,og[1].body_len);