[xiph-commits] r16274 - branches/theora-thusnelda/lib/dec
gumboot at svn.xiph.org
gumboot at svn.xiph.org
Tue Jul 14 02:04:32 PDT 2009
Author: gumboot
Date: 2009-07-14 02:04:32 -0700 (Tue, 14 Jul 2009)
New Revision: 16274
Modified:
branches/theora-thusnelda/lib/dec/bitpack.c
branches/theora-thusnelda/lib/dec/bitpack.h
branches/theora-thusnelda/lib/dec/decinfo.c
branches/theora-thusnelda/lib/dec/decint.h
branches/theora-thusnelda/lib/dec/decode.c
branches/theora-thusnelda/lib/dec/dequant.c
branches/theora-thusnelda/lib/dec/dequant.h
branches/theora-thusnelda/lib/dec/huffdec.c
branches/theora-thusnelda/lib/dec/huffdec.h
Log:
Rewrite the bit-packing to use a sliding window/cache mechanism and abstract its error checking into separate calls to minimise overheads.
Modified: branches/theora-thusnelda/lib/dec/bitpack.c
===================================================================
--- branches/theora-thusnelda/lib/dec/bitpack.c 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/bitpack.c 2009-07-14 09:04:32 UTC (rev 16274)
@@ -14,108 +14,98 @@
last mod: $Id$
********************************************************************/
-
-/*We're 'MSb' endian; if we write a word but read individual bits,
- then we'll read the MSb first.*/
-
#include <string.h>
#include <stdlib.h>
#include "bitpack.h"
-void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes){
+/*We're 'MSb' endian; if we write a word but read individual bits,
+ then we'll read the MSb first.*/
+
+void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes){
memset(_b,0,sizeof(*_b));
- _b->buffer=_b->ptr=_buf;
- _b->storage=_bytes;
+ _b->ptr=_buf;
+ _b->stop=_buf+_bytes;
}
-int theorapackB_look1(oggpack_buffer *_b,long *_ret){
- if(_b->endbyte>=_b->storage){
- *_ret=0L;
- return -1;
+static oc_pb_window oc_pack_refill(oc_pack_buf *_b,int _bits){
+ const unsigned char *ptr;
+ const unsigned char *stop;
+ oc_pb_window window;
+ int available;
+ window=_b->window;
+ available=_b->bits;
+ ptr=_b->ptr;
+ stop=_b->stop;
+ while(available<=OC_PB_WINDOW_SIZE-8&&ptr<stop){
+ available+=8;
+ window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
}
- *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
- return 0;
+ _b->ptr=ptr;
+ if(_bits>available){
+ if(ptr>=stop){
+ _b->eof=1;
+ available=OC_LOTS_OF_BITS;
+ }
+ else window|=*ptr>>(available&7);
+ }
+ _b->bits=available;
+ return window;
}
-void theorapackB_adv1(oggpack_buffer *_b){
- if(++(_b->endbit)>7){
- _b->endbit=0;
- _b->ptr++;
- _b->endbyte++;
- }
+int oc_pack_look1(oc_pack_buf *_b){
+ oc_pb_window window;
+ int available;
+ window=_b->window;
+ available=_b->bits;
+ if(available<1)_b->window=window=oc_pack_refill(_b,1);
+ return window>>OC_PB_WINDOW_SIZE-1;
}
+void oc_pack_adv1(oc_pack_buf *_b){
+ _b->window<<=1;
+ _b->bits--;
+}
+
/*Here we assume that 0<=_bits&&_bits<=32.*/
-int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret){
- long ret;
- long m;
- long d;
- int fail;
- m=32-_bits;
- _bits+=_b->endbit;
- d=_b->storage-_b->endbyte;
- if(d<=4){
- /*Not the main path.*/
- if(d*8<_bits){
- *_ret=0L;
- fail=-1;
- 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){
- *_ret=0L;
- return 0;
- }
+long oc_pack_read(oc_pack_buf *_b,int _bits){
+ oc_pb_window window;
+ int available;
+ long result;
+ window=_b->window;
+ available=_b->bits;
+ if(_bits==0)return 0;
+ if(_bits>available){
+ window=oc_pack_refill(_b,_bits);
+ available=_b->bits;
}
- 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)ret|=_b->ptr[4]>>8-_b->endbit;
- }
- }
- }
- *_ret=((ret&0xFFFFFFFFUL)>>(m>>1))>>(m+1>>1);
- fail=0;
-overflow:
- _b->ptr+=_bits>>3;
- _b->endbyte+=_bits>>3;
- _b->endbit=_bits&7;
- return fail;
+ result=window>>OC_PB_WINDOW_SIZE-_bits;
+ available-=_bits;
+ window<<=1;
+ window<<=_bits-1;
+ _b->bits=available;
+ _b->window=window;
+ return result;
}
-int theorapackB_read1(oggpack_buffer *_b,long *_ret){
- int fail;
- if(_b->endbyte>=_b->storage){
- /*Not the main path.*/
- *_ret=0L;
- fail=-1;
+int oc_pack_read1(oc_pack_buf *_b){
+ oc_pb_window window;
+ int available;
+ int result;
+ window=_b->window;
+ available=_b->bits;
+ if(available<1){
+ window=oc_pack_refill(_b,1);
+ available=_b->bits;
}
- else{
- *_ret=(_b->ptr[0]>>7-_b->endbit)&1;
- fail=0;
- }
- _b->endbit++;
- if(_b->endbit>7){
- _b->endbit=0;
- _b->ptr++;
- _b->endbyte++;
- }
- return fail;
+ result=window>>OC_PB_WINDOW_SIZE-1;
+ available--;
+ window<<=1;
+ _b->bits=available;
+ _b->window=window;
+ return result;
}
-long theorapackB_bytes(oggpack_buffer *_b){
- return _b->endbyte+(_b->endbit+7>>3);
+long oc_pack_bytes_left(oc_pack_buf *_b){
+ if(_b->eof)return -1;
+ return _b->stop-_b->ptr+(_b->bits>>3);
}
-
-long theorapackB_bits(oggpack_buffer *_b){
- return _b->endbyte*8+_b->endbit;
-}
-
-unsigned char *theorapackB_get_buffer(oggpack_buffer *_b){
- return _b->buffer;
-}
Modified: branches/theora-thusnelda/lib/dec/bitpack.h
===================================================================
--- branches/theora-thusnelda/lib/dec/bitpack.h 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/bitpack.h 2009-07-14 09:04:32 UTC (rev 16274)
@@ -16,23 +16,44 @@
********************************************************************/
#if !defined(_bitpack_H)
# define _bitpack_H (1)
-# include <ogg/ogg.h>
+# include <limits.h>
-void theorapackB_readinit(oggpack_buffer *_b,unsigned char *_buf,int _bytes);
-int theorapackB_look1(oggpack_buffer *_b,long *_ret);
-void theorapackB_adv1(oggpack_buffer *_b);
+
+
+typedef unsigned long oc_pb_window;
+typedef struct oc_pack_buf oc_pack_buf;
+
+
+
+# define OC_PB_WINDOW_SIZE ((int)sizeof(oc_pb_window)*CHAR_BIT)
+/*This is meant to be a large, positive constant that can still be efficiently
+ loaded as an immediate (on platforms like ARM, for example).
+ Even relatively modest values like 100 would work fine.*/
+# define OC_LOTS_OF_BITS (0x40000000)
+
+
+
+struct oc_pack_buf{
+ oc_pb_window window;
+ const unsigned char *ptr;
+ const unsigned char *stop;
+ int bits;
+ int eof;
+};
+
+void oc_pack_readinit(oc_pack_buf *_b,unsigned char *_buf,long _bytes);
+int oc_pack_look1(oc_pack_buf *_b);
+void oc_pack_adv1(oc_pack_buf *_b);
/*Here we assume 0<=_bits&&_bits<=32.*/
-int theorapackB_read(oggpack_buffer *_b,int _bits,long *_ret);
-int theorapackB_read1(oggpack_buffer *_b,long *_ret);
-long theorapackB_bytes(oggpack_buffer *_b);
-long theorapackB_bits(oggpack_buffer *_b);
-unsigned char *theorapackB_get_buffer(oggpack_buffer *_b);
+long oc_pack_read(oc_pack_buf *_b,int _bits);
+int oc_pack_read1(oc_pack_buf *_b);
+/* returns -1 for read beyond EOF, or the number of whole bytes available */
+long oc_pack_bytes_left(oc_pack_buf *_b);
/*These two functions are implemented locally in huffdec.c*/
/*Read in bits without advancing the bitptr.
Here we assume 0<=_bits&&_bits<=32.*/
-/*static int theorapackB_look(oggpack_buffer *_b,int _bits,long *_ret);*/
-/*static void theorapackB_adv(oggpack_buffer *_b,int _bits);*/
+/*static int oc_pack_look(oc_pack_buf *_b,int _bits);*/
+/*static void oc_pack_adv(oc_pack_buf *_b,int _bits);*/
-
#endif
Modified: branches/theora-thusnelda/lib/dec/decinfo.c
===================================================================
--- branches/theora-thusnelda/lib/dec/decinfo.c 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/decinfo.c 2009-07-14 09:04:32 UTC (rev 16274)
@@ -27,30 +27,30 @@
_opb: The pack buffer to read the octets from.
_buf: The byte array to store the unpacked bytes in.
_len: The number of octets to unpack.*/
-static void oc_unpack_octets(oggpack_buffer *_opb,char *_buf,size_t _len){
+static void oc_unpack_octets(oc_pack_buf *_opb,char *_buf,size_t _len){
while(_len-->0){
long val;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
*_buf++=(char)val;
}
}
/*Unpacks a 32-bit integer encoded by octets in little-endian form.*/
-static long oc_unpack_length(oggpack_buffer *_opb){
+static long oc_unpack_length(oc_pack_buf *_opb){
long ret[4];
int i;
- for(i=0;i<4;i++)theorapackB_read(_opb,8,ret+i);
+ for(i=0;i<4;i++)ret[i]=oc_pack_read(_opb,8);
return ret[0]|ret[1]<<8|ret[2]<<16|ret[3]<<24;
}
-static int oc_info_unpack(oggpack_buffer *_opb,th_info *_info){
+static int oc_info_unpack(oc_pack_buf *_opb,th_info *_info){
long val;
/*Check the codec bitstream version.*/
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
_info->version_major=(unsigned char)val;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
_info->version_minor=(unsigned char)val;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
_info->version_subminor=(unsigned char)val;
/*verify we can parse this bitstream version.
We accept earlier minors and all subminors, by spec*/
@@ -60,21 +60,21 @@
return TH_EVERSION;
}
/*Read the encoded frame description.*/
- theorapackB_read(_opb,16,&val);
+ val=oc_pack_read(_opb,16);
_info->frame_width=(ogg_uint32_t)val<<4;
- theorapackB_read(_opb,16,&val);
+ val=oc_pack_read(_opb,16);
_info->frame_height=(ogg_uint32_t)val<<4;
- theorapackB_read(_opb,24,&val);
+ val=oc_pack_read(_opb,24);
_info->pic_width=(ogg_uint32_t)val;
- theorapackB_read(_opb,24,&val);
+ val=oc_pack_read(_opb,24);
_info->pic_height=(ogg_uint32_t)val;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
_info->pic_x=(ogg_uint32_t)val;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
_info->pic_y=(ogg_uint32_t)val;
- theorapackB_read(_opb,32,&val);
+ val=oc_pack_read(_opb,32);
_info->fps_numerator=(ogg_uint32_t)val;
- theorapackB_read(_opb,32,&val);
+ val=oc_pack_read(_opb,32);
_info->fps_denominator=(ogg_uint32_t)val;
if(_info->frame_width==0||_info->frame_height==0||
_info->pic_width+_info->pic_x>_info->frame_width||
@@ -87,38 +87,39 @@
This is because the bitstream uses a right-handed coordinate system, while
applications expect a left-handed one.*/
_info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
- theorapackB_read(_opb,24,&val);
+ val=oc_pack_read(_opb,24);
_info->aspect_numerator=(ogg_uint32_t)val;
- theorapackB_read(_opb,24,&val);
+ val=oc_pack_read(_opb,24);
_info->aspect_denominator=(ogg_uint32_t)val;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
_info->colorspace=(th_colorspace)val;
- theorapackB_read(_opb,24,&val);
+ val=oc_pack_read(_opb,24);
_info->target_bitrate=(int)val;
- theorapackB_read(_opb,6,&val);
+ val=oc_pack_read(_opb,6);
_info->quality=(int)val;
- theorapackB_read(_opb,5,&val);
+ val=oc_pack_read(_opb,5);
_info->keyframe_granule_shift=(int)val;
- theorapackB_read(_opb,2,&val);
+ val=oc_pack_read(_opb,2);
_info->pixel_fmt=(th_pixel_fmt)val;
if(_info->pixel_fmt==TH_PF_RSVD)return TH_EBADHEADER;
- if(theorapackB_read(_opb,3,&val)<0||val!=0)return TH_EBADHEADER;
+ val=oc_pack_read(_opb,3);
+ if(val!=0||oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
return 0;
}
-static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
+static int oc_comment_unpack(oc_pack_buf *_opb,th_comment *_tc){
long len;
int i;
/*Read the vendor string.*/
len=oc_unpack_length(_opb);
- if(len<0||len>_opb->storage-theorapackB_bytes(_opb))return TH_EBADHEADER;
+ if(len<0||len>oc_pack_bytes_left(_opb))return TH_EBADHEADER;
_tc->vendor=_ogg_malloc((size_t)len+1);
oc_unpack_octets(_opb,_tc->vendor,len);
_tc->vendor[len]='\0';
/*Read the user comments.*/
_tc->comments=(int)oc_unpack_length(_opb);
len=_tc->comments;
- if(len<0||len>(LONG_MAX>>2)||len<<2>_opb->storage-theorapackB_bytes(_opb)){
+ if(len<0||len>(LONG_MAX>>2)||len<<2>oc_pack_bytes_left(_opb)){
_tc->comments=0;
return TH_EBADHEADER;
}
@@ -128,7 +129,7 @@
_tc->comments*sizeof(_tc->user_comments[0]));
for(i=0;i<_tc->comments;i++){
len=oc_unpack_length(_opb);
- if(len<0||len>_opb->storage-theorapackB_bytes(_opb)){
+ if(len<0||len>oc_pack_bytes_left(_opb)){
_tc->comments=i;
return TH_EBADHEADER;
}
@@ -137,10 +138,10 @@
oc_unpack_octets(_opb,_tc->user_comments[i],len);
_tc->user_comments[i][len]='\0';
}
- return theorapackB_read(_opb,0,&len)<0?TH_EBADHEADER:0;
+ return oc_pack_bytes_left(_opb)<0?TH_EBADHEADER:0;
}
-static int oc_setup_unpack(oggpack_buffer *_opb,th_setup_info *_setup){
+static int oc_setup_unpack(oc_pack_buf *_opb,th_setup_info *_setup){
int ret;
/*Read the quantizer tables.*/
ret=oc_quant_params_unpack(_opb,&_setup->qinfo);
@@ -154,13 +155,13 @@
oc_huff_trees_clear(_setup->huff_tables);
}
-static int oc_dec_headerin(oggpack_buffer *_opb,th_info *_info,
+static int oc_dec_headerin(oc_pack_buf *_opb,th_info *_info,
th_comment *_tc,th_setup_info **_setup,ogg_packet *_op){
char buffer[6];
long val;
int packtype;
int ret;
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
packtype=(int)val;
/*If we're at a data packet and we have received all three headers, we're
done.*/
@@ -224,10 +225,10 @@
stream until it returns 0.*/
int th_decode_headerin(th_info *_info,th_comment *_tc,
th_setup_info **_setup,ogg_packet *_op){
- oggpack_buffer opb;
+ oc_pack_buf opb;
if(_op==NULL)return TH_EBADHEADER;
if(_info==NULL)return TH_EFAULT;
- theorapackB_readinit(&opb,_op->packet,_op->bytes);
+ oc_pack_readinit(&opb,_op->packet,_op->bytes);
return oc_dec_headerin(&opb,_info,_tc,_setup,_op);
}
Modified: branches/theora-thusnelda/lib/dec/decint.h
===================================================================
--- branches/theora-thusnelda/lib/dec/decint.h 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/decint.h 2009-07-14 09:04:32 UTC (rev 16274)
@@ -53,7 +53,7 @@
when a frame has been processed and a data packet is ready.*/
int packet_state;
/*Buffer in which to assemble packets.*/
- oggpack_buffer opb;
+ oc_pack_buf opb;
/*Huffman decode trees.*/
oc_huff_node *huff_tables[TH_NHUFFMAN_TABLES];
/*The index of the first token in each plane for each coefficient.*/
Modified: branches/theora-thusnelda/lib/dec/decode.c
===================================================================
--- branches/theora-thusnelda/lib/dec/decode.c 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/decode.c 2009-07-14 09:04:32 UTC (rev 16274)
@@ -93,7 +93,7 @@
};
-static int oc_sb_run_unpack(oggpack_buffer *_opb){
+static int oc_sb_run_unpack(oc_pack_buf *_opb){
long bits;
int ret;
/*Coding scheme:
@@ -105,30 +105,30 @@
11110xxx 10-17
111110xxxx 18-33
111111xxxxxxxxxxxx 34-4129*/
- theorapackB_read1(_opb,&bits);
+ bits=oc_pack_read1(_opb);
if(bits==0)return 1;
- theorapackB_read(_opb,2,&bits);
+ bits=oc_pack_read(_opb,2);
if((bits&2)==0)return 2+(int)bits;
else if((bits&1)==0){
- theorapackB_read1(_opb,&bits);
+ bits=oc_pack_read1(_opb);
return 4+(int)bits;
}
- theorapackB_read(_opb,3,&bits);
+ bits=oc_pack_read(_opb,3);
if((bits&4)==0)return 6+(int)bits;
else if((bits&2)==0){
ret=10+((bits&1)<<2);
- theorapackB_read(_opb,2,&bits);
+ bits=oc_pack_read(_opb,2);
return ret+(int)bits;
}
else if((bits&1)==0){
- theorapackB_read(_opb,4,&bits);
+ bits=oc_pack_read(_opb,4);
return 18+(int)bits;
}
- theorapackB_read(_opb,12,&bits);
+ bits=oc_pack_read(_opb,12);
return 34+(int)bits;
}
-static int oc_block_run_unpack(oggpack_buffer *_opb){
+static int oc_block_run_unpack(oc_pack_buf *_opb){
long bits;
long bits2;
/*Coding scheme:
@@ -139,21 +139,21 @@
1110xx 7-10
11110xx 11-14
11111xxxx 15-30*/
- theorapackB_read(_opb,2,&bits);
+ bits=oc_pack_read(_opb,2);
if((bits&2)==0)return 1+(int)bits;
else if((bits&1)==0){
- theorapackB_read1(_opb,&bits);
+ bits=oc_pack_read1(_opb);
return 3+(int)bits;
}
- theorapackB_read(_opb,2,&bits);
+ bits=oc_pack_read(_opb,2);
if((bits&2)==0)return 5+(int)bits;
else if((bits&1)==0){
- theorapackB_read(_opb,2,&bits);
+ bits=oc_pack_read(_opb,2);
return 7+(int)bits;
}
- theorapackB_read(_opb,3,&bits);
+ bits=oc_pack_read(_opb,3);
if((bits&4)==0)return 11+bits;
- theorapackB_read(_opb,2,&bits2);
+ bits2=oc_pack_read(_opb,2);
return 15+((bits&3)<<2)+bits2;
}
@@ -224,23 +224,23 @@
static int oc_dec_frame_header_unpack(oc_dec_ctx *_dec){
long val;
/*Check to make sure this is a data packet.*/
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
if(val!=0)return TH_EBADPACKET;
/*Read in the frame type (I or P).*/
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
_dec->state.frame_type=(int)val;
/*Read in the qi list.*/
- theorapackB_read(&_dec->opb,6,&val);
+ val=oc_pack_read(&_dec->opb,6);
_dec->state.qis[0]=(unsigned char)val;
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
if(!val)_dec->state.nqis=1;
else{
- theorapackB_read(&_dec->opb,6,&val);
+ val=oc_pack_read(&_dec->opb,6);
_dec->state.qis[1]=(unsigned char)val;
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
if(!val)_dec->state.nqis=2;
else{
- theorapackB_read(&_dec->opb,6,&val);
+ val=oc_pack_read(&_dec->opb,6);
_dec->state.qis[2]=(unsigned char)val;
_dec->state.nqis=3;
}
@@ -251,7 +251,7 @@
I don't know why these remain.*/
/*I wanted to eliminate wasted bits, but not all config wiggle room
--Monty.*/
- theorapackB_read(&_dec->opb,3,&val);
+ val=oc_pack_read(&_dec->opb,3);
if(val!=0)return TH_EIMPL;
}
return 0;
@@ -311,7 +311,7 @@
unsigned run_count;
long val;
int flag;
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
sb_flags=_dec->state.sb_flags;
nsbs=_dec->state.nsbs;
@@ -328,7 +328,7 @@
}
while(--run_count>0&&sbi<nsbs);
if(full_run&&sbi<nsbs){
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
}
else flag=!flag;
@@ -354,7 +354,7 @@
nsbs=_dec->state.nsbs;
/*Skip partially coded super blocks.*/
for(sbi=0;sb_flags[sbi].coded_partially;sbi++);
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
do{
int full_run;
@@ -366,7 +366,7 @@
sb_flags[sbi].coded_fully=flag;
}
if(full_run&&sbi<nsbs){
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
}
else flag=!flag;
@@ -395,7 +395,7 @@
npartial=oc_dec_partial_sb_flags_unpack(_dec);
if(npartial<_dec->state.nsbs)oc_dec_coded_sb_flags_unpack(_dec);
if(npartial>0){
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=!(int)val;
}
else flag=0;
@@ -443,21 +443,21 @@
-typedef int (*oc_mode_unpack_func)(oggpack_buffer *_opb);
+typedef int (*oc_mode_unpack_func)(oc_pack_buf *_opb);
-static int oc_vlc_mode_unpack(oggpack_buffer *_opb){
+static int oc_vlc_mode_unpack(oc_pack_buf *_opb){
long val;
int i;
for(i=0;i<7;i++){
- theorapackB_read1(_opb,&val);
+ val=oc_pack_read1(_opb);
if(!val)break;
}
return i;
}
-static int oc_clc_mode_unpack(oggpack_buffer *_opb){
+static int oc_clc_mode_unpack(oc_pack_buf *_opb){
long val;
- theorapackB_read(_opb,3,&val);
+ val=oc_pack_read(_opb,3);
return (int)val;
}
@@ -473,7 +473,7 @@
size_t mbi;
long val;
int mode_scheme;
- theorapackB_read(&_dec->opb,3,&val);
+ val=oc_pack_read(&_dec->opb,3);
mode_scheme=(int)val;
if(mode_scheme==0){
int mi;
@@ -484,7 +484,7 @@
/*LOOP VECTORIZES*/
for(mi=0;mi<OC_NMODES;mi++)scheme0_alphabet[mi]=OC_MODE_INTER_NOMV;
for(mi=0;mi<OC_NMODES;mi++){
- theorapackB_read(&_dec->opb,3,&val);
+ val=oc_pack_read(&_dec->opb,3);
scheme0_alphabet[val]=OC_MODE_ALPHABETS[6][mi];
}
alphabet=scheme0_alphabet;
@@ -511,13 +511,13 @@
-typedef int (*oc_mv_comp_unpack_func)(oggpack_buffer *_opb);
+typedef int (*oc_mv_comp_unpack_func)(oc_pack_buf *_opb);
-static int oc_vlc_mv_comp_unpack(oggpack_buffer *_opb){
+static int oc_vlc_mv_comp_unpack(oc_pack_buf *_opb){
long bits;
int mask;
int mv;
- theorapackB_read(_opb,3,&bits);
+ bits=oc_pack_read(_opb,3);
switch(bits){
case 0:return 0;
case 1:return 1;
@@ -525,14 +525,14 @@
case 3:
case 4:{
mv=(int)(bits-1);
- theorapackB_read1(_opb,&bits);
+ bits=oc_pack_read1(_opb);
}break;
/*case 5:
case 6:
case 7:*/
default:{
mv=1<<bits-3;
- theorapackB_read(_opb,bits-2,&bits);
+ bits=oc_pack_read(_opb,bits-2);
mv+=(int)(bits>>1);
bits&=1;
}break;
@@ -541,11 +541,11 @@
return mv+mask^mask;
}
-static int oc_clc_mv_comp_unpack(oggpack_buffer *_opb){
+static int oc_clc_mv_comp_unpack(oc_pack_buf *_opb){
long bits;
int mask;
int mv;
- theorapackB_read(_opb,6,&bits);
+ bits=oc_pack_read(_opb,6);
mv=(int)bits>>1;
mask=-((int)bits&1);
return mv+mask^mask;
@@ -568,7 +568,7 @@
size_t mbi;
long val;
set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt];
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
mv_comp_unpack=val?oc_clc_mv_comp_unpack:oc_vlc_mv_comp_unpack;
map_idxs=OC_MB_MAP_IDXS[_dec->state.info.pixel_fmt];
map_nidxs=OC_MB_MAP_NIDXS[_dec->state.info.pixel_fmt];
@@ -691,7 +691,7 @@
At first we just store the qii in the fragment.
After all the qii's are decoded, we make a final pass to replace them
with the corresponding qi's for this frame.*/
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
run_count=nqi1=0;
fragii=0;
@@ -705,7 +705,7 @@
}
while(--run_count>0&&fragii<ncoded_fragis);
if(full_run&&fragii<ncoded_fragis){
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
}
else flag=!flag;
@@ -717,7 +717,7 @@
if(_dec->state.nqis==3&&nqi1>0){
/*Skip qii==0 fragments.*/
for(fragii=0;frags[coded_fragis[fragii]].qii==0;fragii++);
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
do{
int full_run;
@@ -730,7 +730,7 @@
frags[fragi].qii+=flag;
}
if(full_run&&fragii<ncoded_fragis){
- theorapackB_read1(&_dec->opb,&val);
+ val=oc_pack_read1(&_dec->opb);
flag=(int)val;
}
else flag=!flag;
@@ -897,7 +897,7 @@
neb=OC_DCT_TOKEN_EXTRA_BITS[token];
if(neb){
long val;
- theorapackB_read(&_dec->opb,neb,&val);
+ val=oc_pack_read(&_dec->opb,neb);
eb=(int)val;
extra_bits[ebi++]=(ogg_uint16_t)eb;
}
@@ -976,7 +976,7 @@
neb=OC_DCT_TOKEN_EXTRA_BITS[token];
if(neb){
long val;
- theorapackB_read(&_dec->opb,neb,&val);
+ val=oc_pack_read(&_dec->opb,neb);
eb=(int)val;
extra_bits[ebi++]=(ogg_uint16_t)eb;
}
@@ -1041,15 +1041,15 @@
for(pli=0;pli<3;pli++)for(zzi=0;zzi<64;zzi++){
ntoks_left[pli][zzi]=_dec->state.ncoded_fragis[pli];
}
- theorapackB_read(&_dec->opb,4,&val);
+ val=oc_pack_read(&_dec->opb,4);
huff_idxs[0]=(int)val;
- theorapackB_read(&_dec->opb,4,&val);
+ val=oc_pack_read(&_dec->opb,4);
huff_idxs[1]=(int)val;
_dec->eob_runs[0][0]=0;
eobs=oc_dec_dc_coeff_unpack(_dec,huff_idxs,ntoks_left);
- theorapackB_read(&_dec->opb,4,&val);
+ val=oc_pack_read(&_dec->opb,4);
huff_idxs[0]=(int)val;
- theorapackB_read(&_dec->opb,4,&val);
+ val=oc_pack_read(&_dec->opb,4);
huff_idxs[1]=(int)val;
zzi=1;
for(hgi=1;hgi<5;hgi++){
@@ -1954,7 +1954,7 @@
int pli;
int notstart;
int notdone;
- theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes);
+ oc_pack_readinit(&_dec->opb,_op->packet,_op->bytes);
ret=oc_dec_frame_header_unpack(_dec);
if(ret<0)return ret;
/*Select a free buffer to use for the reconstructed version of this
Modified: branches/theora-thusnelda/lib/dec/dequant.c
===================================================================
--- branches/theora-thusnelda/lib/dec/dequant.c 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/dequant.c 2009-07-14 09:04:32 UTC (rev 16274)
@@ -21,7 +21,7 @@
#include "dequant.h"
#include "decint.h"
-int oc_quant_params_unpack(oggpack_buffer *_opb,th_quant_info *_qinfo){
+int oc_quant_params_unpack(oc_pack_buf *_opb,th_quant_info *_qinfo){
th_quant_base *base_mats;
long val;
int nbase_mats;
@@ -35,30 +35,30 @@
int qri;
int qi;
int i;
- theorapackB_read(_opb,3,&val);
+ val=oc_pack_read(_opb,3);
nbits=(int)val;
for(qi=0;qi<64;qi++){
- theorapackB_read(_opb,nbits,&val);
+ val=oc_pack_read(_opb,nbits);
_qinfo->loop_filter_limits[qi]=(unsigned char)val;
}
- theorapackB_read(_opb,4,&val);
+ val=oc_pack_read(_opb,4);
nbits=(int)val+1;
for(qi=0;qi<64;qi++){
- theorapackB_read(_opb,nbits,&val);
+ val=oc_pack_read(_opb,nbits);
_qinfo->ac_scale[qi]=(ogg_uint16_t)val;
}
- theorapackB_read(_opb,4,&val);
+ val=oc_pack_read(_opb,4);
nbits=(int)val+1;
for(qi=0;qi<64;qi++){
- theorapackB_read(_opb,nbits,&val);
+ val=oc_pack_read(_opb,nbits);
_qinfo->dc_scale[qi]=(ogg_uint16_t)val;
}
- theorapackB_read(_opb,9,&val);
+ val=oc_pack_read(_opb,9);
nbase_mats=(int)val+1;
base_mats=_ogg_malloc(nbase_mats*sizeof(base_mats[0]));
for(bmi=0;bmi<nbase_mats;bmi++){
for(ci=0;ci<64;ci++){
- theorapackB_read(_opb,8,&val);
+ val=oc_pack_read(_opb,8);
base_mats[bmi][ci]=(unsigned char)val;
}
}
@@ -71,12 +71,12 @@
pli=i%3;
qranges=_qinfo->qi_ranges[qti]+pli;
if(i>0){
- theorapackB_read1(_opb,&val);
+ val=oc_pack_read1(_opb);
if(!val){
int qtj;
int plj;
if(qti>0){
- theorapackB_read1(_opb,&val);
+ val=oc_pack_read1(_opb);
if(val){
qtj=qti-1;
plj=pli;
@@ -94,13 +94,13 @@
continue;
}
}
- theorapackB_read(_opb,nbits,&val);
+ val=oc_pack_read(_opb,nbits);
indices[0]=(int)val;
for(qi=qri=0;qi<63;){
- theorapackB_read(_opb,oc_ilog(62-qi),&val);
+ val=oc_pack_read(_opb,oc_ilog(62-qi));
sizes[qri]=(int)val+1;
qi+=(int)val+1;
- theorapackB_read(_opb,nbits,&val);
+ val=oc_pack_read(_opb,nbits);
indices[++qri]=(int)val;
}
/*Note: The caller is responsible for cleaning up any partially
Modified: branches/theora-thusnelda/lib/dec/dequant.h
===================================================================
--- branches/theora-thusnelda/lib/dec/dequant.h 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/dequant.h 2009-07-14 09:04:32 UTC (rev 16274)
@@ -18,8 +18,9 @@
#if !defined(_dequant_H)
# define _dequant_H (1)
# include "quant.h"
+# include "bitpack.h"
-int oc_quant_params_unpack(oggpack_buffer *_opb,
+int oc_quant_params_unpack(oc_pack_buf *_opb,
th_quant_info *_qinfo);
void oc_quant_params_clear(th_quant_info *_qinfo);
Modified: branches/theora-thusnelda/lib/dec/huffdec.c
===================================================================
--- branches/theora-thusnelda/lib/dec/huffdec.c 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/huffdec.c 2009-07-14 09:04:32 UTC (rev 16274)
@@ -25,52 +25,64 @@
#define _ogg_offsetof(_type,_field)\
((size_t)((char *)&((_type *)0)->_field-(char *)0))
-/*These two functions are really part of the bitpack.c module, but
- they are only used here. Declaring local static versions so they
- can be inlined saves considerable function call overhead.*/
+/*These three functions are really part of the bitpack.c module, but
+ they are only used here.
+ Declaring local static versions so they can be inlined saves considerable
+ function call overhead.*/
-/*Read in bits without advancing the bitptr.
- Here we assume 0<=_bits&&_bits<=32.*/
-static int theorapackB_look(oggpack_buffer *_b,int _bits,long *_ret){
- long ret;
- long m;
- long d;
- m=32-_bits;
- _bits+=_b->endbit;
- d=_b->storage-_b->endbyte;
- if(d<=4){
- /*Not the main path.*/
- if(d<=0){
- *_ret=0L;
- return -(_bits>d*8);
- }
- /*If we have some bits left, but not enough, return the ones we have.*/
- if(d*8<_bits)_bits=d*8;
+static oc_pb_window inline oc_pack_refill(oc_pack_buf *_b,int _bits){
+ const unsigned char *ptr;
+ const unsigned char *stop;
+ oc_pb_window window;
+ int available;
+ window=_b->window;
+ available=_b->bits;
+ ptr=_b->ptr;
+ stop=_b->stop;
+ /*This version of _refill() doesn't bother setting eof because we won't
+ check for it after we've started decoding DCT tokens.*/
+ if(ptr>=stop)available=OC_LOTS_OF_BITS;
+ while(available<=OC_PB_WINDOW_SIZE-8){
+ available+=8;
+ window|=(oc_pb_window)*ptr++<<OC_PB_WINDOW_SIZE-available;
+ if(ptr>=stop)available=OC_LOTS_OF_BITS;
}
- 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)ret|=_b->ptr[4]>>8-_b->endbit;
- }
- }
- }
- *_ret=((ret&0xFFFFFFFF)>>(m>>1))>>(m+1>>1);
- return 0;
+ _b->ptr=ptr;
+ if(_bits>available)window|=*ptr>>(available&7);
+ _b->bits=available;
+ return window;
}
-/*advance the bitptr*/
-static void theorapackB_adv(oggpack_buffer *_b,int _bits){
- _bits+=_b->endbit;
- _b->ptr+=_bits>>3;
- _b->endbyte+=_bits>>3;
- _b->endbit=_bits&7;
+
+/*Read in bits without advancing the bit pointer.
+ Here we assume 0<=_bits&&_bits<=32.*/
+static long oc_pack_look(oc_pack_buf *_b,int _bits){
+ oc_pb_window window;
+ int available;
+ long result;
+ window=_b->window;
+ available=_b->bits;
+ if(_bits==0)return 0;
+ if(_bits>available)_b->window=window=oc_pack_refill(_b,_bits);
+ result=window>>OC_PB_WINDOW_SIZE-_bits;
+ return result;
}
+/*Advance the bit pointer.*/
+static void oc_pack_adv(oc_pack_buf *_b,int _bits){
+ oc_pb_window window;
+ window=_b->window;
+ /*We ignore the special cases for _bits==0 and _bits==32 here, since they are
+ never used actually used.
+ OC_HUFF_SLUSH (defined below) would have to be at least 27 to actually read
+ 32 bits in a single go, and would require a 32 GB lookup table (assuming
+ 8 byte pointers, since 4 byte pointers couldn't fit such a table).*/
+ window<<=_bits;
+ _b->window=window;
+ _b->bits-=_bits;
+}
+
/*The log_2 of the size of a lookup table is allowed to grow to relative to
the number of unique nodes it contains.
E.g., if OC_HUFF_SLUSH is 2, then at most 75% of the space in the tree is
@@ -135,7 +147,7 @@
_binodes: The nodes to store the sub-tree in.
_nbinodes: The number of nodes available for the sub-tree.
Return: 0 on success, or a negative value on error.*/
-static int oc_huff_tree_unpack(oggpack_buffer *_opb,
+static int oc_huff_tree_unpack(oc_pack_buf *_opb,
oc_huff_node *_binodes,int _nbinodes){
oc_huff_node *binode;
long bits;
@@ -143,7 +155,8 @@
if(_nbinodes<1)return TH_EBADHEADER;
binode=_binodes;
nused=1;
- if(theorapackB_read1(_opb,&bits)<0)return TH_EBADHEADER;
+ bits=oc_pack_read1(_opb);
+ if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
/*Read an internal node:*/
if(!bits){
int ret;
@@ -161,7 +174,8 @@
}
/*Read a leaf node:*/
else{
- if(theorapackB_read(_opb,OC_NDCT_TOKEN_BITS,&bits)<0)return TH_EBADHEADER;
+ bits=oc_pack_read(_opb,OC_NDCT_TOKEN_BITS);
+ if(oc_pack_bytes_left(_opb)<0)return TH_EBADHEADER;
binode->nbits=0;
binode->depth=1;
binode->token=(unsigned char)bits;
@@ -283,7 +297,7 @@
_opb: The buffer to unpack the trees from.
_nodes: The table to fill with the Huffman trees.
Return: 0 on success, or a negative value on error.*/
-int oc_huff_trees_unpack(oggpack_buffer *_opb,
+int oc_huff_trees_unpack(oc_pack_buf *_opb,
oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]){
int i;
for(i=0;i<TH_NHUFFMAN_TABLES;i++){
@@ -317,12 +331,12 @@
_opb: The buffer to unpack the token from.
_node: The tree to unpack the token with.
Return: The token value.*/
-int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node){
+int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node){
long bits;
while(_node->nbits!=0){
- theorapackB_look(_opb,_node->nbits,&bits);
+ bits=oc_pack_look(_opb,_node->nbits);
_node=_node->nodes[bits];
- theorapackB_adv(_opb,_node->depth);
+ oc_pack_adv(_opb,_node->depth);
}
return _node->token;
}
Modified: branches/theora-thusnelda/lib/dec/huffdec.h
===================================================================
--- branches/theora-thusnelda/lib/dec/huffdec.h 2009-07-14 01:33:17 UTC (rev 16273)
+++ branches/theora-thusnelda/lib/dec/huffdec.h 2009-07-14 09:04:32 UTC (rev 16274)
@@ -18,6 +18,7 @@
#if !defined(_huffdec_H)
# define _huffdec_H (1)
# include "huffman.h"
+# include "bitpack.h"
@@ -80,12 +81,12 @@
-int oc_huff_trees_unpack(oggpack_buffer *_opb,
+int oc_huff_trees_unpack(oc_pack_buf *_opb,
oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
void oc_huff_trees_copy(oc_huff_node *_dst[TH_NHUFFMAN_TABLES],
const oc_huff_node *const _src[TH_NHUFFMAN_TABLES]);
void oc_huff_trees_clear(oc_huff_node *_nodes[TH_NHUFFMAN_TABLES]);
-int oc_huff_token_decode(oggpack_buffer *_opb,const oc_huff_node *_node);
+int oc_huff_token_decode(oc_pack_buf *_opb,const oc_huff_node *_node);
#endif
More information about the commits
mailing list