[xiph-commits] r14059 - in trunk/theora/lib: . dec enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Sun Oct 28 16:43:27 PDT 2007
Author: xiphmont
Date: 2007-10-28 16:43:27 -0700 (Sun, 28 Oct 2007)
New Revision: 14059
Modified:
trunk/theora/lib/Makefile.am
trunk/theora/lib/dec/decapiwrapper.c
trunk/theora/lib/dec/decode.c
trunk/theora/lib/dec/internal.c
trunk/theora/lib/dec/quant.c
trunk/theora/lib/dec/quant.h
trunk/theora/lib/dec/state.c
trunk/theora/lib/enc/block_inline.h
trunk/theora/lib/enc/blockmap.c
trunk/theora/lib/enc/codec_internal.h
trunk/theora/lib/enc/dct_decode.c
trunk/theora/lib/enc/dct_encode.c
trunk/theora/lib/enc/encode.c
trunk/theora/lib/enc/encoder_lookup.h
trunk/theora/lib/enc/encoder_quant.c
trunk/theora/lib/enc/encoder_toplevel.c
trunk/theora/lib/enc/frinit.c
trunk/theora/lib/enc/pb.c
trunk/theora/lib/internal.h
Log:
Partial reimplementation of encoder quant initialization more in line with derf's exp code
Much more work to be done there... and everywhere
add code to dump debugging information to compare encode/decode processes in great detail
Modified: trunk/theora/lib/Makefile.am
===================================================================
--- trunk/theora/lib/Makefile.am 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/Makefile.am 2007-10-28 23:43:27 UTC (rev 14059)
@@ -136,7 +136,7 @@
libtheora_la_LIBADD = $(OGG_LIBS)
debug:
- $(MAKE) all CFLAGS="@DEBUG@" LDFLAGS="-lefence"
+ $(MAKE) all CFLAGS="@DEBUG@"
profile:
$(MAKE) all CFLAGS="@PROFILE@"
Modified: trunk/theora/lib/dec/decapiwrapper.c
===================================================================
--- trunk/theora/lib/dec/decapiwrapper.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/dec/decapiwrapper.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -169,6 +169,11 @@
int ret;
api=(th_api_wrapper *)_td->i->codec_setup;
ret=th_decode_packetin(api->decode,_op,&gp);
+
+#ifdef _TH_DEBUG_
+ dframe++;
+#endif
+
if(ret<0)return OC_BADPACKET;
_td->granulepos=gp;
return 0;
@@ -178,6 +183,7 @@
th_api_wrapper *api;
th_ycbcr_buffer buf;
int ret;
+
api=(th_api_wrapper *)_td->i->codec_setup;
ret=th_decode_ycbcr_out(api->decode,buf);
if(ret>=0){
@@ -192,9 +198,5 @@
_yuv->v=buf[2].data;
}
-#ifdef _TH_DEBUG_
- dframe++;
-#endif
-
return ret;
}
Modified: trunk/theora/lib/dec/decode.c
===================================================================
--- trunk/theora/lib/dec/decode.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/dec/decode.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -153,7 +153,6 @@
};
-
static int oc_sb_run_unpack(oggpack_buffer *_opb){
long bits;
int ret;
@@ -234,7 +233,7 @@
_dec->state.dequant_table_data[qti][pli];
}
oc_dequant_tables_init(_dec->state.dequant_tables,_dec->pp_dc_scale,
- &_setup->qinfo);
+ &_setup->qinfo);
for(qi=0;qi<64;qi++){
int qsum;
qsum=0;
@@ -274,32 +273,43 @@
static int oc_dec_frame_header_unpack(oc_dec_ctx *_dec){
long val;
+
+ TH_DEBUG("\n>>>> beginning frame %ld\n\n",dframe);
+
/*Check to make sure this is a data packet.*/
theora_read1(&_dec->opb,&val);
+ TH_DEBUG("frame type = %s, ",val==0?"video":"unknown");
if(val!=0)return TH_EBADPACKET;
/*Read in the frame type (I or P).*/
theora_read1(&_dec->opb,&val);
_dec->state.frame_type=(int)val;
+ TH_DEBUG("%s\n",val?"predicted":"key");
/*Read in the current qi.*/
theora_read(&_dec->opb,6,&val);
_dec->state.qis[0]=(int)val;
+ TH_DEBUG("frame quality = { %ld ",val);
theora_read1(&_dec->opb,&val);
if(!val)_dec->state.nqis=1;
else{
theora_read(&_dec->opb,6,&val);
_dec->state.qis[1]=(int)val;
+ TH_DEBUG("%ld ",val);
theora_read1(&_dec->opb,&val);
if(!val)_dec->state.nqis=2;
else{
theora_read(&_dec->opb,6,&val);
+ TH_DEBUG("%ld ",val);
_dec->state.qis[2]=(int)val;
_dec->state.nqis=3;
}
}
+ TH_DEBUG("}\n");
+
if(_dec->state.frame_type==OC_INTRA_FRAME){
/*Keyframes have 3 unused configuration bits, holdovers from VP3 days.
Most of the other unused bits in the VP3 headers were eliminated.
I don't know why these remain.*/
+ /* I wanted to eliminate wasted bits, but not all config wiggle room --Monty */
theora_read(&_dec->opb,3,&val);
if(val!=0)return TH_EIMPL;
}
@@ -481,6 +491,71 @@
}
/*TODO: run_count should be 0 here.
If it's not, we should issue a warning of some kind.*/
+
+
+#ifdef _TH_DEBUG_
+ // assuming 4:2:0 right now; THIS IS WRONG but only an issue if dumping debug info
+ TH_DEBUG("predicted (partially coded frame)\n");
+ TH_DEBUG("superblock coded flags = {");
+ int x,y,i;
+ int w = _dec->state.info.frame_width;
+ int h = _dec->state.info.frame_height;
+
+ i=0;
+ for(y=0;y< (h+31)/32;y++){
+ TH_DEBUG("\n ");
+ for(x=0;x< (w+31)/32;x++,i++)
+ TH_DEBUG("%x", (_dec->state.sbs[i].coded_partially!=0)|
+ (_dec->state.sbs[i].coded_fully));
+ }
+
+ TH_DEBUG("\n ");
+ for(y=0;y< (h+63)/64;y++){
+ TH_DEBUG("\n ");
+ for(x=0;x< (w+63)/64;x++,i++)
+ TH_DEBUG("%x", (_dec->state.sbs[i].coded_partially!=0)|
+ (_dec->state.sbs[i].coded_fully));
+ }
+ TH_DEBUG("\n ");
+ for(y=0;y< (h+63)/64;y++){
+ TH_DEBUG("\n ");
+ for(x=0;x< (w+63)/64;x++,i++)
+ TH_DEBUG("%x", (_dec->state.sbs[i].coded_partially!=0)|
+ (_dec->state.sbs[i].coded_fully));
+ }
+ TH_DEBUG("\n}\n");
+
+ if(i!=_dec->state.nsbs)
+ TH_DEBUG("WARNING! superblock count, raster %d != flat %d\n",
+ i,_dec->state.nsbs);
+
+ TH_DEBUG("block coded flags = {");
+
+ i=0;
+ for(y=0;y< (h+7)/8;y++){
+ TH_DEBUG("\n ");
+ for(x=0;x< (w+7)/8;x++,i++)
+ TH_DEBUG("%x", (_dec->state.frags[i].coded!=0));
+ }
+ TH_DEBUG("\n ");
+ for(y=0;y< (h+15)/16;y++){
+ TH_DEBUG("\n ");
+ for(x=0;x< (w+15)/16;x++,i++)
+ TH_DEBUG("%x", (_dec->state.frags[i].coded!=0));
+ }
+ TH_DEBUG("\n ");
+ for(y=0;y< (h+15)/16;y++){
+ TH_DEBUG("\n ");
+ for(x=0;x< (w+15)/16;x++,i++)
+ TH_DEBUG("%x", (_dec->state.frags[i].coded!=0));
+ }
+ TH_DEBUG("\n}\n");
+
+ if(i!=_dec->state.nfrags)
+ TH_DEBUG("WARNING! block count, raster %d != flat %d\n",
+ i,_dec->state.nfrags);
+#endif
+
}
@@ -509,39 +584,61 @@
oc_mb *mb;
oc_mb *mb_end;
const int *alphabet;
- long val;
+ long val,j;
int scheme0_alphabet[8];
int mode_scheme;
theora_read(&_dec->opb,3,&val);
mode_scheme=(int)val;
+ TH_DEBUG("mode encode scheme = %d\n",(int)val);
+
if(mode_scheme==0){
int mi;
/*Just in case, initialize the modes to something.
If the bitstream doesn't contain each index exactly once, it's likely
corrupt and the rest of the packet is garbage anyway, but this way we
won't crash, and we'll decode SOMETHING.*/
+ TH_DEBUG("mode scheme list = { ");
for(mi=0;mi<OC_NMODES;mi++)scheme0_alphabet[mi]=OC_MODE_INTER_NOMV;
for(mi=0;mi<OC_NMODES;mi++){
theora_read(&_dec->opb,3,&val);
scheme0_alphabet[val]=OC_MODE_ALPHABETS[6][mi];
+ TH_DEBUG("%d ",(int)val);
}
+ TH_DEBUG("}\n");
alphabet=scheme0_alphabet;
- }
- else alphabet=OC_MODE_ALPHABETS[mode_scheme-1];
- if(mode_scheme==7)mode_unpack=oc_clc_mode_unpack;
- else mode_unpack=oc_vlc_mode_unpack;
+ }else
+ alphabet=OC_MODE_ALPHABETS[mode_scheme-1];
+ if(mode_scheme==7)
+ mode_unpack=oc_clc_mode_unpack;
+ else
+ mode_unpack=oc_vlc_mode_unpack;
mb=_dec->state.mbs;
mb_end=mb+_dec->state.nmbs;
- for(;mb<mb_end;mb++)if(mb->mode!=OC_MODE_INVALID){
- int bi;
- for(bi=0;bi<4;bi++){
- int fragi;
- fragi=mb->map[0][bi];
- if(fragi>=0&&_dec->state.frags[fragi].coded)break;
+
+ TH_DEBUG("mode list = { ");
+ for(j=0;mb<mb_end;mb++){
+ if(mb->mode!=OC_MODE_INVALID){
+ int bi;
+ for(bi=0;bi<4;bi++){
+ int fragi;
+ fragi=mb->map[0][bi];
+ if(fragi>=0&&_dec->state.frags[fragi].coded)break;
+ }
+ if(bi<4){
+ mb->mode=alphabet[(*mode_unpack)(&_dec->opb)];
+
+#ifdef _TH_DEBUG_
+ if((j&0x1f)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%d ",mb->mode);
+ j++;
+#endif
+
+ }else
+ mb->mode=OC_MODE_INTER_NOMV;
}
- if(bi<4)mb->mode=alphabet[(*mode_unpack)(&_dec->opb)];
- else mb->mode=OC_MODE_INTER_NOMV;
}
+ TH_DEBUG("\n}\n");
}
@@ -603,16 +700,21 @@
const int *map_idxs;
long val;
int map_nidxs;
+ int j=0;
oc_mv last_mv[2];
oc_mv cbmvs[4];
set_chroma_mvs=OC_SET_CHROMA_MVS_TABLE[_dec->state.info.pixel_fmt];
theora_read1(&_dec->opb,&val);
+ TH_DEBUG("motion vector table = %d\n",(int)val);
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];
memset(last_mv,0,sizeof(last_mv));
mb=_dec->state.mbs;
mb_end=mb+_dec->state.nmbs;
+
+ TH_DEBUG("motion vectors = {");
+
for(;mb<mb_end;mb++)if(mb->mode!=OC_MODE_INVALID){
oc_fragment *frag;
oc_mv mbmv;
@@ -634,62 +736,98 @@
if(ncoded<=0)continue;
mb_mode=mb->mode;
switch(mb_mode){
- case OC_MODE_INTER_MV_FOUR:{
- oc_mv lbmvs[4];
- int bi;
- /*Mark the tail of the list, so we don't accidentally go past it.*/
- coded[ncoded]=-1;
- for(bi=codedi=0;bi<4;bi++){
- if(coded[codedi]==bi){
- codedi++;
- frag=_dec->state.frags+mb->map[0][bi];
- frag->mbmode=mb_mode;
- frag->mv[0]=lbmvs[bi][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
- frag->mv[1]=lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
- }
- else lbmvs[bi][0]=lbmvs[bi][1]=0;
- }
- if(codedi>0){
- last_mv[1][0]=last_mv[0][0];
- last_mv[1][1]=last_mv[0][1];
- last_mv[0][0]=lbmvs[coded[codedi-1]][0];
- last_mv[0][1]=lbmvs[coded[codedi-1]][1];
- }
- if(codedi<ncoded){
- (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
- for(;codedi<ncoded;codedi++){
- mapi=coded[codedi];
- bi=mapi&3;
- frag=_dec->state.frags+mb->map[mapi>>2][bi];
- frag->mbmode=mb_mode;
- frag->mv[0]=cbmvs[bi][0];
- frag->mv[1]=cbmvs[bi][1];
- }
- }
- }break;
- case OC_MODE_INTER_MV:{
- last_mv[1][0]=last_mv[0][0];
- last_mv[1][1]=last_mv[0][1];
- mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
- mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
- }break;
- case OC_MODE_INTER_MV_LAST:{
+ case OC_MODE_INTER_MV_FOUR:
+ {
+ oc_mv lbmvs[4];
+ int bi;
+ /*Mark the tail of the list, so we don't accidentally go past it.*/
+ coded[ncoded]=-1;
+ for(bi=codedi=0;bi<4;bi++){
+ if(coded[codedi]==bi){
+ codedi++;
+ frag=_dec->state.frags+mb->map[0][bi];
+ frag->mbmode=mb_mode;
+ frag->mv[0]=lbmvs[bi][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+ frag->mv[1]=lbmvs[bi][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+
+#ifdef _TH_DEBUG_
+ if((j&0x7)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%+03d,%+03d ",frag->mv[0],frag->mv[1]);
+ j++;
+#endif
+
+ }
+ else lbmvs[bi][0]=lbmvs[bi][1]=0;
+ }
+ if(codedi>0){
+ last_mv[1][0]=last_mv[0][0];
+ last_mv[1][1]=last_mv[0][1];
+ last_mv[0][0]=lbmvs[coded[codedi-1]][0];
+ last_mv[0][1]=lbmvs[coded[codedi-1]][1];
+ }
+ if(codedi<ncoded){
+ (*set_chroma_mvs)(cbmvs,(const oc_mv *)lbmvs);
+ for(;codedi<ncoded;codedi++){
+ mapi=coded[codedi];
+ bi=mapi&3;
+ frag=_dec->state.frags+mb->map[mapi>>2][bi];
+ frag->mbmode=mb_mode;
+ frag->mv[0]=cbmvs[bi][0];
+ frag->mv[1]=cbmvs[bi][1];
+ }
+ }
+ }
+ break;
+ case OC_MODE_INTER_MV:
+ {
+ last_mv[1][0]=last_mv[0][0];
+ last_mv[1][1]=last_mv[0][1];
+ mbmv[0]=last_mv[0][0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+ mbmv[1]=last_mv[0][1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
+
+#ifdef _TH_DEBUG_
+ if((j&0x7)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%+03d,%+03d ",mbmv[0],mbmv[1]);
+ j++;
+#endif
+
+ }
+ break;
+ case OC_MODE_INTER_MV_LAST:
+ {
mbmv[0]=last_mv[0][0];
mbmv[1]=last_mv[0][1];
- }break;
- case OC_MODE_INTER_MV_LAST2:{
+ }
+ break;
+ case OC_MODE_INTER_MV_LAST2:
+ {
mbmv[0]=last_mv[1][0];
mbmv[1]=last_mv[1][1];
last_mv[1][0]=last_mv[0][0];
last_mv[1][1]=last_mv[0][1];
last_mv[0][0]=mbmv[0];
last_mv[0][1]=mbmv[1];
- }break;
- case OC_MODE_GOLDEN_MV:{
+ }
+ break;
+ case OC_MODE_GOLDEN_MV:
+ {
mbmv[0]=(signed char)(*mv_comp_unpack)(&_dec->opb);
mbmv[1]=(signed char)(*mv_comp_unpack)(&_dec->opb);
- }break;
- default:mbmv[0]=mbmv[1]=0;break;
+
+#ifdef _TH_DEBUG_
+ if((j&0x7)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%+03d,%+03d ",mbmv[0],mbmv[1]);
+ j++;
+#endif
+
+ }
+ break;
+ default:
+ mbmv[0]=mbmv[1]=0;
+ break;
}
/*4MV mode fills in the fragments itself.
For all other modes we can use this common code.*/
@@ -704,6 +842,9 @@
}
}
}
+
+ TH_DEBUG("\n}\n");
+
}
static void oc_dec_block_qis_unpack(oc_dec_ctx *_dec){
@@ -1033,22 +1174,28 @@
/*Tokens describing the DCT coefficients that belong to each fragment are
stored in the bitstream grouped by coefficient, not by fragment.
+
This means that we either decode all the tokens in order, building up a
separate coefficient list for each fragment as we go, and then go back and
do the iDCT on each fragment, or we have to create separate lists of tokens
for each coefficient, so that we can pull the next token required off the
head of the appropriate list when decoding a specific fragment.
+
The former was VP3's choice, and it meant 2*w*h extra storage for all the
decoded coefficient values.
+
We take the second option, which lets us store just one or three bytes per
token (generally far fewer than the number of coefficients, due to EOB
tokens and zero runs), and which requires us to only maintain a counter for
each of the 64 coefficients, instead of a counter for every fragment to
determine where the next token goes.
+
Actually, we use 3 counters per coefficient, one for each color plane, so we
can decode all color planes simultaneously.
- This lets us color conversion, etc., be done as soon as a full MCU (one or
+
+ This lets color conversion, etc., be done as soon as a full MCU (one or
two super block rows) is decoded, while the image data is still in cache.*/
+
static void oc_dec_residual_tokens_unpack(oc_dec_ctx *_dec){
static const int OC_HUFF_LIST_MAX[5]={1,6,15,28,64};
long val;
@@ -1423,6 +1570,9 @@
for(fragy=fragy0;fragy<fragy_end;fragy++){
for(fragx=0;fragx<fplane->nhfrags;fragx++,frag++){
if(!frag->coded)continue;
+#ifdef _TH_DEBUG_
+ frag->quant[0] = frag->dc; /* stash un-predicted dc for debug output */
+#endif
pred_last[OC_FRAME_FOR_MODE[frag->mbmode]]=frag->dc+=
oc_frag_pred_dc(frag,fplane,fragx,fragy,pred_last);
ncoded_fragis++;
@@ -1939,6 +2089,7 @@
/*A completely empty packet indicates a dropped frame and is treated exactly
like an inter frame with no coded blocks.
Only proceed if we have a non-empty packet.*/
+
if(_op->bytes!=0){
oc_dec_pipeline_state pipe;
th_ycbcr_buffer stripe_buf;
@@ -1985,14 +2136,14 @@
if(_dec->state.frame_type==OC_INTRA_FRAME){
oc_dec_mark_all_intra(_dec);
_dec->state.keyframe_num=_dec->state.curframe_num;
- }
- else{
+ }else{
oc_dec_coded_flags_unpack(_dec);
oc_dec_mb_modes_unpack(_dec);
oc_dec_mv_unpack_and_frag_modes_fill(_dec);
}
oc_dec_block_qis_unpack(_dec);
oc_dec_residual_tokens_unpack(_dec);
+
/*Update granule position.
This must be done before the striped decode callbacks so that the
application knows what to do with the frame data.*/
@@ -2102,6 +2253,78 @@
}
notstart=1;
}
+
+#ifdef _TH_DEBUG_
+ {
+
+ int x,y,i,j,k,l;
+ int w = _dec->state.info.frame_width;
+ int h = _dec->state.info.frame_height;
+
+ /* dump fragment DCT components */
+ i=0;
+ for(y=0;y<(h>>3);y++){
+ for(x=0;x<(w>>3);x++,i++){
+ TH_DEBUG("DCT Y [%d][%d] = {",x,y);
+ if(!_dec->state.frags[i].coded)
+ TH_DEBUG(" not coded }\n");
+ else{
+ l=0;
+ for(j=0;j<8;j++){
+ TH_DEBUG("\n ");
+ for(k=0;k<8;k++,l++)
+ TH_DEBUG("%d:%d:%d ",
+ _dec->state.frags[i].quant[l],
+ _dec->state.frags[i].freq[l],
+ _dec->state.frags[i].time[l]);
+ }
+ TH_DEBUG(" }\n");
+ }
+ }
+ }
+
+ for(y=0;y<(h>>4);y++){
+ for(x=0;x<(w>>4);x++,i++){
+ TH_DEBUG("DCT U [%d][%d] = {",x,y);
+ if(!_dec->state.frags[i].coded)
+ TH_DEBUG(" not coded }\n");
+ else{
+ l=0;
+ for(j=0;j<8;j++){
+ TH_DEBUG("\n ");
+ for(k=0;k<8;k++,l++)
+ TH_DEBUG("%d:%d:%d ",
+ _dec->state.frags[i].quant[l],
+ _dec->state.frags[i].freq[l],
+ _dec->state.frags[i].time[l]);
+ }
+ TH_DEBUG(" }\n");
+ }
+ }
+ }
+
+ for(y=0;y<(h>>4);y++){
+ for(x=0;x<(w>>4);x++,i++){
+ TH_DEBUG("DCT V [%d][%d] = {",x,y);
+ if(!_dec->state.frags[i].coded)
+ TH_DEBUG(" not coded }\n");
+ else{
+ l=0;
+ for(j=0;j<8;j++){
+ TH_DEBUG("\n ");
+ for(k=0;k<8;k++,l++)
+ TH_DEBUG("%d:%d:%d ",
+ _dec->state.frags[i].quant[l],
+ _dec->state.frags[i].freq[l],
+ _dec->state.frags[i].time[l]);
+ }
+ TH_DEBUG(" }\n");
+ }
+ }
+ }
+ }
+#endif
+
/*Finish filling in the reference frame borders.*/
for(pli=0;pli<3;pli++)oc_state_borders_fill_caps(&_dec->state,refi,pli);
/*Update the reference frame indices.*/
Modified: trunk/theora/lib/dec/internal.c
===================================================================
--- trunk/theora/lib/dec/internal.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/dec/internal.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -61,22 +61,22 @@
/*The predictor frame to use for each macro block mode.*/
const int OC_FRAME_FOR_MODE[8]={
+ /*OC_MODE_INTER_NOMV*/
+ OC_FRAME_PREV,
/*OC_MODE_INTRA*/
OC_FRAME_SELF,
- /*OC_MODE_INTER_NOMV*/
- OC_FRAME_PREV,
/*OC_MODE_INTER_MV*/
OC_FRAME_PREV,
/*OC_MODE_INTER_MV_LAST*/
OC_FRAME_PREV,
/*OC_MODE_INTER_MV_LAST2*/
OC_FRAME_PREV,
- /*OC_MODE_INTER_MV_FOUR*/
- OC_FRAME_PREV,
/*OC_MODE_GOLDEN*/
OC_FRAME_GOLD,
/*OC_MODE_GOLDEN_MV*/
OC_FRAME_GOLD,
+ /*OC_MODE_INTER_MV_FOUR*/
+ OC_FRAME_PREV,
};
/*A map from physical macro block ordering to bitstream macro block
Modified: trunk/theora/lib/dec/quant.c
===================================================================
--- trunk/theora/lib/dec/quant.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/dec/quant.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -19,6 +19,7 @@
#include <string.h>
#include <ogg/ogg.h>
#include "quant.h"
+#include "decint.h"
unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2};
unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2};
@@ -129,4 +130,24 @@
}
}
}
+
+#ifdef _TH_DEBUG_
+ int i, j, k, l;
+ /* dump the calculated quantizer tables */
+ for(i=0;i<2;i++){
+ for(j=0;j<3;j++){
+ for(k=0;k<64;k++){
+ TH_DEBUG("quantizer table [%s][%s][Q%d] = {",
+ (i==0?"intra":"inter"),(j==0?"Y":(j==1?"U":"V")),k);
+ for(l=0;l<64;l++){
+ if((l&7)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%4d ",_dequant[i][j][k][l]);
+ }
+ TH_DEBUG("}\n");
+ }
+ }
+ }
+#endif
+
}
Modified: trunk/theora/lib/dec/quant.h
===================================================================
--- trunk/theora/lib/dec/quant.h 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/dec/quant.h 2007-10-28 23:43:27 UTC (rev 14059)
@@ -40,6 +40,7 @@
void oc_dequant_tables_init(oc_quant_table *_dequant[2][3],
- int _pp_dc_scale[64],const th_quant_info *_qinfo);
+ int _pp_dc_scale[64],
+ const th_quant_info *_qinfo);
#endif
Modified: trunk/theora/lib/dec/state.c
===================================================================
--- trunk/theora/lib/dec/state.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/dec/state.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -800,16 +800,16 @@
return 1;
}
-void oc_state_frag_recon(oc_theora_state *_state,const oc_fragment *_frag,
+void oc_state_frag_recon(oc_theora_state *_state, oc_fragment *_frag,
int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]){
_state->opt_vtable.state_frag_recon(_state,_frag,_pli,_dct_coeffs,
_last_zzi,_ncoefs,_dc_iquant,_ac_iquant);
}
-void oc_state_frag_recon_c(oc_theora_state *_state,const oc_fragment *_frag,
+void oc_state_frag_recon_c(oc_theora_state *_state, oc_fragment *_frag,
int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
- ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]){
+ ogg_uint16_t _dc_iquant, const ogg_uint16_t _ac_iquant[64]){
ogg_int16_t dct_buf[64];
ogg_int16_t res_buf[64];
int dst_framei;
@@ -845,10 +845,36 @@
ogg_int16_t p;
/*Why is the iquant product rounded in this case and no others?
Who knows.*/
+
p=(ogg_int16_t)((ogg_int32_t)_frag->dc*_dc_iquant+15>>5);
for(ci=0;ci<64;ci++)res_buf[ci]=p;
+
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ _frag->freq[0] = _frag->dc*_dc_iquant;
+ _frag->time[0] = p;
+ for(i=1;i<64;i++){
+ _frag->quant[i] = 0;
+ _frag->freq[i] = 0;
+ _frag->time[i] = p;
+ }
+ }
+#endif
+
}
else{
+
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ for(i=1;i<_ncoefs;i++)
+ _frag->quant[i] = _dct_coeffs[i];
+ for(;i<64;i++)
+ _frag->quant[i] = 0;
+ }
+#endif
+
/*First, dequantize the coefficients.*/
dct_buf[0]=(ogg_int16_t)((ogg_int32_t)_frag->dc*_dc_iquant);
for(zzi=1;zzi<_ncoefs;zzi++){
@@ -856,6 +882,21 @@
ci=OC_FZIG_ZAG[zzi];
dct_buf[ci]=(ogg_int16_t)((ogg_int32_t)_dct_coeffs[zzi]*_ac_iquant[ci]);
}
+
+#ifdef _TH_DEBUG_
+ for(;zzi<64;zzi++){
+ int ci;
+ ci=OC_FZIG_ZAG[zzi];
+ dct_buf[ci]=0;
+ }
+
+ {
+ int i;
+ for(i=0;i<64;i++)
+ _frag->freq[i] = dct_buf[i];
+ }
+#endif
+
/*Then, fill in the remainder of the coefficients with 0's, and perform
the iDCT.*/
if(_last_zzi<10){
@@ -866,6 +907,15 @@
for(;zzi<64;zzi++)dct_buf[OC_FZIG_ZAG[zzi]]=0;
oc_idct8x8_c(res_buf,dct_buf);
}
+
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ for(i=0;i<64;i++)
+ _frag->time[i] = res_buf[i];
+ }
+#endif
+
}
/*Fill in the target buffer.*/
dst_framei=_state->ref_frame_idx[OC_FRAME_SELF];
Modified: trunk/theora/lib/enc/block_inline.h
===================================================================
--- trunk/theora/lib/enc/block_inline.h 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/block_inline.h 2007-10-28 23:43:27 UTC (rev 14059)
@@ -31,7 +31,6 @@
return BlockMap[SB][MBOrderMap[MB]][BlockOrderMap1[MB][B]];
}
-
static ogg_int32_t QuadMapToMBTopLeft( ogg_int32_t (*BlockMap)[4][4],
ogg_uint32_t SB, ogg_uint32_t MB ){
return BlockMap[SB][MBOrderMap[MB]][0];
Modified: trunk/theora/lib/enc/blockmap.c
===================================================================
--- trunk/theora/lib/enc/blockmap.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/blockmap.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -97,4 +97,3 @@
CreateMapping ( BlockMap, YSuperBlocks + UVSuperBlocks, (HFrags*VFrags*5)/4,
HFrags/2, VFrags/2 );
}
-
Modified: trunk/theora/lib/enc/codec_internal.h
===================================================================
--- trunk/theora/lib/enc/codec_internal.h 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/codec_internal.h 2007-10-28 23:43:27 UTC (rev 14059)
@@ -356,8 +356,6 @@
ogg_uint32_t UVSBCols; /* Number of cols of SuperBlocks in a
U or V frame */
- ogg_uint32_t YMacroBlocks; /* Number of Macro-Blocks in Y component */
- ogg_uint32_t UVMacroBlocks; /* Number of Macro-Blocks in U/V component */
ogg_uint32_t MacroBlocks; /* Total number of Macro-Blocks */
/**********************************************************************/
@@ -381,7 +379,7 @@
skipped */
ogg_int32_t *CodedBlockList; /* A list of fragment indices for
coded blocks. */
- MOTION_VECTOR *FragMVect; /* fragment motion vectors */
+ MOTION_VECTOR *FragMVect; /* Frag motion vectors */
ogg_uint32_t *FragTokenCounts; /* Number of tokens per fragment */
ogg_uint32_t (*TokenList)[128]; /* Fragment Token Pointers */
@@ -467,28 +465,27 @@
/* Dequantiser and rounding tables */
ogg_uint16_t *QThreshTable;
-
- Q_LIST_ENTRY *dequant_Y_coeffs;
- Q_LIST_ENTRY *dequant_U_coeffs;
- Q_LIST_ENTRY *dequant_V_coeffs;
- Q_LIST_ENTRY *dequant_InterY_coeffs;
- Q_LIST_ENTRY *dequant_InterU_coeffs;
- Q_LIST_ENTRY *dequant_InterV_coeffs;
+ Q_LIST_ENTRY dequant_Y_coeffs[64];
+ Q_LIST_ENTRY dequant_U_coeffs[64];
+ Q_LIST_ENTRY dequant_V_coeffs[64];
+ Q_LIST_ENTRY dequant_InterY_coeffs[64];
+ Q_LIST_ENTRY dequant_InterU_coeffs[64];
+ Q_LIST_ENTRY dequant_InterV_coeffs[64];
+
Q_LIST_ENTRY *dequant_coeffs; /* currently active quantizer */
unsigned int zigzag_index[64];
- ogg_int32_t quant_Y_coeffs[64];
- ogg_int32_t quant_UV_coeffs[64];
-
HUFF_ENTRY *HuffRoot_VP3x[NUM_HUFF_TABLES];
ogg_uint32_t *HuffCodeArray_VP3x[NUM_HUFF_TABLES];
unsigned char *HuffCodeLengthArray_VP3x[NUM_HUFF_TABLES];
const unsigned char *ExtraBitLengths_VP3x;
- th_quant_info quant_info;
- ogg_uint16_t quant_tables[2][3][64][64];
+ th_quant_info quant_info;
+ oc_quant_tables quant_tables[2][3];
/* Quantiser and rounding tables */
+ /* this is scheduled to be replaced a new mechanism
+ that will simply reuse the dequantizer information. */
ogg_int32_t fp_quant_Y_coeffs[64]; /* used in reiniting quantizers */
ogg_int32_t fp_quant_U_coeffs[64];
ogg_int32_t fp_quant_V_coeffs[64];
@@ -524,6 +521,15 @@
DspFunctions dsp; /* Selected functions for this platform */
+#ifdef _TH_DEBUG_
+ Q_LIST_ENTRY (*QFragQUAN)[64]; /* Fragment Coefficients
+ Array Pointers */
+ Q_LIST_ENTRY (*QFragFREQ)[64]; /* Fragment Coefficients
+ Array Pointers */
+ Q_LIST_ENTRY (*QFragTIME)[64]; /* Fragment Coefficients
+ Array Pointers */
+#endif
+
} PB_INSTANCE;
/* Encoder (Compressor) instance -- installed in a theora_state */
Modified: trunk/theora/lib/enc/dct_decode.c
===================================================================
--- trunk/theora/lib/enc/dct_decode.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/dct_decode.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -89,6 +89,15 @@
/* Set up pointer into the quantisation buffer. */
pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ for(i=0;i<64;i++)
+ pbi->QFragFREQ[FragmentNumber][dezigzag_index[i]]=
+ pbi->quantized_list[i] * pbi->dequant_coeffs[i];
+ }
+#endif
+
/* Invert quantisation and DCT to get pixel data. */
switch(pbi->FragCoefEOB[FragmentNumber]){
case 0:case 1:
@@ -104,6 +113,14 @@
dsp_IDctSlow(pbi->dsp, pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
}
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ for(i=0;i<64;i++)
+ pbi->QFragTIME[FragmentNumber][i]= pbi->ReconDataBuffer[i];
+ }
+#endif
+
/* Convert fragment number to a pixel offset in a reconstruction buffer. */
ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];
@@ -113,7 +130,7 @@
}
-static void ExpandBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber ){
+static void ExpandBlock ( PB_INSTANCE *pbi, ogg_int32_t FragmentNumber){
unsigned char *LastFrameRecPtr; /* Pointer into previous frame
reconstruction. */
unsigned char *LastFrameRecPtr2; /* Pointer into previous frame
@@ -172,6 +189,15 @@
/* Set up pointer into the quantisation buffer. */
pbi->quantized_list = &pbi->QFragData[FragmentNumber][0];
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ for(i=0;i<64;i++)
+ pbi->QFragFREQ[FragmentNumber][dezigzag_index[i]]=
+ pbi->quantized_list[i] * pbi->dequant_coeffs[i];
+ }
+#endif
+
/* Invert quantisation and DCT to get pixel data. */
switch(pbi->FragCoefEOB[FragmentNumber]){
case 0:case 1:
@@ -187,6 +213,14 @@
dsp_IDctSlow(pbi->dsp, pbi->quantized_list, pbi->dequant_coeffs, pbi->ReconDataBuffer );
}
+#ifdef _TH_DEBUG_
+ {
+ int i;
+ for(i=0;i<64;i++)
+ pbi->QFragTIME[FragmentNumber][i]= pbi->ReconDataBuffer[i];
+ }
+#endif
+
/* Convert fragment number to a pixel offset in a reconstruction buffer. */
ReconPixelIndex = pbi->recon_pixel_index_table[FragmentNumber];
@@ -1153,7 +1187,6 @@
/* Inverse DCT and reconstitute buffer in thisframe */
ExpandBlockA( pbi, i );
-
}
}
}
Modified: trunk/theora/lib/enc/dct_encode.c
===================================================================
--- trunk/theora/lib/enc/dct_encode.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/dct_encode.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -295,8 +295,7 @@
half pixel MC */
unsigned char *ReconPtr1; /* DCT reconstructed image pointers */
unsigned char *ReconPtr2; /* Pointer used in half pixel MC */
-
-
+
switch(MvDevisor) {
case 2:
MvShift = 1;
@@ -367,7 +366,7 @@
}
void TransformQuantizeBlock (CP_INSTANCE *cpi, ogg_int32_t FragIndex,
- ogg_uint32_t PixelsPerLine ) {
+ ogg_uint32_t PixelsPerLine) {
unsigned char *new_ptr1; /* Pointers into current frame */
unsigned char *old_ptr1; /* Pointers into old frame */
unsigned char *FiltPtr; /* Pointers to srf filtered pixels */
Modified: trunk/theora/lib/enc/encode.c
===================================================================
--- trunk/theora/lib/enc/encode.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/encode.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -28,10 +28,10 @@
#define HIGHBITDUPPED(X) (((ogg_int16_t) X) >> 15)
static ogg_uint32_t QuadCodeComponent ( CP_INSTANCE *cpi,
- ogg_uint32_t FirstSB,
- ogg_uint32_t SBRows,
- ogg_uint32_t SBCols,
- ogg_uint32_t PixelsPerLine ){
+ ogg_uint32_t FirstSB,
+ ogg_uint32_t SBRows,
+ ogg_uint32_t SBCols,
+ ogg_uint32_t PixelsPerLine){
ogg_int32_t FragIndex; /* Fragment number */
ogg_uint32_t MB, B; /* Macro-Block, Block indices */
@@ -45,10 +45,11 @@
/* actually transform and quantize the image now that we've decided
on the modes Parse in quad-tree ordering */
- SB=FirstSB;
for ( SBrow=0; SBrow<SBRows; SBrow++ ) {
for ( SBcol=0; SBcol<SBCols; SBcol++ ) {
/* Check its four Macro-Blocks */
+ /* 'Macro-Block' is a misnomer in the chroma planes; this is
+ really just a Hilbert curve iterator */
for ( MB=0; MB<4; MB++ ) {
if ( QuadMapToMBTopLeft(cpi->pb.BlockMap,SB,MB) >= 0 ) {
@@ -61,6 +62,7 @@
/* Does Block lie in frame: */
if ( FragIndex >= 0 ) {
+
/* In Frame: Is it coded: */
if ( cpi->pb.display_fragments[FragIndex] ) {
@@ -153,8 +155,6 @@
/* Add the DC huffman table choice to the bitstream */
oggpackB_write( opb, DcHuffChoice[1], DC_HUFF_CHOICE_BITS );
- TH_DEBUG("dc hufftables = %d %d\n",(int)DcHuffChoice[0],(int)DcHuffChoice[1]);
-
/* Encode the token list */
for ( i = 0; i < cpi->OptimisedTokenCount; i++ ) {
@@ -181,6 +181,7 @@
oggpackB_write( opb, ExtraBitsToken,
(ogg_uint32_t)cpi->pb.ExtraBitLengths_VP3x[Token] );
}
+
}
/* Reset the count of second order optimised tokens */
@@ -341,9 +342,10 @@
/* If the chosen schems is scheme 0 send details of the mode
frequency order */
if ( BestScheme == 0 ) {
- for ( j = 0; j < MAX_MODES; j++ )
+ for ( j = 0; j < MAX_MODES; j++ ){
/* Note that the last two entries are implicit */
oggpackB_write( opb, BestModeSchemes[j], (ogg_uint32_t)MODE_BITS );
+ }
SchemeList = BestModeSchemes;
}
else {
@@ -353,19 +355,35 @@
/* Are we using one of the alphabet based schemes or the fallback scheme */
if ( BestScheme < (MODE_METHODS - 1)) {
/* Pack and encode the Mode list */
- for ( i = 0; i < cpi->ModeListCount; i++ ) {
+ for ( i = 0; i < cpi->ModeListCount; i++) {
/* Add the appropriate mode entropy token. */
ModeIndex = SchemeList[cpi->ModeList[i]];
oggpackB_write( opb, ModeBitPatterns[ModeIndex],
- (ogg_uint32_t)ModeBitLengths[ModeIndex] );
+ (ogg_uint32_t)ModeBitLengths[ModeIndex] );
}
}else{
/* Fall back to MODE_BITS per entry */
- for ( i = 0; i < cpi->ModeListCount; i++ ) {
+ for ( i = 0; i < cpi->ModeListCount; i++)
/* Add the appropriate mode entropy token. */
- oggpackB_write( opb, cpi->ModeList[i], MODE_BITS );
- }
+ oggpackB_write( opb, cpi->ModeList[i], MODE_BITS );
}
+
+#ifdef _TH_DEBUG_
+ TH_DEBUG("mode encode scheme = %d\n",(int)BestScheme);
+ if ( BestScheme == 0 ) {
+ TH_DEBUG("mode scheme list = { ");
+ for ( j = 0; j < MAX_MODES; j++ )
+ TH_DEBUG("%d ",(int)BestModeSchemes[j]);
+ TH_DEBUG("}\n");
+ }
+ TH_DEBUG("mode list = { ");
+ for ( i = 0; i < cpi->ModeListCount; i++) {
+ if((i&0x1f)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%d ",cpi->ModeList[i]);
+ }
+ TH_DEBUG("\n}\n");
+#endif
}
static void PackMotionVectors (CP_INSTANCE *cpi) {
@@ -403,6 +421,16 @@
oggpackB_write( opb, MvPatternPtr[cpi->MVList[i].y],
(ogg_uint32_t)MvBitsPtr[cpi->MVList[i].y] );
}
+
+#ifdef _TH_DEBUG_
+ TH_DEBUG("motion vectors = {");
+ for ( i = 0; i < (ogg_int32_t)cpi->MvListCount; i++ ) {
+ if((i&0x7)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%+03d,%+03d ",cpi->MVList[i].x,cpi->MVList[i].y);
+ }
+ TH_DEBUG("\n}\n");
+#endif
}
static void PackEOBRun( CP_INSTANCE *cpi) {
@@ -562,8 +590,6 @@
ogg_int32_t FragIndex;
ogg_uint32_t HuffIndex; /* Index to group of tables used to code a token */
- TH_DEBUG("\n>>>> beginning frame %d\n\n",dframe);
-
/* Reset the count of second order optimised tokens */
cpi->OptimisedTokenCount = 0;
@@ -807,6 +833,7 @@
if( cpi->pb.display_fragments[i] ||
(GetFrameType(&cpi->pb) == KEY_FRAME) ) {
/* Type of Fragment */
+
WhichFrame = Mode2Frame[cpi->pb.FragCodingMethod[i]];
/* Check Borderline Cases */
@@ -878,6 +905,17 @@
}
}
+#ifdef _TH_DEBUG_
+ {
+ int j;
+ for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
+ FragIndex = cpi->pb.CodedBlockList[i];
+ for(j=0;j<64;j++)
+ cpi->pb.QFragQUAN[FragIndex][j] = cpi->pb.QFragData[FragIndex][j];
+ }
+ }
+#endif
+
/* Pack DC tokens and adjust the ones we couldn't predict 2d */
for ( i = 0; i < cpi->pb.CodedBlockIndex; i++ ) {
/* Get the linear index for the current coded fragment. */
@@ -886,7 +924,6 @@
}
-
/* Bit pack the video data data */
PackCodedVideo(cpi);
@@ -896,6 +933,74 @@
/* Reconstruct the reference frames */
ReconRefFrames(&cpi->pb);
+#ifdef _TH_DEBUG_
+ {
+ int x,y,i,j,k,l;
+
+ /* dump fragment DCT components */
+ i=0;
+ for(y=0;y<cpi->pb.VFragments;y++){
+ for(x=0;x<cpi->pb.HFragments;x++,i++){
+ TH_DEBUG("DCT Y [%d][%d] = {",x,y);
+ if ( !cpi->pb.display_fragments[i] )
+ TH_DEBUG(" not coded }\n");
+ else{
+ l=0;
+ for(j=0;j<8;j++){
+ TH_DEBUG("\n ");
+ for(k=0;k<8;k++,l++)
+ TH_DEBUG("%d:%d:%d ",
+ cpi->pb.QFragQUAN[i][l],
+ cpi->pb.QFragFREQ[i][l],
+ cpi->pb.QFragTIME[i][l]);
+ }
+ TH_DEBUG(" }\n");
+ }
+ }
+ }
+
+ for(y=0;y<(cpi->pb.VFragments>>1);y++){
+ for(x=0;x<(cpi->pb.HFragments>>1);x++,i++){
+ TH_DEBUG("DCT U [%d][%d] = {",x,y);
+ if ( !cpi->pb.display_fragments[i] )
+ TH_DEBUG(" not coded }\n");
+ else{
+ l=0;
+ for(j=0;j<8;j++){
+ TH_DEBUG("\n ");
+ for(k=0;k<8;k++,l++)
+ TH_DEBUG("%d:%d:%d ",
+ cpi->pb.QFragQUAN[i][l],
+ cpi->pb.QFragFREQ[i][l],
+ cpi->pb.QFragTIME[i][l]);
+ }
+ TH_DEBUG(" }\n");
+ }
+ }
+ }
+
+ for(y=0;y<(cpi->pb.VFragments>>1);y++){
+ for(x=0;x<(cpi->pb.HFragments>>1);x++,i++){
+ TH_DEBUG("DCT V [%d][%d] = {",x,y);
+ if ( !cpi->pb.display_fragments[i] )
+ TH_DEBUG(" not coded }\n");
+ else{
+ l=0;
+ for(j=0;j<8;j++){
+ TH_DEBUG("\n ");
+ for(k=0;k<8;k++,l++)
+ TH_DEBUG("%d:%d:%d ",
+ cpi->pb.QFragQUAN[i][l],
+ cpi->pb.QFragFREQ[i][l],
+ cpi->pb.QFragTIME[i][l]);
+ }
+ TH_DEBUG(" }\n");
+ }
+ }
+ }
+ }
+#endif
+
UpdateFragQIndex(&cpi->pb);
/* Measure the inter reconstruction error for all the blocks that
@@ -944,7 +1049,6 @@
ogg_uint32_t SBcol; /* Super-Block row number */
ogg_uint32_t SB=0; /* Super-Block index, initialised to first of
this component */
-
ogg_uint32_t UVRow;
ogg_uint32_t UVColumn;
ogg_uint32_t UVFragOffset;
@@ -977,8 +1081,7 @@
cpi->pb.FragCodingMethod[cpi->pb.YPlaneFragments +
cpi->pb.UVPlaneFragments + UVFragOffset] =
cpi->MBCodingMode;
-
- }
+ }
}
/* Next Super-Block */
@@ -1356,7 +1459,7 @@
cpi->MBCodingMode = CODE_INTER_PLUS_MV;
SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&InterMVect);
+ VFragIndex,&InterMVect);
/* Update Prior last mv with last mv */
PriorLastInterMVect.x = LastInterMVect.x;
@@ -1372,7 +1475,7 @@
cpi->MBCodingMode = CODE_GOLDEN_MV;
SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&GFMVect);
+ VFragIndex,&GFMVect);
/* Note last inter GF MV for future use */
LastGFMVect.x = GFMVect.x;
@@ -1428,7 +1531,7 @@
cpi->MBCodingMode = CODE_INTRA;
SetMBMotionVectorsAndMode(cpi,YFragIndex,UFragIndex,
- VFragIndex,&ZeroVect);
+ VFragIndex,&ZeroVect);
}
@@ -1453,12 +1556,16 @@
ogg_uint32_t i;
oggpack_buffer *opb=cpi->oggbuffer;
+ TH_DEBUG("\n>>>> beginning frame %ld\n\n",dframe);
+
/* Output the frame type (base/key frame or inter frame) */
oggpackB_write( opb, cpi->pb.FrameType, 1 );
-
+ TH_DEBUG("frame type = video, %s\n",cpi->pb.FrameType?"predicted":"key");
+
/* Write out details of the current value of Q... variable resolution. */
for ( i = 0; i < Q_TABLE_SIZE; i++ ) {
if ( cpi->pb.ThisFrameQualityValue == cpi->pb.QThreshTable[i] ) {
+ TH_DEBUG("frame quality = { %d }\n",i);
oggpackB_write( opb, i, 6 );
break;
}
@@ -1475,11 +1582,8 @@
/* If the frame was a base frame then write out the frame dimensions. */
if ( cpi->pb.FrameType == KEY_FRAME ) {
- /* Key frame type / method */
- oggpackB_write( opb, cpi->pb.KeyFrameType, 1 );
-
- /* Spare configuration bits */
- oggpackB_write( opb, 0, 2 );
+ /* all bits reserved! */
+ oggpackB_write( opb, 0, 3 );
}
}
Modified: trunk/theora/lib/enc/encoder_lookup.h
===================================================================
--- trunk/theora/lib/enc/encoder_lookup.h 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/encoder_lookup.h 2007-10-28 23:43:27 UTC (rev 14059)
@@ -91,8 +91,8 @@
{ 2, 4, 1, 0, 3, 5, 6, 7 }, /* L M N P I G GM 4 */
/* No MV dominates */
- { 0, 4, 3, 1, 2, 5, 6, 7 }, /* N L P M I G GM 4 */
- { 0, 5, 4, 2, 3, 1, 6, 7 }, /* N G L P M I GM 4 */
+ { 0, 4, 3, 1, 2, 5, 6, 7 }, /* N L P M I G GM 4 */
+ { 0, 5, 4, 2, 3, 1, 6, 7 }, /* N G L P M I GM 4 */
};
Modified: trunk/theora/lib/enc/encoder_quant.c
===================================================================
--- trunk/theora/lib/enc/encoder_quant.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/encoder_quant.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -26,6 +26,14 @@
extern long dframe;
#endif
+#define OC_QUANT_MAX (1024<<2)
+//unsigned OC_DC_QUANT_MIN[2]={4<<2,8<<2};
+//unsigned OC_AC_QUANT_MIN[2]={2<<2,4<<2};
+#define OC_MAXI(_a,_b) ((_a)<(_b)?(_b):(_a))
+#define OC_MINI(_a,_b) ((_a)>(_b)?(_b):(_a))
+#define OC_CLAMPI(_a,_b,_c) (OC_MAXI(_a,OC_MINI(_b,_c)))
+
+
void WriteQTables(PB_INSTANCE *pbi,oggpack_buffer* _opb) {
th_quant_info *_qinfo = &pbi->quant_info;
@@ -125,16 +133,79 @@
oggpackB_write(_opb,indices[qti][pli][qri+1],nbits);
}
}
+}
+/* a copied/reconciled version of derf's theora-exp code; redundancy
+ should be eliminated at some point */
+void InitQTables( PB_INSTANCE *pbi ){
+ int qti; /* coding mode: intra or inter */
+ int pli; /* Y U V */
+ th_quant_info *qinfo = &pbi->quant_info;
+
+ pbi->QThreshTable = pbi->quant_info.ac_scale;
+
+ for(qti=0;qti<2;qti++){
+ for(pli=0;pli<3;pli++){
+ int qi; /* quality index */
+ int qri; /* range iterator */
+
+ for(qi=0,qri=0; qri<=qinfo->qi_ranges[qti][pli].nranges; qri++){
+ th_quant_base base;
+
+ ogg_uint32_t q;
+ int qi_start;
+ int qi_end;
+ int ci;
+ memcpy(base,qinfo->qi_ranges[qti][pli].base_matrices[qri],
+ sizeof(base));
+
+ qi_start=qi;
+ if(qri==qinfo->qi_ranges[qti][pli].nranges)
+ qi_end=qi+1;
+ else
+ qi_end=qi+qinfo->qi_ranges[qti][pli].sizes[qri];
+
+ /* Iterate over quality indicies in this range */
+ for(;;){
+
+ /*Scale DC the coefficient from the proper table.*/
+ q=((ogg_uint32_t)qinfo->dc_scale[qi]*base[0]/100)<<2;
+ q=OC_CLAMPI(OC_DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
+ pbi->quant_tables[qti][pli][qi][0]=(ogg_uint16_t)q;
+
+ /*Now scale AC coefficients from the proper table.*/
+ for(ci=1;ci<64;ci++){
+ q=((ogg_uint32_t)qinfo->ac_scale[qi]*base[ci]/100)<<2;
+ q=OC_CLAMPI(OC_AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
+ pbi->quant_tables[qti][pli][qi][ci]=(ogg_uint16_t)q;
+ }
+
+ if(++qi>=qi_end)break;
+
+ /*Interpolate the next base matrix.*/
+ for(ci=0;ci<64;ci++){
+ base[ci]=(unsigned char)
+ ((2*((qi_end-qi)*qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
+ (qi-qi_start)*qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
+ +qinfo->qi_ranges[qti][pli].sizes[qri])/
+ (2*qinfo->qi_ranges[qti][pli].sizes[qri]));
+ }
+ }
+ }
+ }
+ }
+
#ifdef _TH_DEBUG_
- /* dump the tables */
+ int i, j, k, l;
+
+ /* dump the static tables */
{
int i, j, k, l, m;
TH_DEBUG("loop filter limits = {");
for(i=0;i<64;){
TH_DEBUG("\n ");
for(j=0;j<16;i++,j++)
- TH_DEBUG("%3d ",_qinfo->loop_filter_limits[i]);
+ TH_DEBUG("%3d ",qinfo->loop_filter_limits[i]);
}
TH_DEBUG("\n}\n\n");
@@ -142,7 +213,7 @@
for(i=0;i<64;){
TH_DEBUG("\n ");
for(j=0;j<16;i++,j++)
- TH_DEBUG("%3d ",_qinfo->ac_scale[i]);
+ TH_DEBUG("%3d ",qinfo->ac_scale[i]);
}
TH_DEBUG("\n}\n\n");
@@ -150,7 +221,7 @@
for(i=0;i<64;){
TH_DEBUG("\n ");
for(j=0;j<16;i++,j++)
- TH_DEBUG("%3d ",_qinfo->dc_scale[i]);
+ TH_DEBUG("%3d ",qinfo->dc_scale[i]);
}
TH_DEBUG("\n}\n\n");
@@ -161,7 +232,7 @@
{"inter Y bases","inter U bases", "inter V bases"}
};
- th_quant_ranges *r = &_qinfo->qi_ranges[k][l];
+ th_quant_ranges *r = &qinfo->qi_ranges[k][l];
TH_DEBUG("%s = {\n",name[k][l]);
TH_DEBUG(" ranges = %d\n",r->nranges);
TH_DEBUG(" intervals = { ");
@@ -181,19 +252,24 @@
TH_DEBUG("\n }\n");
}
}
-
+
+ /* dump the calculated quantizer tables */
+ for(i=0;i<2;i++){
+ for(j=0;j<3;j++){
+ for(k=0;k<64;k++){
+ TH_DEBUG("quantizer table [%s][%s][Q%d] = {",
+ (i==0?"intra":"inter"),(j==0?"Y":(j==1?"U":"V")),k);
+ for(l=0;l<64;l++){
+ if((l&7)==0)
+ TH_DEBUG("\n ");
+ TH_DEBUG("%4d ",pbi->quant_tables[i][j][k][l]);
+ }
+ TH_DEBUG("}\n");
+ }
+ }
+ }
#endif
-}
-
-/* Initialize custom qtables using the VP31 values.
- Someday we can change the quant tables to be adaptive, or just plain
- better. */
-void InitQTables( PB_INSTANCE *pbi ){
-
- pbi->QThreshTable = pbi->quant_info.ac_scale;
-
- quant_tables_init(pbi, &pbi->quant_info);
}
static void BuildZigZagIndex(PB_INSTANCE *pbi){
@@ -206,97 +282,46 @@
}
}
-/* this is a butchered version of derf's theora-exp code */
-void quant_tables_init(PB_INSTANCE *pbi, const th_quant_info *qinfo){
- int qti;
- int pli;
- for(qti=0;qti<2;qti++)for(pli=0;pli<3;pli++){
- int qi;
- int qri;
- /*These simple checks help us improve cache coherency later.*/
- /*if(pli>0&&memcmp(_qinfo->qi_ranges[qti]+pli-1,
- _qinfo->qi_ranges[qti]+pli,sizeof(_qinfo->qi_ranges[qti][pli]))==0){
- pbi->quant_tables[qti][pli]=pbi->quant_tables[qti][pli-1];
- continue;
- }
- if(qti>0&&memcmp(_qinfo->qi_ranges[qti-1]+pli,
- _qinfo->qi_ranges[qti]+pli,sizeof(_qinfo->qi_ranges[qti][pli]))==0){
- pbi->quant_tables[qti][pli]=pbi->quant_tables[qti-1][pli];
- continue;
- }*/
- for(qi=qri=0;qri<=qinfo->qi_ranges[qti][pli].nranges;qri++){
- int i;
- ogg_uint16_t base[64];
- int qi_start;
- int qi_end;
- int ci;
-
- for(i = 0; i < 64; i++)
- base[i] = qinfo->qi_ranges[qti][pli].base_matrices[qri][i];
-
- qi_start=qi;
- if(qri==qinfo->qi_ranges[qti][pli].nranges)qi_end=qi+1;
- else qi_end=qi+qinfo->qi_ranges[qti][pli].sizes[qri];
- for(;;){
-
- memcpy(pbi->quant_tables[qti][pli][qi], base, sizeof(base));
-
- if(++qi>=qi_end)break;
- /*Interpolate the next base matrix.*/
- for(ci=0;ci<64;ci++){
- base[ci]=(unsigned char)(
- (2*((qi_end-qi)*qinfo->qi_ranges[qti][pli].base_matrices[qri][ci]+
- (qi-qi_start)*qinfo->qi_ranges[qti][pli].base_matrices[qri+1][ci])
- +qinfo->qi_ranges[qti][pli].sizes[qri])/
- (2*qinfo->qi_ranges[qti][pli].sizes[qri]));
- }
- }
- }
- }
-}
-
static void init_quantizer ( CP_INSTANCE *cpi,
- ogg_uint32_t scale_factor,
- unsigned char QIndex ){
- int i;
- double ZBinFactor;
- double RoundingFactor;
-
- double temp_fp_quant_coeffs;
- double temp_fp_quant_round;
- double temp_fp_ZeroBinSize;
- PB_INSTANCE *pbi = &cpi->pb;
-
-
- const ogg_uint16_t * temp_Y_coeffs;
- const ogg_uint16_t * temp_U_coeffs;
- const ogg_uint16_t * temp_V_coeffs;
- const ogg_uint16_t * temp_Inter_Y_coeffs;
- const ogg_uint16_t * temp_Inter_U_coeffs;
- const ogg_uint16_t * temp_Inter_V_coeffs;
- const ogg_uint16_t * temp_DcScaleFactorTable;
-
- /* Notes on setup of quantisers. The initial multiplication by
+ unsigned char QIndex ){
+ int i;
+ double ZBinFactor;
+ double RoundingFactor;
+
+ double temp_fp_quant_coeffs;
+ double temp_fp_quant_round;
+ double temp_fp_ZeroBinSize;
+ PB_INSTANCE *pbi = &cpi->pb;
+
+
+ const ogg_uint16_t * temp_Y_coeffs;
+ const ogg_uint16_t * temp_U_coeffs;
+ const ogg_uint16_t * temp_V_coeffs;
+ const ogg_uint16_t * temp_Inter_Y_coeffs;
+ const ogg_uint16_t * temp_Inter_U_coeffs;
+ const ogg_uint16_t * temp_Inter_V_coeffs;
+ ogg_uint16_t scale_factor = cpi->pb.quant_info.ac_scale[QIndex];
+
+ /* Notes on setup of quantisers. The initial multiplication by
the scale factor is done in the ogg_int32_t domain to insure that the
precision in the quantiser is the same as in the inverse
quantiser where all calculations are integer. The "<< 2" is a
normalisation factor for the forward DCT transform. */
-
- temp_Y_coeffs = pbi->quant_tables[0][0][QIndex];
- temp_U_coeffs = pbi->quant_tables[0][1][QIndex];
- temp_V_coeffs = pbi->quant_tables[0][2][QIndex];
- temp_Inter_Y_coeffs = pbi->quant_tables[1][0][QIndex];
- temp_Inter_U_coeffs = pbi->quant_tables[1][1][QIndex];
- temp_Inter_V_coeffs = pbi->quant_tables[1][2][QIndex];
- temp_DcScaleFactorTable = pbi->quant_info.dc_scale;
-
- ZBinFactor = 0.9;
-
- switch(cpi->pb.info.sharpness){
- case 0:
- ZBinFactor = 0.65;
- if ( scale_factor <= 50 )
- RoundingFactor = 0.49;
+
+ temp_Y_coeffs = pbi->quant_tables[0][0][QIndex];
+ temp_U_coeffs = pbi->quant_tables[0][1][QIndex];
+ temp_V_coeffs = pbi->quant_tables[0][2][QIndex];
+ temp_Inter_Y_coeffs = pbi->quant_tables[1][0][QIndex];
+ temp_Inter_U_coeffs = pbi->quant_tables[1][1][QIndex];
+ temp_Inter_V_coeffs = pbi->quant_tables[1][2][QIndex];
+
+ ZBinFactor = 0.9;
+
+ switch(cpi->pb.info.sharpness){
+ case 0:
+ ZBinFactor = 0.65;
+ if ( scale_factor <= 50 )
+ RoundingFactor = 0.499;
else
RoundingFactor = 0.46;
break;
@@ -318,186 +343,113 @@
}
/* Use fixed multiplier for intra Y DC */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(temp_DcScaleFactorTable[QIndex] * temp_Y_coeffs[0])/100) << 2);
- if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2 )
- temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;
-
+ temp_fp_quant_coeffs = temp_Y_coeffs[0];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Y_round[0] = (ogg_int32_t) (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Y[0] = (ogg_int32_t) (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Y_coeffs[0] = (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Intra U */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(temp_DcScaleFactorTable[QIndex] * temp_U_coeffs[0])/100) << 2);
- if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2)
- temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;
-
+ temp_fp_quant_coeffs = temp_U_coeffs[0];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_U_round[0] = (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_U[0] = (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_U_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Intra V */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(temp_DcScaleFactorTable[QIndex] * temp_V_coeffs[0])/100) << 2);
- if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 2)
- temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 2;
-
+ temp_fp_quant_coeffs = temp_V_coeffs[0];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_V_round[0] = (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_V[0] = (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_V_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Inter Y */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(temp_DcScaleFactorTable[QIndex] * temp_Inter_Y_coeffs[0])/100) << 2);
- if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
- temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;
-
+ temp_fp_quant_coeffs = temp_Inter_Y_coeffs[0];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Inter_Y_round[0]= (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Inter_Y[0]= (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Inter_Y_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Inter U */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(temp_DcScaleFactorTable[QIndex] * temp_Inter_U_coeffs[0])/100) << 2);
- if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
- temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;
-
+ temp_fp_quant_coeffs = temp_Inter_U_coeffs[0];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Inter_U_round[0]= (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Inter_U[0]= (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Inter_U_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Inter V */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(temp_DcScaleFactorTable[QIndex] * temp_Inter_V_coeffs[0])/100) << 2);
- if ( temp_fp_quant_coeffs < MIN_LEGAL_QUANT_ENTRY * 4)
- temp_fp_quant_coeffs = MIN_LEGAL_QUANT_ENTRY * 4;
-
+ temp_fp_quant_coeffs = temp_Inter_V_coeffs[0];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Inter_V_round[0]= (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Inter_V[0]= (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs= 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Inter_V_coeffs[0]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
for ( i = 1; i < 64; i++ ){
- /* now scale coefficients by required compression factor */
/* Intra Y */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(scale_factor * temp_Y_coeffs[i]) / 100 ) << 2 );
- if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY) )
- temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);
-
+ temp_fp_quant_coeffs = temp_Y_coeffs[i];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Y_round[i] = (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Y[i] = (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Y_coeffs[i] = (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Intra U */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(scale_factor * temp_U_coeffs[i]) / 100 ) << 2 );
- if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY))
- temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);
-
+ temp_fp_quant_coeffs = temp_U_coeffs[i];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_U_round[i] = (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_U[i] = (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_U_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Intra V */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(scale_factor * temp_V_coeffs[i]) / 100 ) << 2 );
- if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY))
- temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY);
-
+ temp_fp_quant_coeffs = temp_V_coeffs[i];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_V_round[i] = (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_V[i] = (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_V_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Inter Y */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(scale_factor * temp_Inter_Y_coeffs[i]) / 100 ) << 2 );
- if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
- temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);
-
+ temp_fp_quant_coeffs = temp_Inter_Y_coeffs[i];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Inter_Y_round[i]= (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Inter_Y[i]= (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Inter_Y_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Inter U */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(scale_factor * temp_Inter_U_coeffs[i]) / 100 ) << 2 );
- if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
- temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);
-
+ temp_fp_quant_coeffs = temp_Inter_U_coeffs[i];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Inter_U_round[i]= (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Inter_U[i]= (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Inter_U_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
/* Inter V */
- temp_fp_quant_coeffs =
- (((ogg_uint32_t)(scale_factor * temp_Inter_V_coeffs[i]) / 100 ) << 2 );
- if ( temp_fp_quant_coeffs < (MIN_LEGAL_QUANT_ENTRY * 2) )
- temp_fp_quant_coeffs = (MIN_LEGAL_QUANT_ENTRY * 2);
-
+ temp_fp_quant_coeffs = temp_Inter_V_coeffs[i];
temp_fp_quant_round = temp_fp_quant_coeffs * RoundingFactor;
pbi->fp_quant_Inter_V_round[i]= (0.5 + temp_fp_quant_round);
-
temp_fp_ZeroBinSize = temp_fp_quant_coeffs * ZBinFactor;
pbi->fp_ZeroBinSize_Inter_V[i]= (0.5 + temp_fp_ZeroBinSize);
-
temp_fp_quant_coeffs = 1.0 / temp_fp_quant_coeffs;
pbi->fp_quant_Inter_V_coeffs[i]= (0.5 + SHIFT16 * temp_fp_quant_coeffs);
@@ -590,27 +542,23 @@
}
static void init_dequantizer ( PB_INSTANCE *pbi,
- ogg_uint32_t scale_factor,
- unsigned char QIndex ){
+ unsigned char QIndex ){
int i, j;
-
+
ogg_uint16_t * InterY_coeffs;
ogg_uint16_t * InterU_coeffs;
ogg_uint16_t * InterV_coeffs;
ogg_uint16_t * Y_coeffs;
ogg_uint16_t * U_coeffs;
ogg_uint16_t * V_coeffs;
- ogg_uint16_t * DcScaleFactorTable;
-
Y_coeffs = pbi->quant_tables[0][0][QIndex];
U_coeffs = pbi->quant_tables[0][1][QIndex];
V_coeffs = pbi->quant_tables[0][2][QIndex];
InterY_coeffs = pbi->quant_tables[1][0][QIndex];
InterU_coeffs = pbi->quant_tables[1][1][QIndex];
InterV_coeffs = pbi->quant_tables[1][2][QIndex];
- DcScaleFactorTable = pbi->quant_info.dc_scale;
-
+
/* invert the dequant index into the quant index
the dxer has a different order than the cxer. */
BuildZigZagIndex(pbi);
@@ -641,95 +589,6 @@
pbi->dequant_InterV_coeffs[j] = InterV_coeffs[i];
}
- /* Intra Y DC coeff */
- pbi->dequant_Y_coeffs[0] =
- ((DcScaleFactorTable[QIndex] * pbi->dequant_Y_coeffs[0])/100);
- if ( pbi->dequant_Y_coeffs[0] < MIN_DEQUANT_VAL * 2 )
- pbi->dequant_Y_coeffs[0] = MIN_DEQUANT_VAL * 2;
- pbi->dequant_Y_coeffs[0] =
- pbi->dequant_Y_coeffs[0] << IDCT_SCALE_FACTOR;
-
- /* Intra UV */
- pbi->dequant_U_coeffs[0] =
- ((DcScaleFactorTable[QIndex] * pbi->dequant_U_coeffs[0])/100);
- if ( pbi->dequant_U_coeffs[0] < MIN_DEQUANT_VAL * 2 )
- pbi->dequant_U_coeffs[0] = MIN_DEQUANT_VAL * 2;
- pbi->dequant_U_coeffs[0] =
- pbi->dequant_U_coeffs[0] << IDCT_SCALE_FACTOR;
- pbi->dequant_V_coeffs[0] =
- ((DcScaleFactorTable[QIndex] * pbi->dequant_V_coeffs[0])/100);
- if ( pbi->dequant_V_coeffs[0] < MIN_DEQUANT_VAL * 2 )
- pbi->dequant_V_coeffs[0] = MIN_DEQUANT_VAL * 2;
- pbi->dequant_V_coeffs[0] =
- pbi->dequant_V_coeffs[0] << IDCT_SCALE_FACTOR;
-
- /* Inter Y DC coeff */
- pbi->dequant_InterY_coeffs[0] =
- ((DcScaleFactorTable[QIndex] * pbi->dequant_InterY_coeffs[0])/100);
- if ( pbi->dequant_InterY_coeffs[0] < MIN_DEQUANT_VAL * 4 )
- pbi->dequant_InterY_coeffs[0] = MIN_DEQUANT_VAL * 4;
- pbi->dequant_InterY_coeffs[0] =
- pbi->dequant_InterY_coeffs[0] << IDCT_SCALE_FACTOR;
-
- /* Inter UV */
- pbi->dequant_InterU_coeffs[0] =
- ((DcScaleFactorTable[QIndex] * pbi->dequant_InterU_coeffs[0])/100);
- if ( pbi->dequant_InterU_coeffs[0] < MIN_DEQUANT_VAL * 4 )
- pbi->dequant_InterU_coeffs[0] = MIN_DEQUANT_VAL * 4;
- pbi->dequant_InterU_coeffs[0] =
- pbi->dequant_InterU_coeffs[0] << IDCT_SCALE_FACTOR;
- pbi->dequant_InterV_coeffs[0] =
- ((DcScaleFactorTable[QIndex] * pbi->dequant_InterV_coeffs[0])/100);
- if ( pbi->dequant_InterV_coeffs[0] < MIN_DEQUANT_VAL * 4 )
- pbi->dequant_InterV_coeffs[0] = MIN_DEQUANT_VAL * 4;
- pbi->dequant_InterV_coeffs[0] =
- pbi->dequant_InterV_coeffs[0] << IDCT_SCALE_FACTOR;
-
- for ( i = 1; i < BLOCK_SIZE; i++ ){
- /* now scale coefficients by required compression factor */
- pbi->dequant_Y_coeffs[i] =
- (( scale_factor * pbi->dequant_Y_coeffs[i] ) / 100);
- if ( pbi->dequant_Y_coeffs[i] < MIN_DEQUANT_VAL )
- pbi->dequant_Y_coeffs[i] = MIN_DEQUANT_VAL;
- pbi->dequant_Y_coeffs[i] =
- pbi->dequant_Y_coeffs[i] << IDCT_SCALE_FACTOR;
-
- pbi->dequant_U_coeffs[i] =
- (( scale_factor * pbi->dequant_U_coeffs[i] ) / 100);
- if ( pbi->dequant_U_coeffs[i] < MIN_DEQUANT_VAL )
- pbi->dequant_U_coeffs[i] = MIN_DEQUANT_VAL;
- pbi->dequant_U_coeffs[i] =
- pbi->dequant_U_coeffs[i] << IDCT_SCALE_FACTOR;
-
- pbi->dequant_V_coeffs[i] =
- (( scale_factor * pbi->dequant_V_coeffs[i] ) / 100);
- if ( pbi->dequant_V_coeffs[i] < MIN_DEQUANT_VAL )
- pbi->dequant_V_coeffs[i] = MIN_DEQUANT_VAL;
- pbi->dequant_V_coeffs[i] =
- pbi->dequant_V_coeffs[i] << IDCT_SCALE_FACTOR;
-
- pbi->dequant_InterY_coeffs[i] =
- (( scale_factor * pbi->dequant_InterY_coeffs[i] ) / 100);
- if ( pbi->dequant_InterY_coeffs[i] < (MIN_DEQUANT_VAL * 2) )
- pbi->dequant_InterY_coeffs[i] = MIN_DEQUANT_VAL * 2;
- pbi->dequant_InterY_coeffs[i] =
- pbi->dequant_InterY_coeffs[i] << IDCT_SCALE_FACTOR;
-
- pbi->dequant_InterU_coeffs[i] =
- (( scale_factor * pbi->dequant_InterU_coeffs[i] ) / 100);
- if ( pbi->dequant_InterU_coeffs[i] < (MIN_DEQUANT_VAL * 2) )
- pbi->dequant_InterU_coeffs[i] = MIN_DEQUANT_VAL * 2;
- pbi->dequant_InterU_coeffs[i] =
- pbi->dequant_InterU_coeffs[i] << IDCT_SCALE_FACTOR;
-
- pbi->dequant_InterV_coeffs[i] =
- (( scale_factor * pbi->dequant_InterV_coeffs[i] ) / 100);
- if ( pbi->dequant_InterV_coeffs[i] < (MIN_DEQUANT_VAL * 2) )
- pbi->dequant_InterV_coeffs[i] = MIN_DEQUANT_VAL * 2;
- pbi->dequant_InterV_coeffs[i] =
- pbi->dequant_InterV_coeffs[i] << IDCT_SCALE_FACTOR;
- }
-
pbi->dequant_coeffs = pbi->dequant_Y_coeffs;
}
@@ -746,7 +605,7 @@
pbi->ThisFrameQualityValue = qscale;
/* Re-initialise the Q tables for forward and reverse transforms. */
- init_dequantizer ( pbi, qscale, (unsigned char) pbi->FrameQIndex );
+ init_dequantizer ( pbi, (unsigned char) pbi->FrameQIndex );
}
void UpdateQC( CP_INSTANCE *cpi, ogg_uint32_t NewQ ){
@@ -759,7 +618,7 @@
qscale = pbi->quant_info.ac_scale[Q_TABLE_SIZE-1];
else if ( qscale > pbi->quant_info.ac_scale[0] )
qscale = pbi->quant_info.ac_scale[0];
-
+
/* Set the inter/intra descision control variables. */
pbi->FrameQIndex = Q_TABLE_SIZE - 1;
while ((ogg_int32_t) pbi->FrameQIndex >= 0 ) {
@@ -770,6 +629,6 @@
}
/* Re-initialise the Q tables for forward and reverse transforms. */
- init_quantizer ( cpi, qscale, (unsigned char) pbi->FrameQIndex );
- init_dequantizer ( pbi, qscale, (unsigned char) pbi->FrameQIndex );
+ init_quantizer ( cpi, pbi->FrameQIndex );
+ init_dequantizer ( pbi, pbi->FrameQIndex );
}
Modified: trunk/theora/lib/enc/encoder_toplevel.c
===================================================================
--- trunk/theora/lib/enc/encoder_toplevel.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/encoder_toplevel.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -900,6 +900,10 @@
CP_INSTANCE *cpi;
+#ifdef _TH_DEBUG_
+ debugout=fopen("theoraenc-debugout.txt","w");
+#endif
+
memset(th, 0, sizeof(*th));
/*Currently only the 4:2:0 format is supported.*/
if(c->pixelformat!=OC_PF_420)return OC_IMPL;
@@ -933,7 +937,7 @@
cpi->ExhaustiveSearchThresh = 2500;
cpi->MinImprovementForFourMV = 100;
cpi->FourMVThreshold = 10000;
- cpi->BitRateCapFactor = 5.0;
+ cpi->BitRateCapFactor = 1.5;
cpi->InterTripOutThresh = 5000;
cpi->MVEnabled = 1;
cpi->InterCodeCount = 127;
@@ -1188,10 +1192,6 @@
CP_INSTANCE *cpi=(CP_INSTANCE *)(t->internal_encode);
int offset_y;
-#ifdef _TH_DEBUG_
- debugout=fopen("theoraenc-debugout.txt","w");
-#endif
-
#ifndef LIBOGG2
oggpackB_reset(cpi->oggbuffer);
#else
Modified: trunk/theora/lib/enc/frinit.c
===================================================================
--- trunk/theora/lib/enc/frinit.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/frinit.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -141,6 +141,14 @@
if(pbi->FragCoefEOB) _ogg_free(pbi->FragCoefEOB);
if(pbi->skipped_display_fragments) _ogg_free(pbi->skipped_display_fragments);
if(pbi->QFragData) _ogg_free(pbi->QFragData);
+#ifdef _TH_DEBUG_
+ if(pbi->QFragTIME) _ogg_free(pbi->QFragTIME);
+ if(pbi->QFragFREQ) _ogg_free(pbi->QFragFREQ);
+ if(pbi->QFragQUAN) _ogg_free(pbi->QFragQUAN);
+ pbi->QFragTIME = 0;
+ pbi->QFragFREQ = 0;
+ pbi->QFragQUAN = 0;
+#endif
if(pbi->TokenList) _ogg_free(pbi->TokenList);
if(pbi->FragCodingMethod) _ogg_free(pbi->FragCodingMethod);
if(pbi->FragCoordinates) _ogg_free(pbi->FragCoordinates);
@@ -235,6 +243,19 @@
pbi->QFragData =
_ogg_malloc(pbi->UnitFragments * sizeof(*pbi->QFragData));
+#ifdef _TH_DEBUG_
+
+ pbi->QFragTIME =
+ _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->QFragTIME));
+
+ pbi->QFragFREQ =
+ _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->QFragFREQ));
+
+ pbi->QFragQUAN =
+ _ogg_malloc(pbi->UnitFragments * sizeof(*pbi->QFragQUAN));
+
+#endif
+
pbi->TokenList =
_ogg_malloc(pbi->UnitFragments * sizeof(*pbi->TokenList));
@@ -374,9 +395,7 @@
pbi->SuperBlocks = pbi->YSuperBlocks+2*pbi->UVSuperBlocks;
/* Useful externals */
- pbi->YMacroBlocks = ((pbi->VFragments+1)/2)*((pbi->HFragments+1)/2);
- pbi->UVMacroBlocks = ((pbi->VFragments/2+1)/2)*((pbi->HFragments/2+1)/2);
- pbi->MacroBlocks = pbi->YMacroBlocks+2*pbi->UVMacroBlocks;
+ pbi->MacroBlocks = ((pbi->VFragments+1)/2)*((pbi->HFragments+1)/2);
InitFragmentInfo(pbi);
InitFrameInfo(pbi, FrameSize);
Modified: trunk/theora/lib/enc/pb.c
===================================================================
--- trunk/theora/lib/enc/pb.c 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/enc/pb.c 2007-10-28 23:43:27 UTC (rev 14059)
@@ -29,30 +29,12 @@
_ogg_free(pbi->TmpDataBuffer);
if(pbi->TmpReconBuffer)
_ogg_free(pbi->TmpReconBuffer);
- if(pbi->dequant_Y_coeffs)
- _ogg_free(pbi->dequant_Y_coeffs);
- if(pbi->dequant_U_coeffs)
- _ogg_free(pbi->dequant_U_coeffs);
- if(pbi->dequant_V_coeffs)
- _ogg_free(pbi->dequant_V_coeffs);
- if(pbi->dequant_InterY_coeffs)
- _ogg_free(pbi->dequant_InterY_coeffs);
- if(pbi->dequant_InterU_coeffs)
- _ogg_free(pbi->dequant_InterU_coeffs);
- if(pbi->dequant_InterV_coeffs)
- _ogg_free(pbi->dequant_InterV_coeffs);
pbi->ReconDataBuffer=0;
pbi->DequantBuffer = 0;
pbi->TmpDataBuffer = 0;
pbi->TmpReconBuffer = 0;
- pbi->dequant_Y_coeffs = 0;
- pbi->dequant_U_coeffs = 0;
- pbi->dequant_V_coeffs = 0;
- pbi->dequant_InterY_coeffs = 0;
- pbi->dequant_InterU_coeffs = 0;
- pbi->dequant_InterV_coeffs = 0;
}
@@ -74,24 +56,6 @@
pbi->TmpReconBuffer =
_ogg_malloc(64 * sizeof(*pbi->TmpReconBuffer));
- pbi->dequant_Y_coeffs =
- _ogg_malloc(64 * sizeof(*pbi->dequant_Y_coeffs));
-
- pbi->dequant_U_coeffs =
- _ogg_malloc(64 * sizeof(*pbi->dequant_U_coeffs));
-
- pbi->dequant_V_coeffs =
- _ogg_malloc(64 * sizeof(*pbi->dequant_V_coeffs));
-
- pbi->dequant_InterY_coeffs =
- _ogg_malloc(64 * sizeof(*pbi->dequant_InterY_coeffs));
-
- pbi->dequant_InterU_coeffs =
- _ogg_malloc(64 * sizeof(*pbi->dequant_InterU_coeffs));
-
- pbi->dequant_InterV_coeffs =
- _ogg_malloc(64 * sizeof(*pbi->dequant_InterV_coeffs));
-
}
void ClearPBInstance(PB_INSTANCE *pbi){
Modified: trunk/theora/lib/internal.h
===================================================================
--- trunk/theora/lib/internal.h 2007-10-28 21:20:36 UTC (rev 14058)
+++ trunk/theora/lib/internal.h 2007-10-28 23:43:27 UTC (rev 14059)
@@ -15,6 +15,7 @@
********************************************************************/
+
#if !defined(_internal_H)
# define _internal_H (1)
# include <stdlib.h>
@@ -43,7 +44,7 @@
# endif
/*This library's version.*/
-# define OC_VENDOR_STRING "Xiph.Org libTheora I 20070915 3 2 1"
+# define OC_VENDOR_STRING "Xiph.Org libTheora I 20071025 3 2 1"
/*Theora bitstream version.*/
# define TH_VERSION_MAJOR (3)
@@ -77,28 +78,28 @@
/*Macroblock modes.*/
/*Macro block is invalid: It is never coded.*/
#define OC_MODE_INVALID (-1)
-
+/*Encoded difference from the same macro block in the previous frame.*/
+#define OC_MODE_INTER_NOMV (0)
/*Encoded with no motion compensated prediction.*/
-#define OC_MODE_INTRA (0)
-/*Encoded difference from the same macro block in the previous frame.*/
-#define OC_MODE_INTER_NOMV (1)
-/*Encoded difference from the previous frame offset by the given motion
- vector.*/
+#define OC_MODE_INTRA (1)
+/*Encoded difference from the previous frame offset by the given motion
+ vector.*/
#define OC_MODE_INTER_MV (2)
-/*Encoded difference from the previous frame offset by the last coded motion
- vector.*/
+/*Encoded difference from the previous frame offset by the last coded motion
+ vector.*/
#define OC_MODE_INTER_MV_LAST (3)
-/*Encoded difference from the previous frame offset by the second to last
- coded motion vector.*/
+/*Encoded difference from the previous frame offset by the second to last
+ coded motion vector.*/
#define OC_MODE_INTER_MV_LAST2 (4)
-/*Encoded difference from the previous frame offset by the individual motion
- vectors given for each block.*/
-#define OC_MODE_INTER_MV_FOUR (5)
-/*Encoded difference from the same macro block in the previous golden frame.*/
-#define OC_MODE_GOLDEN_NOMV (6)
-/*Encoded difference from the previous golden frame offset by the given motion
- vector.*/
-#define OC_MODE_GOLDEN_MV (7)
+/*Encoded difference from the same macro block in the previous golden
+ frame.*/
+#define OC_MODE_GOLDEN_NOMV (5)
+/*Encoded difference from the previous golden frame offset by the given motion
+ vector.*/
+#define OC_MODE_GOLDEN_MV (6)
+/*Encoded difference from the previous frame offset by the individual motion
+ vectors given for each block.*/
+#define OC_MODE_INTER_MV_FOUR (7)
/*The number of (coded) modes.*/
#define OC_NMODES (8)
@@ -233,6 +234,12 @@
oc_border_info *border;
/*The motion vector used for this fragment.*/
oc_mv mv;
+
+#ifdef _TH_DEBUG_
+ int quant[64];
+ int freq[64];
+ int time[64];
+#endif
}oc_fragment;
@@ -270,7 +277,7 @@
int _src2_ystride,const ogg_int16_t *_residue);
void (*state_frag_copy)(const oc_theora_state *_state,
const int *_fragis,int _nfragis,int _dst_frame,int _src_frame,int _pli);
- void (*state_frag_recon)(oc_theora_state *_state,const oc_fragment *_frag,
+ void (*state_frag_recon)(oc_theora_state *_state, oc_fragment *_frag,
int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]);
void (*restore_fpu)(void);
@@ -441,7 +448,7 @@
int _src2_ystride,const ogg_int16_t *_residue);
void oc_state_frag_copy(const oc_theora_state *_state,const int *_fragis,
int _nfragis,int _dst_frame,int _src_frame,int _pli);
-void oc_state_frag_recon(oc_theora_state *_state,const oc_fragment *_frag,
+void oc_state_frag_recon(oc_theora_state *_state, oc_fragment *_frag,
int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]);
void oc_state_loop_filter_frag_rows(oc_theora_state *_state,int *_bv,
@@ -458,7 +465,7 @@
int _src2_ystride,const ogg_int16_t *_residue);
void oc_state_frag_copy_c(const oc_theora_state *_state,const int *_fragis,
int _nfragis,int _dst_frame,int _src_frame,int _pli);
-void oc_state_frag_recon_c(oc_theora_state *_state,const oc_fragment *_frag,
+void oc_state_frag_recon_c(oc_theora_state *_state, oc_fragment *_frag,
int _pli,ogg_int16_t _dct_coeffs[128],int _last_zzi,int _ncoefs,
ogg_uint16_t _dc_iquant,const ogg_uint16_t _ac_iquant[64]);
void oc_state_loop_filter_frag_rows_c(oc_theora_state *_state,int *_bv,
More information about the commits
mailing list