[xiph-commits] r14410 - branches/theora-thusnelda/lib/enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Thu Jan 17 10:04:23 PST 2008
Author: xiphmont
Date: 2008-01-17 10:04:21 -0800 (Thu, 17 Jan 2008)
New Revision: 14410
Modified:
branches/theora-thusnelda/lib/enc/codec_internal.h
branches/theora-thusnelda/lib/enc/dct_encode.c
branches/theora-thusnelda/lib/enc/frinit.c
branches/theora-thusnelda/lib/enc/mode.c
branches/theora-thusnelda/lib/enc/mode_select.h
Log:
Move some work [that does not yet build/run] into SVN to move to remote machine
Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h 2008-01-17 07:51:18 UTC (rev 14409)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h 2008-01-17 18:04:21 UTC (rev 14410)
@@ -204,6 +204,7 @@
unsigned char *frag_nonzero;
ogg_int16_t *frag_dc;
dct_t *frag_dct;
+ ogg_uint32_t *frag_mbi;
macroblock_t *macro;
superblock_t *super[3];
@@ -255,7 +256,19 @@
ogg_uint32_t MVBits_0; /* count of bits used by MV coding mode 0 */
ogg_uint32_t MVBits_1; /* count of bits used by MV coding mode 1 */
+ /********************************************************************/
+ /* Fragment SAD->bitrate estimation tracking metrics */
+ int *frag_sad;
+ int *dct_token_frag_storage;
+ int *dct_token_frag[64];
+ int *dct_eob_fi_storage;
+ int *dct_eob_fi_stack[64];
+ int dct_eob_fi_count[64];
+ ogg_uint32_t frag_bitrates[64][3][8][OC_SAD_BINS];
+ ogg_uint32_t frag_distort[64][3][8][OC_SAD_BINS];
+ ogg_uint32_t frag_distort_count[64][3][8][OC_SAD_BINS];
+
/********************************************************************/
/* Setup */
int keyframe_granule_shift;
Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c 2008-01-17 07:51:18 UTC (rev 14409)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c 2008-01-17 18:04:21 UTC (rev 14410)
@@ -32,10 +32,11 @@
/* plane == 0 for Y, 1 for UV */
static void add_token(CP_INSTANCE *cpi, int plane, int coeff,
- unsigned char token, ogg_uint16_t eb){
+ unsigned char token, ogg_uint16_t eb, int fi){
cpi->dct_token[coeff][cpi->dct_token_count[coeff]] = token;
cpi->dct_token_eb[coeff][cpi->dct_token_count[coeff]] = eb;
+ cpi->dct_token_frag[coeff][cpi->dct_token_count[coeff]] = fi;
cpi->dct_token_count[coeff]++;
if(coeff == 0){
@@ -54,12 +55,14 @@
}
static void prepend_token(CP_INSTANCE *cpi, int plane, int coeff,
- unsigned char token, ogg_uint16_t eb){
+ unsigned char token, ogg_uint16_t eb, int fi){
cpi->dct_token[coeff]--;
cpi->dct_token_eb[coeff]--;
+ cpi->dct_token_frag[coeff]--;
cpi->dct_token[coeff][0] = token;
cpi->dct_token_eb[coeff][0] = eb;
+ cpi->dct_token_frag[coeff][0] = fi;
cpi->dct_token_count[coeff]++;
if(coeff == 0){
@@ -80,23 +83,23 @@
static void emit_eob_run(CP_INSTANCE *cpi, int plane, int pos, int run){
if ( run <= 3 ) {
if ( run == 1 ) {
- add_token(cpi, plane, pos, DCT_EOB_TOKEN, 0);
+ add_token(cpi, plane, pos, DCT_EOB_TOKEN, 0, 0);
} else if ( run == 2 ) {
- add_token(cpi, plane, pos, DCT_EOB_PAIR_TOKEN, 0);
+ add_token(cpi, plane, pos, DCT_EOB_PAIR_TOKEN, 0, 0);
} else {
- add_token(cpi, plane, pos, DCT_EOB_TRIPLE_TOKEN, 0);
+ add_token(cpi, plane, pos, DCT_EOB_TRIPLE_TOKEN, 0, 0);
}
} else {
if ( run < 8 ) {
- add_token(cpi, plane, pos, DCT_REPEAT_RUN_TOKEN, run-4);
+ add_token(cpi, plane, pos, DCT_REPEAT_RUN_TOKEN, run-4, 0);
} else if ( run < 16 ) {
- add_token(cpi, plane, pos, DCT_REPEAT_RUN2_TOKEN, run-8);
+ add_token(cpi, plane, pos, DCT_REPEAT_RUN2_TOKEN, run-8, 0);
} else if ( run < 32 ) {
- add_token(cpi, plane, pos, DCT_REPEAT_RUN3_TOKEN, run-16);
+ add_token(cpi, plane, pos, DCT_REPEAT_RUN3_TOKEN, run-16, 0);
} else if ( run < 4096) {
- add_token(cpi, plane, pos, DCT_REPEAT_RUN4_TOKEN, run);
+ add_token(cpi, plane, pos, DCT_REPEAT_RUN4_TOKEN, run, 0);
}
}
}
@@ -104,23 +107,23 @@
static void prepend_eob_run(CP_INSTANCE *cpi, int plane, int pos, int run){
if ( run <= 3 ) {
if ( run == 1 ) {
- prepend_token(cpi, plane, pos, DCT_EOB_TOKEN, 0);
+ prepend_token(cpi, plane, pos, DCT_EOB_TOKEN, 0, 0);
} else if ( run == 2 ) {
- prepend_token(cpi, plane, pos, DCT_EOB_PAIR_TOKEN, 0);
+ prepend_token(cpi, plane, pos, DCT_EOB_PAIR_TOKEN, 0, 0);
} else {
- prepend_token(cpi, plane, pos, DCT_EOB_TRIPLE_TOKEN, 0);
+ prepend_token(cpi, plane, pos, DCT_EOB_TRIPLE_TOKEN, 0, 0);
}
} else {
if ( run < 8 ) {
- prepend_token(cpi, plane, pos, DCT_REPEAT_RUN_TOKEN, run-4);
+ prepend_token(cpi, plane, pos, DCT_REPEAT_RUN_TOKEN, run-4, 0);
} else if ( run < 16 ) {
- prepend_token(cpi, plane, pos, DCT_REPEAT_RUN2_TOKEN, run-8);
+ prepend_token(cpi, plane, pos, DCT_REPEAT_RUN2_TOKEN, run-8, 0);
} else if ( run < 32 ) {
- prepend_token(cpi, plane, pos, DCT_REPEAT_RUN3_TOKEN, run-16);
+ prepend_token(cpi, plane, pos, DCT_REPEAT_RUN3_TOKEN, run-16, 0);
} else if ( run < 4096) {
- prepend_token(cpi, plane, pos, DCT_REPEAT_RUN4_TOKEN, run);
+ prepend_token(cpi, plane, pos, DCT_REPEAT_RUN4_TOKEN, run, 0);
}
}
}
@@ -128,46 +131,47 @@
static void TokenizeDctValue (CP_INSTANCE *cpi,
int plane,
int coeff,
- ogg_int16_t DataValue){
+ ogg_int16_t DataValue,
+ int fi){
int AbsDataVal = abs(DataValue);
int neg = (DataValue<0);
if ( AbsDataVal == 1 ){
- add_token(cpi, plane, coeff, (neg ? MINUS_ONE_TOKEN : ONE_TOKEN), 0);
+ add_token(cpi, plane, coeff, (neg ? MINUS_ONE_TOKEN : ONE_TOKEN), 0, fi);
} else if ( AbsDataVal == 2 ) {
- add_token(cpi, plane, coeff, (neg ? MINUS_TWO_TOKEN : TWO_TOKEN), 0);
+ add_token(cpi, plane, coeff, (neg ? MINUS_TWO_TOKEN : TWO_TOKEN), 0, fi);
} else if ( AbsDataVal <= MAX_SINGLE_TOKEN_VALUE ) {
- add_token(cpi, plane, coeff, LOW_VAL_TOKENS + (AbsDataVal - DCT_VAL_CAT2_MIN), neg);
+ add_token(cpi, plane, coeff, LOW_VAL_TOKENS + (AbsDataVal - DCT_VAL_CAT2_MIN), neg, fi);
} else if ( AbsDataVal <= 8 ) {
- add_token(cpi, plane, coeff, DCT_VAL_CATEGORY3, (AbsDataVal - DCT_VAL_CAT3_MIN) + (neg << 1));
+ add_token(cpi, plane, coeff, DCT_VAL_CATEGORY3, (AbsDataVal - DCT_VAL_CAT3_MIN) + (neg << 1), fi);
} else if ( AbsDataVal <= 12 ) {
- add_token(cpi, plane, coeff, DCT_VAL_CATEGORY4, (AbsDataVal - DCT_VAL_CAT4_MIN) + (neg << 2));
+ add_token(cpi, plane, coeff, DCT_VAL_CATEGORY4, (AbsDataVal - DCT_VAL_CAT4_MIN) + (neg << 2), fi);
} else if ( AbsDataVal <= 20 ) {
- add_token(cpi, plane, coeff, DCT_VAL_CATEGORY5, (AbsDataVal - DCT_VAL_CAT5_MIN) + (neg << 3));
+ add_token(cpi, plane, coeff, DCT_VAL_CATEGORY5, (AbsDataVal - DCT_VAL_CAT5_MIN) + (neg << 3), fi);
} else if ( AbsDataVal <= 36 ) {
- add_token(cpi, plane, coeff, DCT_VAL_CATEGORY6, (AbsDataVal - DCT_VAL_CAT6_MIN) + (neg << 4));
+ add_token(cpi, plane, coeff, DCT_VAL_CATEGORY6, (AbsDataVal - DCT_VAL_CAT6_MIN) + (neg << 4), fi);
} else if ( AbsDataVal <= 68 ) {
- add_token(cpi, plane, coeff, DCT_VAL_CATEGORY7, (AbsDataVal - DCT_VAL_CAT7_MIN) + (neg << 5));
+ add_token(cpi, plane, coeff, DCT_VAL_CATEGORY7, (AbsDataVal - DCT_VAL_CAT7_MIN) + (neg << 5), fi);
} else {
- add_token(cpi, plane, coeff, DCT_VAL_CATEGORY8, (AbsDataVal - DCT_VAL_CAT8_MIN) + (neg << 9));
+ add_token(cpi, plane, coeff, DCT_VAL_CATEGORY8, (AbsDataVal - DCT_VAL_CAT8_MIN) + (neg << 9), fi);
}
}
@@ -187,19 +191,19 @@
if ( AbsDataVal == 1 ) {
if ( RunLength <= 5 )
- add_token(cpi,plane,coeff, DCT_RUN_CATEGORY1 + RunLength - 1, neg);
+ add_token(cpi,plane,coeff, DCT_RUN_CATEGORY1 + RunLength - 1, neg, fi);
else if ( RunLength <= 9 )
- add_token(cpi,plane,coeff, DCT_RUN_CATEGORY1B, RunLength - 6 + (neg<<2));
+ add_token(cpi,plane,coeff, DCT_RUN_CATEGORY1B, RunLength - 6 + (neg<<2), fi);
else
- add_token(cpi,plane,coeff, DCT_RUN_CATEGORY1C, RunLength - 10 + (neg<<3));
+ add_token(cpi,plane,coeff, DCT_RUN_CATEGORY1C, RunLength - 10 + (neg<<3), fi);
} else if ( AbsDataVal <= 3 ) {
if ( RunLength == 1 )
- add_token(cpi,plane,coeff, DCT_RUN_CATEGORY2, AbsDataVal - 2 + (neg<<1));
+ add_token(cpi,plane,coeff, DCT_RUN_CATEGORY2, AbsDataVal - 2 + (neg<<1), fi);
else
add_token(cpi,plane,coeff, DCT_RUN_CATEGORY2B,
- (neg<<2) + ((AbsDataVal-2)<<1) + RunLength - 2);
+ (neg<<2) + ((AbsDataVal-2)<<1) + RunLength - 2, fi);
}
}
@@ -240,6 +244,7 @@
eob_ypre[coeff]++;
else
eob_uvpre[coeff]++;
+ cpi->dct_eob_fi_stack[coeff][cpi->dct_eob_fi_count[coeff]++]=fi;
}else{
if(eob_run[coeff] == 4095){
emit_eob_run(cpi,eob_plane[coeff],coeff,4095);
@@ -250,6 +255,7 @@
eob_plane[coeff]=plane;
eob_run[coeff]++;
+ cpi->dct_eob_fi_stack[coeff][cpi->dct_eob_fi_count[coeff]++]=fi;
}
coeff = BLOCK_SIZE;
}else{
@@ -264,17 +270,17 @@
ogg_uint32_t absval = abs(val);
if ( ((absval == 1) && (zero_run <= 17)) ||
((absval <= 3) && (zero_run <= 3)) ) {
- TokenizeDctRunValue( cpi, plane, coeff, zero_run, val);
+ TokenizeDctRunValue( cpi, plane, coeff, zero_run, val, fi);
coeff = i+1;
}else{
if ( zero_run <= 8 )
- add_token(cpi, plane, coeff, DCT_SHORT_ZRL_TOKEN, zero_run - 1);
+ add_token(cpi, plane, coeff, DCT_SHORT_ZRL_TOKEN, zero_run - 1, fi);
else
- add_token(cpi, plane, coeff, DCT_ZRL_TOKEN, zero_run - 1);
+ add_token(cpi, plane, coeff, DCT_ZRL_TOKEN, zero_run - 1, fi);
coeff = i;
}
}else{
- TokenizeDctValue( cpi, plane, coeff, val );
+ TokenizeDctValue(cpi, plane, coeff, val, fi);
coeff = i+1;
}
}
@@ -300,10 +306,13 @@
memset(cpi->ac_bits, 0, sizeof(cpi->ac_bits));
memset(cpi->dct_token_count, 0, sizeof(cpi->dct_token_count));
memset(cpi->dct_token_ycount, 0, sizeof(cpi->dct_token_ycount));
+ memset(cpi->dct_eob_fi_count, 0, sizeof(cpi->dct_eob_fi_count));
for(i=0;i<BLOCK_SIZE;i++){
cpi->dct_token[i] = cpi->dct_token_storage+cpi->frag_total*i;
cpi->dct_token_eb[i] = cpi->dct_token_eb_storage+cpi->frag_total*i;
+ cpi->dct_token_frag[i] = cpi->dct_token_frag_storage+cpi->frag_total*i;
+ cpi->dct_eob_fi_stack[i] = cpi->dct_eob_fi_storage+cpi->frag_total*i;
}
/* Tokenize the dct data. */
@@ -512,6 +521,25 @@
}
}
+static int blockSAD(ogg_int16_t *b, int interp){
+ int j;
+ int sad = 0;
+
+ if(inter_p){
+ for(j=0;j<64;j++)
+ sad += abs(b[j]);
+ }else{
+ ogg_uint32_t acc = 0;
+ for(j=0;j<64;j++)
+ acc += b[j];
+ for(j=0;j<64;j++)
+ sad += abs ((b[j]<<6)-acc);
+ sad>>=6;
+ }
+
+ return sad;
+}
+
void TransformQuantizeBlock (CP_INSTANCE *cpi,
coding_mode_t mode,
int fi,
@@ -540,7 +568,8 @@
forward DCT */
BlockUpdateDifference(cpi, FiltPtr, DCTInput,
MvDivisor, fi, cpi->stride[plane], mode, mv);
-
+ cpi->frag_sad[fi] = blockSAD(DCTInput, inter);
+
/* Proceed to encode the data into the encode buffer if the encoder
is enabled. */
/* Perform a 2D DCT transform on the data. */
Modified: branches/theora-thusnelda/lib/enc/frinit.c
===================================================================
--- branches/theora-thusnelda/lib/enc/frinit.c 2008-01-17 07:51:18 UTC (rev 14409)
+++ branches/theora-thusnelda/lib/enc/frinit.c 2008-01-17 18:04:21 UTC (rev 14410)
@@ -58,6 +58,12 @@
if(cpi->frag_dc) _ogg_free(cpi->frag_dc);
cpi->frag_dc = 0;
+ if(cpi->frag_mbi) _ogg_free(cpi->frag_mbi);
+ cpi->frag_mbi = 0;
+
+ if(cpi->frag_sad) _ogg_free(cpi->frag_sad);
+ cpi->frag_sad = 0;
+
if(cpi->macro) _ogg_free(cpi->macro);
cpi->macro = 0;
@@ -137,6 +143,8 @@
cpi->frag_nonzero = calloc(cpi->frag_total, sizeof(*cpi->frag_nonzero));
cpi->frag_dct = calloc(cpi->frag_total, sizeof(*cpi->frag_dct));
cpi->frag_dc = calloc(cpi->frag_total, sizeof(*cpi->frag_dc));
+ cpi->frag_mbi = calloc(cpi->frag_total+1, sizeof(*cpi->frag_mbi));
+ cpi->frag_sad = calloc(cpi->frag_total, sizeof(*cpi->frag_sad));
/* +1; the last entry is the 'invalid' mb, which contains only 'invalid' frags */
cpi->macro = calloc(cpi->macro_total+1, sizeof(*cpi->macro));
@@ -241,27 +249,33 @@
for(col=0;col<cpi->macro_h;col++){
int basecol = col*2;
int macroindex = row*cpi->macro_h + col;
+ int fragindex;
for(frag=0;frag<4;frag++){
/* translate to fragment index */
int frow = baserow + scany[frag];
int fcol = basecol + scanx[frag];
if(frow<cpi->frag_v[0] && fcol<cpi->frag_h[0]){
- int fragindex = frow*cpi->frag_h[0] + fcol;
- cpi->macro[macroindex].yuv[0][frag] = fragindex;
+ fragindex = frow*cpi->frag_h[0] + fcol;
+ cpi->frag_mbi[fragindex] = macroindex;
}else
- cpi->macro[macroindex].yuv[0][frag] = cpi->frag_total;
+ fragindex = cpi->frag_total;
+ cpi->macro[macroindex].yuv[0][frag] = fragindex;
}
- if(row<cpi->frag_v[1] && col<cpi->frag_h[1])
- cpi->macro[macroindex].yuv[1][0] = cpi->frag_n[0] + macroindex;
- else
- cpi->macro[macroindex].yuv[1][0] = cpi->frag_total;
-
- if(row<cpi->frag_v[2] && col<cpi->frag_h[2])
- cpi->macro[macroindex].yuv[2][0] = cpi->frag_n[0] + cpi->frag_n[1] + macroindex;
- else
- cpi->macro[macroindex].yuv[2][0] = cpi->frag_total;
-
+ if(row<cpi->frag_v[1] && col<cpi->frag_h[1]){
+ fragindex = cpi->frag_n[0] + macroindex;
+ cpi->frag_mbi[fragindex] = macroindex;
+ }else
+ fragindex = cpi->frag_total;
+ cpi->macro[macroindex].yuv[1][0] = fragindex;
+
+ if(row<cpi->frag_v[2] && col<cpi->frag_h[2]){
+ fragindex = cpi->frag_n[0] + cpi->frag_n[1] + macroindex;
+ cpi->frag_mbi[fragindex] = macroindex;
+ }else
+ fragindex = cpi->frag_total;
+ cpi->macro[macroindex].yuv[2][0] = fragindex;
+
}
}
}
@@ -309,6 +323,7 @@
cpi->macro[cpi->macro_total].yuv[p][f] = cpi->frag_total;
cpi->macro[cpi->macro_total].ncneighbors=0;
cpi->macro[cpi->macro_total].npneighbors=0;
+ cpi->frag_mbi[cpi->frag_total] = cpi->macro_total;
}
/* allocate frames */
@@ -318,8 +333,22 @@
cpi->recon = _ogg_malloc(cpi->frame_size*sizeof(*cpi->recon));
cpi->dct_token_storage = _ogg_malloc(cpi->frag_total*BLOCK_SIZE*sizeof(*cpi->dct_token_storage));
+ cpi->dct_token_frag_storage = _ogg_malloc(cpi->frag_total*BLOCK_SIZE*sizeof(*cpi->dct_token_frag_storage));
cpi->dct_token_eb_storage = _ogg_malloc(cpi->frag_total*BLOCK_SIZE*sizeof(*cpi->dct_token_eb_storage));
+ cpi->dct_eob_fi_storage = _ogg_malloc(cpi->frag_total*BLOCK_SIZE*sizeof(*cpi->dct_eob_fi_storage));
+ memset(cpi->frag_bitrates,0,sizeof(cpi->frag_distort));
+ memset(cpi->frag_distort_count,0,sizeof(cpi->frag_distort));
+ {
+ int qi,plane,mode,bin;
+
+ for(qi=0;i<64;qi++)
+ for(plane=0;plane<3;plane++)
+ for(mode=0;mode<8;mode++)
+ for(bin=0;bin<OC_SAD_BINS;bin++)
+ cpi->frag_distort_count[qi][plane][mode][bin]=100;
+ }
+
/* Re-initialise the pixel index table. */
{
ogg_uint32_t plane,row,col;
Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c 2008-01-17 07:51:18 UTC (rev 14409)
+++ branches/theora-thusnelda/lib/enc/mode.c 2008-01-17 18:04:21 UTC (rev 14410)
@@ -250,7 +250,7 @@
b += stride;
}
- return sad;
+ return sad>>6;
}
/* equivalent to adding up the abs values of the AC components of a block */
@@ -262,24 +262,24 @@
/* all frags in a macroblock are valid so long as the macroblock itself is valid */
if(mbi < cpi->macro_total){
if(all || cp[mb->yuv[0][0]])
- cost += OC_RES_BITRATES[qi][0][OC_MODE_INTRA]
- [OC_MINI(BIntraSAD(cpi,mb->yuv[0][0],0)>>12,15)];
+ cost += cpi->frag_bitrates[qi][0][OC_MODE_INTRA]
+ [OC_MINI(BIntraSAD(cpi,mb->yuv[0][0],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(all || cp[mb->yuv[0][1]])
- cost += OC_RES_BITRATES[qi][0][OC_MODE_INTRA]
- [OC_MINI(BIntraSAD(cpi,mb->yuv[0][1],0)>>12,15)];
+ cost += cpi->frag_bitrates[qi][0][OC_MODE_INTRA]
+ [OC_MINI(BIntraSAD(cpi,mb->yuv[0][1],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(all || cp[mb->yuv[0][2]])
- cost += OC_RES_BITRATES[qi][0][OC_MODE_INTRA]
- [OC_MINI(BIntraSAD(cpi,mb->yuv[0][2],0)>>12,15)];
+ cost += cpi->frag_bitrates[qi][0][OC_MODE_INTRA]
+ [OC_MINI(BIntraSAD(cpi,mb->yuv[0][2],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(all || cp[mb->yuv[0][3]])
- cost += OC_RES_BITRATES[qi][0][OC_MODE_INTRA]
- [OC_MINI(BIntraSAD(cpi,mb->yuv[0][3],0)>>12,15)];
+ cost += cpi->frag_bitrates[qi][0][OC_MODE_INTRA]
+ [OC_MINI(BIntraSAD(cpi,mb->yuv[0][3],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(all || cp[mb->yuv[1][0]])
- cost += OC_RES_BITRATES[qi][1][OC_MODE_INTRA]
- [OC_MINI(BIntraSAD(cpi,mb->yuv[1][0],1)>>12,15)];
+ cost += cpi->frag_bitrates[qi][1][OC_MODE_INTRA]
+ [OC_MINI(BIntraSAD(cpi,mb->yuv[1][0],1)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(all || cp[mb->yuv[2][0]])
- cost += OC_RES_BITRATES[qi][2][OC_MODE_INTRA]
- [OC_MINI(BIntraSAD(cpi,mb->yuv[2][0],2)>>12,15)];
+ cost += cpi->frag_bitrates[qi][2][OC_MODE_INTRA]
+ [OC_MINI(BIntraSAD(cpi,mb->yuv[2][0],2)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
}
/* Bit costs are stored in the table with extra precision. Round them down to whole bits.*/
@@ -357,24 +357,24 @@
int cost = 0;
if(cp[mb->yuv[0][0]])
- cost += OC_RES_BITRATES[qi][0][modei]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][0],0,goldenp,mv,0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][modei]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][0],0,goldenp,mv,0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[0][1]])
- cost += OC_RES_BITRATES[qi][0][modei]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][1],0,goldenp,mv,0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][modei]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][1],0,goldenp,mv,0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[0][2]])
- cost += OC_RES_BITRATES[qi][0][modei]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][2],0,goldenp,mv,0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][modei]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][2],0,goldenp,mv,0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[0][3]])
- cost += OC_RES_BITRATES[qi][0][modei]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][3],0,goldenp,mv,0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][modei]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][3],0,goldenp,mv,0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[1][0]])
- cost += OC_RES_BITRATES[qi][1][modei]
- [OC_MINI(BInterSAD(cpi,mb->yuv[1][0],1,goldenp,mv,1)>>6,15)];
+ cost += cpi->frag_bitrates[qi][1][modei]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[1][0],1,goldenp,mv,1)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[2][0]])
- cost += OC_RES_BITRATES[qi][2][modei]
- [OC_MINI(BInterSAD(cpi,mb->yuv[2][0],2,goldenp,mv,1)>>6,15)];
+ cost += cpi->frag_bitrates[qi][2][modei]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[2][0],2,goldenp,mv,1)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
/* Bit costs are stored in the table with extra precision. Round them down to whole bits.*/
return cost + (1<<OC_BIT_SCALE-1) >> OC_BIT_SCALE;
@@ -387,17 +387,17 @@
mv_t ch;
if(cp[mb->yuv[0][0]])
- cost += OC_RES_BITRATES[qi][0][CODE_INTER_FOURMV]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][0],0,goldenp,mv[0],0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][CODE_INTER_FOURMV]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][0],0,goldenp,mv[0],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[0][1]])
- cost += OC_RES_BITRATES[qi][0][CODE_INTER_FOURMV]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][1],0,goldenp,mv[1],0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][CODE_INTER_FOURMV]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][1],0,goldenp,mv[1],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[0][2]])
- cost += OC_RES_BITRATES[qi][0][CODE_INTER_FOURMV]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][2],0,goldenp,mv[2],0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][CODE_INTER_FOURMV]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][2],0,goldenp,mv[2],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[0][3]])
- cost += OC_RES_BITRATES[qi][0][CODE_INTER_FOURMV]
- [OC_MINI(BInterSAD(cpi,mb->yuv[0][3],0,goldenp,mv[3],0)>>6,15)];
+ cost += cpi->frag_bitrates[qi][0][CODE_INTER_FOURMV]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[0][3],0,goldenp,mv[3],0)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
/* Calculate motion vector as the average of the Y plane ones. */
/* Uncoded members are 0,0 and not special-cased */
@@ -408,11 +408,11 @@
ch.y = ( ch.y >= 0 ? (ch.y + 2) / 4 : (ch.y - 2) / 4);
if(cp[mb->yuv[1][0]])
- cost += OC_RES_BITRATES[qi][1][CODE_INTER_FOURMV]
- [OC_MINI(BInterSAD(cpi,mb->yuv[1][0],1,goldenp,ch,1)>>6,15)];
+ cost += cpi->frag_bitrates[qi][1][CODE_INTER_FOURMV]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[1][0],1,goldenp,ch,1)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
if(cp[mb->yuv[2][0]])
- cost += OC_RES_BITRATES[qi][2][CODE_INTER_FOURMV]
- [OC_MINI(BInterSAD(cpi,mb->yuv[2][0],2,goldenp,ch,1)>>6,15)];
+ cost += cpi->frag_bitrates[qi][2][CODE_INTER_FOURMV]
+ [OC_MINI(BInterSAD(cpi,mb->yuv[2][0],2,goldenp,ch,1)>>OC_SAD_SHIFT,OC_SAD_CLAMP)];
/* Bit costs are stored in the table with extra precision. Round them down to whole bits.*/
return cost + (1<<OC_BIT_SCALE-1) >> OC_BIT_SCALE;
@@ -569,7 +569,7 @@
if(cpi->FrameType != KEY_FRAME){
- //if(interbits>intrabits) return 1; /* short circuit */
+ if(interbits>intrabits) return 1; /* short circuit */
/* finish adding flagging overhead costs to inter bit counts */
@@ -580,7 +580,7 @@
interbits+=cpi->chooser.scheme_bits[cpi->chooser.scheme_list[0]];
- //if(interbits>intrabits) return 1; /* short circuit */
+ if(interbits>intrabits) return 1; /* short circuit */
/* The easiest way to count the bits needed for coded/not coded fragments is
to code them. */
@@ -590,11 +590,168 @@
interbits += oggpackB_bits(cpi->oggbuffer) - bits;
}
- //if(interbits>intrabits) return 1;
+ if(interbits>intrabits) return 1;
}
return 0;
}
+static void UpdateModeEstimation(CP_INSTANCE *cpi){
+ /* compile collected SAD/rate metrics into an immediately useful
+ mode estimation form */
+ int qi,plane,mode,bin;
+
+ //for(qi=0;i<64;qi++)
+ qi = cpi->BaseQ;
+ for(plane=0;plane<3;plane++)
+ for(mode=0;mode<8;mode++)
+ for(bin=0;bin<OC_SAD_BINS;bin++){
+ int bits = cpi->frag_distort[qi][plane][mode][bin];
+ int frags = cpi->frag_distort_count[qi][plane][mode][bin];
+
+ if(frags){
+
+ while(bits > (1<<24)-(frags>>1)){
+ bits >>= 1;
+ frags >>= 1;
+ }
+ cpi->frag_distort[qi][plane][mode][bin] = bits;
+ cpi->frag_distort_count[qi][plane][mode][bin] = frags;
+ cpi->frag_bitrates[qi][plane][mode][bin] = (bits + (frags>>1)) / frags;
+
+ }else{
+ cpi->frag_bitrates[qi][plane][mode][bin] = 0;
+ }
+ }
+}
+
+static int ModeMetricsGroup(CP_INSTANCE *cpi, int group, int huffY, int huffC, int prerun){
+ int ti,plane;
+ int *stack = cpi->dct_eob_fi_stack[group];
+ int ty = cpi->dct_token_ycount[group];
+
+ for(ti=0;ti<cpi->dct_token_count[group];ti++){
+ int huff = (ti<ty?huffY:huffC);
+ int token = cpi->dct_token[group][ti];
+ int bits = cpi->HuffCodeLengthArray_VP3x[huff][token[i]] + cpi->ExtraBitLengths_VP3x[token[i]];
+
+ if(token>DCT_REPEAT_RUN4_TOKEN){
+ /* not an EOB run; this token belongs to a single fragment */
+
+
+
+ }else{
+ /* EOB run; its bits should be split up between all the fragments in the run */
+ int run = parse_eob_run(token, cpi->dct_token_eb[group][ti]);
+ int fracbits = ((bits<<OC_BIT_SCALE) + (run>>1))/run;
+ int eobptr = eobcounts[group];
+
+ if(ti+1<n){
+ /* EOB entirely ensconced within this group */
+ while(run--){
+ int fi = stack[eobptr++];
+ int bin = OC_MINI(sp[fi] >> OC_SAD_SHIFT, OC_SAD_CLAMP);
+ int plane = (fi < y ? 0 : (fi < u ? 1 : 2));
+
+
+
+ }else{
+ /* this EOB is the last token in this group, so it may span into the next group */
+ int n = cpi->dct_eob_fi_count[group];
+
+
+
+
+ while(run--){
+ int fi = stack[eobptr++];
+ int bin = OC_MINI(sp[fi] >> OC_SAD_SHIFT, OC_SAD_CLAMP);
+ int plane = (fi < y ? 0 : (fi < u ? 1 : 2));
+
+ int eobfi;
+ if(eobptr >= cpi->dct_eob_fi_count[group]){
+ eobptr = eobcounts[group+1]++;
+ eobfi = cpi->dct_eob_fi_stack[group+1][eobptr];
+ }else{
+ eobcounts[group]++;
+ eobfi = cpi->dct_eob_fi_stack[group][eobptr];
+ }
+
+ int
+
+
+ }
+
+ }
+ }
+
+ int i;
+ oggpack_buffer *opb=cpi->oggbuffer;
+ int y = cpi->dct_token_ycount[group];
+ unsigned char *token = cpi->dct_token[group];
+ ogg_uint16_t *eb = cpi->dct_token_eb[group];
+
+ for(i=0; i<y; i++){
+ oggpackB_write( opb, cpi->HuffCodeArray_VP3x[huffY][token[i]],
+ cpi->HuffCodeLengthArray_VP3x[huffY][token[i]] );
+ if (cpi->ExtraBitLengths_VP3x[token[i]] > 0)
+ oggpackB_write( opb, eb[i], cpi->ExtraBitLengths_VP3x[token[i]] );
+ }
+
+ for(; i<cpi->dct_token_count[group]; i++){
+ oggpackB_write( opb, cpi->HuffCodeArray_VP3x[huffC][token[i]],
+ cpi->HuffCodeLengthArray_VP3x[huffC][token[i]] );
+ if (cpi->ExtraBitLengths_VP3x[token[i]] > 0)
+ oggpackB_write( opb, eb[i], cpi->ExtraBitLengths_VP3x[token[i]] );
+ }
+}
+
+
+
+
+
+
+
+}
+
+void ModeMetrics(CP_INSTANCE *cpi, int huff[4]){
+ int fi,ti,gi,n;
+ int y = cpi->frag_n[0];
+ int u = y + cpi->frag_n[1];
+ int v = y + cpi->frag_total;
+ unsigned char *cp = cpi->frag_coded;
+ unsigned char *sp = cpi->frag_sad;
+ unsigned char *mp = cpi->frag_mbi;
+ int eobcounts[64];
+ int qi = cpi->BaseQ; /* temporary */
+
+ memset(eobcounts,0,sizeof(eobcounts));
+
+ /* count coded frags by mode and SAD bin */
+ for(fi=0;fi<v;fi++)
+ if(cp[fi]){
+ macroblock_t *mb = cpi->macro[mp[fi]];
+ int mode = mb->mode;
+ int bin = OC_MINI(sp[fi] >> OC_SAD_SHIFT, OC_SAD_CLAMP);
+ int plane = (fi < y ? 0 : (fi < u ? 1 : 2));
+ cpi->frag_distort_count[qi][plane][mode][bin]++;
+ }
+
+ /* count bits for tokens */
+ ModeMetricsGroup(cpi, 0, huff[0], huff[1]);
+
+ for(gi=1;gi<=AC_TABLE_2_THRESH;gi++)
+ ModeMetricsGroup(cpi, gi, huff[2], huff[3]);
+ for(;gi<=AC_TABLE_3_THRESH;gi++)
+ ModeMetricsGroup(cpi, gi, huff[2]+AC_HUFF_CHOICES, huff[3]+AC_HUFF_CHOICES);
+ for(;gi<=AC_TABLE_4_THRESH;gi++)
+ ModeMetricsGroup(cpi, gi, huff[2]+AC_HUFF_CHOICES*2, huff[3]+AC_HUFF_CHOICES*2);
+ for(;gi<=BLOCK_SIZE;gi++)
+ ModeMetricsGroup(cpi, gi, huff[2]+AC_HUFF_CHOICES*3, huff[3]+AC_HUFF_CHOICES*3);
+
+ /* update global SAD/rate estimation matrix */
+ UpdateModeEstimation(cpi);
+
+
+}
Modified: branches/theora-thusnelda/lib/enc/mode_select.h
===================================================================
--- branches/theora-thusnelda/lib/enc/mode_select.h 2008-01-17 07:51:18 UTC (rev 14409)
+++ branches/theora-thusnelda/lib/enc/mode_select.h 2008-01-17 18:04:21 UTC (rev 14410)
@@ -17,6 +17,10 @@
#include "codec_internal.h"
+#define OC_SAD_BINS (16)
+#define OC_SAD_CLAMP (OC_SAD_BINS-1)
+#define OC_SAD_SHIFT (6)
+
#define OC_BIT_SCALE (7)
/* [qi][plane][mode][sad_bin] */
More information about the commits
mailing list