[xiph-commits] r15167 - branches/theora-thusnelda/lib/enc
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Fri Aug 8 14:53:24 PDT 2008
Author: xiphmont
Date: 2008-08-08 14:53:24 -0700 (Fri, 08 Aug 2008)
New Revision: 15167
Modified:
branches/theora-thusnelda/lib/enc/codec_internal.h
branches/theora-thusnelda/lib/enc/frarray.c
branches/theora-thusnelda/lib/enc/mode.c
Log:
Commit work in progress: account for block coding flag overhead when calculating block coding costs.
Completely untested code: DON'T RUN THIS ONE YET!
Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h 2008-08-08 15:43:31 UTC (rev 15166)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h 2008-08-08 21:53:24 UTC (rev 15167)
@@ -404,6 +404,7 @@
char sb_partial;
char sb_coded;
+ int cost;
} fr_state_t;
void fr_clear(CP_INSTANCE *cpi, fr_state_t *fr);
@@ -411,6 +412,7 @@
void fr_codeblock(CP_INSTANCE *cpi, fr_state_t *fr);
void fr_finishsb(CP_INSTANCE *cpi, fr_state_t *fr);
void fr_write(CP_INSTANCE *cpi, fr_state_t *fr);
+int fr_block_coding_cost(CP_INSTANCE *cpi, fr_state_t *fr);
#ifdef COLLECT_METRICS
extern void ModeMetrics(CP_INSTANCE *cpi);
Modified: branches/theora-thusnelda/lib/enc/frarray.c
===================================================================
--- branches/theora-thusnelda/lib/enc/frarray.c 2008-08-08 15:43:31 UTC (rev 15166)
+++ branches/theora-thusnelda/lib/enc/frarray.c 2008-08-08 21:53:24 UTC (rev 15167)
@@ -38,6 +38,8 @@
fr->cpi_partial_count=0;
fr->cpi_full_count=0;
fr->cpi_block_count=0;
+
+ fr->cost=0;
}
static int Brun( ogg_uint32_t value, ogg_int16_t *token) {
@@ -72,6 +74,23 @@
}
}
+static int BrunCost( ogg_uint32_t value ) {
+
+ if ( value <= 2 ) {
+ return 2;
+ } else if ( value <= 4 ) {
+ return 3;
+ } else if ( value <= 6 ) {
+ return 4;
+ } else if ( value <= 10 ) {
+ return 6;
+ } else if ( value <= 14 ) {
+ return 7;
+ } else {
+ return 9;
+ }
+}
+
void fr_skipblock(CP_INSTANCE *cpi, fr_state_t *fr){
if(fr->sb_coded){
if(!fr->sb_partial){
@@ -82,6 +101,7 @@
/* first run of the frame */
cpi->fr_block[fr->cpi_block_count]=1;
cpi->fr_block_bits[fr->cpi_block_count]=1;
+ fr->cost++;
fr->cpi_block_count++;
fr->b_last = 1;
}
@@ -91,7 +111,8 @@
fr->b_count += fr->b_pend;
}else{
/* in-progress run an uncoded run; flush */
- cpi->fr_block_bits[fr->cpi_block_count] =
+ fr->cost +=
+ cpi->fr_block_bits[fr->cpi_block_count] =
Brun(fr->b_count, cpi->fr_block+fr->cpi_block_count);
fr->cpi_block_count++;
fr->b_count=fr->b_pend;
@@ -103,7 +124,8 @@
if(fr->b_last == 0){
fr->b_count++;
}else{
- cpi->fr_block_bits[fr->cpi_block_count] =
+ fr->cost+=
+ cpi->fr_block_bits[fr->cpi_block_count] =
Brun(fr->b_count, cpi->fr_block+fr->cpi_block_count);
fr->cpi_block_count++;
fr->b_count = 1;
@@ -125,6 +147,7 @@
/* first run of the frame */
cpi->fr_block[fr->cpi_block_count]=0;
cpi->fr_block_bits[fr->cpi_block_count]=1;
+ fr->cost++;
fr->cpi_block_count++;
fr->b_last = 0;
}
@@ -134,7 +157,8 @@
fr->b_count += fr->b_pend;
}else{
/* in-progress run a coded run; flush */
- cpi->fr_block_bits[fr->cpi_block_count] =
+ fr->cost+=
+ cpi->fr_block_bits[fr->cpi_block_count] =
Brun(fr->b_count, cpi->fr_block+fr->cpi_block_count);
fr->cpi_block_count++;
fr->b_count=fr->b_pend;
@@ -146,7 +170,8 @@
if(fr->b_last == 1){
fr->b_count++;
}else{
- cpi->fr_block_bits[fr->cpi_block_count] =
+ fr->cost+=
+ cpi->fr_block_bits[fr->cpi_block_count] =
Brun(fr->b_count, cpi->fr_block+fr->cpi_block_count);
fr->cpi_block_count++;
fr->b_count = 1;
@@ -194,12 +219,32 @@
}
}
+static int SBRunCost(ogg_uint32_t value){
+
+ if ( value == 1 ){
+ return 1;
+ } else if ( value <= 3 ) {
+ return 3;
+ } else if ( value <= 5 ) {
+ return 4;
+ } else if ( value <= 9 ) {
+ return 6;
+ } else if ( value <= 17 ) {
+ return 8;
+ } else if ( value <= 33 ) {
+ return 10;
+ } else {
+ return 18;
+ }
+}
+
void fr_finishsb(CP_INSTANCE *cpi, fr_state_t *fr){
/* update partial state */
int partial = (fr->sb_partial & fr->sb_coded);
if(fr->sb_partial_last == -1){
cpi->fr_partial[fr->cpi_partial_count] = partial;
cpi->fr_partial_bits[fr->cpi_partial_count] = 1;
+ fr->cost++;
fr->cpi_partial_count++;
fr->sb_partial_last = partial;
}
@@ -210,11 +255,13 @@
if(fr->sb_partial_break){
cpi->fr_partial[fr->cpi_partial_count] = partial;
cpi->fr_partial_bits[fr->cpi_partial_count] = 1;
+ fr->cost++;
fr->cpi_partial_count++;
}
fr->sb_partial_break=0;
- cpi->fr_partial_bits[fr->cpi_partial_count] =
+ fr->cost+=
+ cpi->fr_partial_bits[fr->cpi_partial_count] =
SBRun( fr->sb_partial_count, cpi->fr_partial+fr->cpi_partial_count);
fr->cpi_partial_count++;
@@ -229,6 +276,7 @@
if(fr->sb_full_last == -1){
cpi->fr_full[fr->cpi_full_count] = fr->sb_coded;
cpi->fr_full_bits[fr->cpi_full_count] = 1;
+ fr->cost++;
fr->cpi_full_count++;
fr->sb_full_last = fr->sb_coded;
}
@@ -239,11 +287,13 @@
if(fr->sb_full_break){
cpi->fr_full[fr->cpi_full_count] = fr->sb_coded;
cpi->fr_full_bits[fr->cpi_full_count] = 1;
+ fr->cost++;
fr->cpi_full_count++;
}
fr->sb_full_break=0;
- cpi->fr_full_bits[fr->cpi_full_count] =
+ fr->cost+=
+ cpi->fr_full_bits[fr->cpi_full_count] =
SBRun( fr->sb_full_count, cpi->fr_full+fr->cpi_full_count);
fr->cpi_full_count++;
if(fr->sb_full_count >= 4129) fr->sb_full_break = 1;
@@ -258,15 +308,99 @@
fr->sb_coded=0;
}
+int fr_block_coding_cost(CP_INSTANCE *cpi, fr_state_t *fr){
+ int coded=0, uncoded=0;
+
+ if(fr->b_pend == 0){
+ /* first block in SB */
+
+ /* if(fr->sb_partial_last==1){ */
+ /* last SB was partially coded; no opportunity cost one way or the other */
+ /* } */
+
+ if(fr->sb_partial_last==0){
+ if(fr->sb_full_last==1){
+ /* last SB was fully coded */
+ /* if next block is uncoded, the result may be a partial or
+ fully uncoded superblock, but we don't know which yet.
+ The certain cost is the minimum of the two. */
+ int uncoded1 = SBRunCost( fr->sb_full_count );
+ int uncoded2 = SBRunCost( fr->sb_partial_count );
+ uncoded += OC_MINI(uncoded1, uncoded2);
+
+ if(fr->sb_full_count+1 >= 4129)
+ coded += SBRunCost( fr->sb_full_count )+1;
+
+ }
+ if(fr->sb_full_last==0){
+ /* last SB was fully uncoded */
+ /* if next block is coded, the result may be a partial or
+ fully coded superblock, but we don't know which yet.
+ The certain cost is the minimum of the two. */
+ int coded1 = SBRunCost( fr->sb_full_count );
+ int coded2 = SBRunCost( fr->sb_partial_count );
+ coded += OC_MINI(coded1, coded2);
+ if(fr->sb_full_count+1 >= 4129)
+ uncoded += SBRunCost( fr->sb_full_count )+1;
+
+ }
+ }
+
+ /* this is the first block in the SB, so it always begins a block-run; there is no block opportunity cost either way */
+
+ }else{
+ if(fr->sb_partial){
+ if(fr->sb_coded){
+ /* SB is partially coded to this point; only new costs are block-run costs */
+
+ if(fr->b_last == 0){
+ coded += BrunCost(fr->b_count);
+ }else{
+ uncoded += BrunCost(fr->b_count);
+ }
+
+ }else{
+ /* SB is fully uncoded to this point */
+
+ /* coded cost reflects transition from uncoded -> partial */
+ coded += BrunCost(fr->b_pend);
+
+ if(fr->sb_partial_last==0){
+ coded += SBRunCost( fr->sb_partial_count );
+ }else
+ if(fr->sb_partial_count+1 >= 4129)
+ coded += SBRunCost( fr->sb_partial_count )+1;
+
+ }
+ }else{
+ /* SB is fully coded to this point */
+
+ uncoded += BrunCost(fr->b_pend);
+
+ /* uncoded cost reflects transition from coded -> partial */
+ uncoded += BrunCost(fr->b_pend);
+
+ if(fr->sb_partial_last==0){
+ uncoded += SBRunCost( fr->sb_partial_count );
+ }else
+ if(fr->sb_partial_count+1 >= 4129)
+ uncoded += SBRunCost( fr->sb_partial_count )+1;
+ }
+ }
+ return coded-uncoded;
+}
+
static void fr_flush(CP_INSTANCE *cpi, fr_state_t *fr){
/* flush any pending partial run */
if(fr->sb_partial_break){
cpi->fr_partial[fr->cpi_partial_count] = fr->sb_partial_last;
cpi->fr_partial_bits[fr->cpi_partial_count] = 1;
+ fr->cost++;
fr->cpi_partial_count++;
}
if(fr->sb_partial_count){
- cpi->fr_partial_bits[fr->cpi_partial_count] =
+ fr->cost+=
+ cpi->fr_partial_bits[fr->cpi_partial_count] =
SBRun( fr->sb_partial_count, cpi->fr_partial+fr->cpi_partial_count);
fr->cpi_partial_count++;
}
@@ -275,17 +409,20 @@
if(fr->sb_full_break){
cpi->fr_full[fr->cpi_full_count] = fr->sb_full_last;
cpi->fr_full_bits[fr->cpi_full_count] = 1;
+ fr->cost++;
fr->cpi_full_count++;
}
if(fr->sb_full_count){
- cpi->fr_full_bits[fr->cpi_full_count] =
+ fr->cost+=
+ cpi->fr_full_bits[fr->cpi_full_count] =
SBRun( fr->sb_full_count, cpi->fr_full+fr->cpi_full_count);
fr->cpi_full_count++;
}
/* flush any pending block run */
if(fr->b_count){
- cpi->fr_block_bits[fr->cpi_block_count] =
+ fr->cost+=
+ cpi->fr_block_bits[fr->cpi_block_count] =
Brun(fr->b_count, cpi->fr_block+fr->cpi_block_count);
fr->cpi_block_count++;
}
Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c 2008-08-08 15:43:31 UTC (rev 15166)
+++ branches/theora-thusnelda/lib/enc/mode.c 2008-08-08 21:53:24 UTC (rev 15167)
@@ -487,7 +487,6 @@
typedef struct{
int uncoded_ssd;
- int uncoded_cost;
int ssd;
int cost;
} rd_metric_t;
@@ -529,7 +528,7 @@
}
static int TQB (CP_INSTANCE *cpi, plane_state_t *ps, int mode, int fi, mv_t mv,
- int uncoded_overhead, int coded_overhead, rd_metric_t *mo, long *rho_count,
+ int coding_overhead, rd_metric_t *mo, long *rho_count,
token_checkpoint_t **stack){
int keyframe = (cpi->FrameType == KEY_FRAME);
@@ -697,19 +696,14 @@
uncoded_ssd*=ps->ssdmul;
mo->uncoded_ssd+=uncoded_ssd;
- mo->uncoded_cost+=(uncoded_overhead<<OC_BIT_SCALE);
/* the partial_ssd underreports distortion, so this comparison
will only yield false negatives, which are harmless */
- if(uncoded_ssd+uncoded_overhead*lambda <=
- coded_partial_ssd+coded_overhead*lambda+((sad_cost*lambda)>>OC_BIT_SCALE)){
+ if(uncoded_ssd <= coded_partial_ssd+coding_overhead*lambda+((sad_cost*lambda)>>OC_BIT_SCALE)){
/* SKIP */
uncode_frag(cpi,fi,ps->plane);
-
mo->ssd+=uncoded_ssd;
- mo->cost+=(uncoded_overhead<<OC_BIT_SCALE);
-
return 0;
}
@@ -751,20 +745,19 @@
/* for undersampled planes */
coded_ssd*=ps->ssdmul;
- if(uncoded_ssd+uncoded_overhead*lambda <= coded_ssd+coded_overhead*lambda+((sad_cost*lambda)>>OC_BIT_SCALE)){
+ if(uncoded_ssd <= coded_ssd+coding_overhead*lambda+((sad_cost*lambda)>>OC_BIT_SCALE)){
/* Hm, not worth it. roll back */
tokenlog_rollback(cpi, checkpoint, (*stack)-checkpoint);
*stack = checkpoint;
uncode_frag(cpi,fi,ps->plane);
mo->ssd+=uncoded_ssd;
- mo->cost+=(uncoded_overhead<<OC_BIT_SCALE);
return 0;
}else{
mo->ssd+=coded_ssd;
- mo->cost+=sad_cost+(coded_overhead<<OC_BIT_SCALE);
+ mo->cost+=sad_cost;
}
}
@@ -779,14 +772,14 @@
int mode = mb->mode;
int coded = 0;
int i;
- fr_state_t fr_checkpoint;
+ fr_state_t fr_nocode;
token_checkpoint_t stack[64*5]; /* worst case token usage for 4 fragments*/
token_checkpoint_t *stackptr = stack;
rd_metric_t mo;
memset(&mo,0,sizeof(mo));
- memcpy(&fr_checkpoint,fr,sizeof(fr_checkpoint));
+ memcpy(&fr_nocode,fr,sizeof(fr_nocode));
for(i=0;i<4;i++){
/* Blocks must be handled in Hilbert order which is defined by MB
@@ -794,7 +787,9 @@
raster order just to make it more difficult. */
int bi = macroblock_phase_Y[mb_phase][i];
int fi = mb->Ryuv[0][bi];
- if(TQB(cpi,ps,mode,fi,mb->mv[bi],0,0,&mo,rc,&stackptr)){
+
+ fr_skipblock(cpi,&fr_nocode);
+ if(TQB(cpi,ps,mode,fi,mb->mv[bi],fr_block_coding_cost(cpi,fr),&mo,rc,&stackptr)){
fr_codeblock(cpi,fr);
coded++;
}else{
@@ -803,22 +798,21 @@
mb->mv[bi]=(mv_t){0,0};
}
}
+
-
if(cpi->FrameType != KEY_FRAME){
if(coded){
/* block by block, still coding the MB. Now consider the
macroblock coding cost as a whole (mode and MV) */
- if(mo.uncoded_ssd+((cpi->skip_lambda*mo.uncoded_cost)>>OC_BIT_SCALE) <=
- mo.ssd+((cpi->skip_lambda*(mo.cost+mode_overhead))>>(OC_BIT_SCALE))){
-
+ int fr_overhead = fr->cost - fr_nocode.cost;
+ if(mo.uncoded_ssd <= mo.ssd+((cpi->skip_lambda*(mo.cost+fr_overhead+mode_overhead))>>(OC_BIT_SCALE))){
+
/* taking macroblock overhead into account, it is not worth coding this MB */
tokenlog_rollback(cpi, stack, stackptr-stack);
-
- memcpy(fr,&fr_checkpoint,sizeof(fr_checkpoint));
+
+ memcpy(fr,&fr_nocode,sizeof(fr_nocode));
for(i=0;i<4;i++){
int fi = mb->Ryuv[0][i];
- fr_skipblock(cpi,fr);
if(cp[fi])
uncode_frag(cpi,fi,0);
}
@@ -912,7 +906,7 @@
}else
mv = mb->mv[0];
- if(TQB(cpi,ps,mb->mode,fi,mv,0,0,&mo,rc,&stackptr)){
+ if(TQB(cpi,ps,mb->mode,fi,mv,fr_block_coding_cost(cpi,fr),&mo,rc,&stackptr)){
fr_codeblock(cpi,fr);
tokenlog_commit(cpi, stack, stackptr-stack);
coded++;
More information about the commits
mailing list