[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