[xiph-commits] r15047 - branches/theora-thusnelda/lib/enc

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Tue Jun 17 04:22:43 PDT 2008


Author: xiphmont
Date: 2008-06-17 04:22:43 -0700 (Tue, 17 Jun 2008)
New Revision: 15047

Modified:
   branches/theora-thusnelda/lib/enc/mode.c
Log:
Take MB coding overhead into account when evaluating blocks/MBs for 
SKIP.  Still does not account for SB DFarray coding flag overhead.



Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c	2008-06-17 11:08:24 UTC (rev 15046)
+++ branches/theora-thusnelda/lib/enc/mode.c	2008-06-17 11:22:43 UTC (rev 15047)
@@ -245,7 +245,8 @@
   ogg_int32_t *y = lookup + bin;
   int xdel = sad - (bin<<OC_SAD_SHIFT);
   int ydel = y[1] - y[0];
-  return y[0] + ((ydel*xdel)>>OC_SAD_SHIFT);
+  int ret = y[0] + ((ydel*xdel)>>OC_SAD_SHIFT);
+  return ret;
 }
 
 static const int mvmap[2][63] = {
@@ -318,7 +319,7 @@
   }
 }
 
-static int cost_intra(CP_INSTANCE *cpi, int qi, int mbi, ogg_uint32_t *intrabits){
+static int cost_intra(CP_INSTANCE *cpi, int qi, int mbi, ogg_uint32_t *intrabits, int *overhead){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
   int i,j;
@@ -333,10 +334,11 @@
     }
   }
   *intrabits+=cost;
-  return cost + (oc_mode_cost(cpi,1) << OC_BIT_SCALE);
+  *overhead = (oc_mode_cost(cpi,1) << OC_BIT_SCALE);
+  return cost + *overhead;
 }
 
-static int cost_inter(CP_INSTANCE *cpi, int qi, int mbi, mv_t mv, int mode){
+static int cost_inter(CP_INSTANCE *cpi, int qi, int mbi, mv_t mv, int mode, int *overhead){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
   int i,j;
@@ -350,10 +352,11 @@
       }
     }
   }
-  return cost + (oc_mode_cost(cpi,mode) << OC_BIT_SCALE);
+  *overhead = (oc_mode_cost(cpi,mode) << OC_BIT_SCALE);
+  return cost + *overhead;
 }
 
-static int cost_inter_nomv(CP_INSTANCE *cpi, int qi, int mbi){
+static int cost_inter_nomv(CP_INSTANCE *cpi, int qi, int mbi, int *overhead){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
   int i,j;
@@ -372,10 +375,11 @@
       }
     }
   }
-  return cost + (oc_mode_cost(cpi,CODE_INTER_NO_MV) << OC_BIT_SCALE);
+  *overhead = (oc_mode_cost(cpi,CODE_INTER_NO_MV) << OC_BIT_SCALE);
+  return cost + *overhead;
 }
 
-static int cost_inter1mv(CP_INSTANCE *cpi, int qi, int mbi, int golden, int *bits0){
+static int cost_inter1mv(CP_INSTANCE *cpi, int qi, int mbi, int golden, int *bits0, int *overhead){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
   int i,j;
@@ -390,16 +394,18 @@
       }
     }
   }
-  cost += oc_mode_cost(cpi,golden?CODE_GOLDEN_MV:CODE_INTER_PLUS_MV) << OC_BIT_SCALE;
-
+  
   *bits0  = MvBits[mb->analysis_mv[0][golden].x + MAX_MV_EXTENT] + 
     MvBits[mb->analysis_mv[0][golden].y + MAX_MV_EXTENT];
   
-  return cost + ((OC_MINI(cpi->MVBits_0 + *bits0, cpi->MVBits_1+12)-
-		  OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+  *overhead = (oc_mode_cost(cpi,golden?CODE_GOLDEN_MV:CODE_INTER_PLUS_MV) +
+	       (OC_MINI(cpi->MVBits_0 + *bits0, cpi->MVBits_1+12)-
+		OC_MINI(cpi->MVBits_0, cpi->MVBits_1))) << OC_BIT_SCALE;
+  
+  return cost + *overhead;
 }
 
-static int cost_inter4mv(CP_INSTANCE *cpi, int qi, int mbi, int *bits0, int *bits1){
+static int cost_inter4mv(CP_INSTANCE *cpi, int qi, int mbi, int *bits0, int *bits1, int *overhead){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
   int j;
@@ -437,7 +443,6 @@
     }
   }
 
-  cost += (oc_mode_cost(cpi,CODE_INTER_FOURMV) << OC_BIT_SCALE);
 
   *bits0 = *bits1 = 0;
 
@@ -453,9 +458,11 @@
   *bits0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] + 
     MvBits[mb->mv[3].y+MAX_MV_EXTENT];
   *bits1 += 12;
-      
-  return cost + ((OC_MINI(cpi->MVBits_0 + *bits0, cpi->MVBits_1 + *bits1)-
-		  OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+
+  *overhead = (oc_mode_cost(cpi,CODE_INTER_FOURMV) +
+	       (OC_MINI(cpi->MVBits_0 + *bits0, cpi->MVBits_1 + *bits1)-
+		OC_MINI(cpi->MVBits_0, cpi->MVBits_1))) << OC_BIT_SCALE;
+  return cost + *overhead;
 }
 
 static void MBSAD420(CP_INSTANCE *cpi, int mbi, mv_t last, mv_t last2,
@@ -502,11 +509,16 @@
 
 #include "quant_lookup.h"
 
-#include <stdio.h>
+static void uncode_frag(CP_INSTANCE *cpi, int fi, int plane){
+  int bi = cpi->frag_buffer_index[fi];
+  int stride = cpi->stride[plane];
 
+  cpi->frag_coded[fi]=0;
+  dsp_copy8x8 (cpi->dsp, cpi->lastrecon+bi, cpi->recon+bi, stride);
+}      
 
 static int TQB (CP_INSTANCE *cpi, int mode, int fi, mv_t mv, int plane, ogg_int16_t re_q[2][3][64], 
-		 long *rho_count, int keyframe){
+		 long *rho_count, int keyframe, int *uncoded_ssd_acc, int *coded_ssd_acc, int *cost_acc){
 
   int qi = cpi->BaseQ; /* temporary */;
   int inter = (mode != CODE_INTRA);
@@ -653,36 +665,53 @@
     }
     
     if(uncoded_ssd <= coded_ssd+((cpi->skip_lambda*cost)>>(OC_BIT_SCALE))){ 
-      /* mark uncoded */
-      cpi->frag_coded[fi]=0;
-      
-      /* replace reconstruction with a block copy */
-      dsp_copy8x8 (cpi->dsp, cpi->lastrecon+bi, thisrecon, stride);
-      
+      uncode_frag(cpi,fi,plane);
       return 0;
     }
+
+    *uncoded_ssd_acc+=uncoded_ssd;
+    *coded_ssd_acc+=coded_ssd;
+    *cost_acc+=cost;
+
   }
     
-
   return 1;
 }
 
-static int TQMB ( CP_INSTANCE *cpi, macroblock_t *mb, 
-		  int qi, ogg_int16_t req[2][3][64], long *rc, int keyframe){
+static int TQMB ( CP_INSTANCE *cpi, macroblock_t *mb, int mbphase,
+		  int qi, ogg_int16_t req[2][3][64], long *rc, int keyframe, int overhead){
   int pf = cpi->info.pixelformat;
   int mode = mb->mode;
   int i;
   int coded=0;
+  int coded_ssd=0;
+  int uncoded_ssd=0;
+  int coded_cost=0;
+
+  int ysb_coded = 0;
+  int ysb_partial = 0;
+  int usb_coded = 0;
+  int usb_partial = 0;
+  int vsb_coded = 0;
+  int vsb_partial = 0;
+
   superblock_t *ysb = &cpi->super[0][mb->ysb];
   superblock_t *usb = &cpi->super[0][mb->usb];
   superblock_t *vsb = &cpi->super[0][mb->vsb];
 
+  /* It's exceptionally difficult in the current Theora coding
+     structure to take the global superblock coding runs into account
+     when computing relative bitcosts in block coding decisions, but
+     this is a relatively exceedingly minor cost consideration.  We do
+     account for the local coding costs of skip blocks within the
+     superblock, a more significant contribution to consider. */
+
   for(i=0;i<4;i++){
-    if(TQB(cpi,mode,mb->Ryuv[0][i],mb->mv[i],0,req,rc,keyframe)){
-      ysb->coded=1;
+    if(TQB(cpi,mode,mb->Ryuv[0][i],mb->mv[i],0,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+      ysb_coded=1;
       coded++;
     }else{
-      ysb->partial=1;
+      ysb_partial=1;
       if(mode == CODE_INTER_FOURMV) 
 	mb->mv[i]=(mv_t){0,0};
     }
@@ -708,17 +737,17 @@
       }else{
 	mv = mb->mv[0];
       }
-      if(TQB(cpi,mode,mb->Ryuv[1][0],mv,1,req,rc,keyframe)){
-	usb->coded=1;
+      if(TQB(cpi,mode,mb->Ryuv[1][0],mv,1,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+	usb_coded=1;
 	coded++;
       }else{
-	usb->partial=1;
+	usb_partial=1;
       }
-      if(TQB(cpi,mode,mb->Ryuv[2][0],mv,2,req,rc,keyframe)){
-	vsb->coded=1;
+      if(TQB(cpi,mode,mb->Ryuv[2][0],mv,2,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+	vsb_coded=1;
 	coded++;
       }else{
-	vsb->partial=1;
+	vsb_partial=1;
       }
     }
     break;
@@ -739,43 +768,75 @@
       }
 
       for(i=0;i<2;i++)
-	if(TQB(cpi,mode,mb->Ryuv[1][i],mv[i],1,req,rc,keyframe)){
-	  usb->coded=1;
+	if(TQB(cpi,mode,mb->Ryuv[1][i],mv[i],1,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+	  usb_coded=1;
 	  coded++;
 	}else{
-	  usb->partial=1;
+	  usb_partial=1;
 	}
 
       for(i=0;i<2;i++)
-	if(TQB(cpi,mode,mb->Ryuv[2][i],mv[i],2,req,rc,keyframe)){
-	  vsb->coded=1;
+	if(TQB(cpi,mode,mb->Ryuv[2][i],mv[i],2,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+	  vsb_coded=1;
 	  coded++;
 	}else{
-	  vsb->partial=1;
+	  vsb_partial=1;
 	}
     }
     break;
     
   case OC_PF_444:
     for(i=0;i<4;i++)
-      if(TQB(cpi,mode,mb->Ryuv[1][i],mb->mv[i],1,req,rc,keyframe)){
-	usb->coded=1;
+      if(TQB(cpi,mode,mb->Ryuv[1][i],mb->mv[i],1,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+	usb_coded=1;
 	coded++;
       }else{
-	usb->partial=1;
+	usb_partial=1;
       }
 
     for(i=0;i<4;i++)
-      if(TQB(cpi,mode,mb->Ryuv[2][i],mb->mv[i],2,req,rc,keyframe)){
-	vsb->coded=1;
+      if(TQB(cpi,mode,mb->Ryuv[2][i],mb->mv[i],2,req,rc,keyframe, &uncoded_ssd, &coded_ssd, &coded_cost)){
+	vsb_coded=1;
 	coded++;
       }else{
-	vsb->partial=1;
+	vsb_partial=1;
       }
     
     break;
   }
+
+  if(coded && !keyframe){
+    /* block by block, still coding the MB.  Now consider the
+       macroblock coding cost as a whole (mode and MV) */ 
+    if(uncoded_ssd <= coded_ssd+((cpi->skip_lambda*(coded_cost+overhead))>>(OC_BIT_SCALE))){     
+      /* taking macroblock overhead into account, it is not worth coding this MB */
+      int j;
+      for(j=0;j<3;j++){
+	for(i=0;i<4;i++){
+	  int fi = mb->Ryuv[j][i];
+	  if(cpi->frag_coded[fi])
+	    uncode_frag(cpi,fi,j);
+	}
+      }
+
+      mb->mode = CODE_INTER_NO_MV; 
+      mb->coded = 0;
+      mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
+
+      ysb->partial = 1;
+      usb->partial = 1;
+      vsb->partial = 1;
+
+      return 0;
+    }
+  }
   
+  ysb->coded |= ysb_coded;
+  ysb->partial |= ysb_partial;
+  usb->coded |= usb_coded;
+  usb->partial |= usb_partial;
+  vsb->coded |= vsb_coded;
+  vsb->partial |= vsb_partial;
   return coded;
   
 }
@@ -828,6 +889,7 @@
       if(mbi >= cpi->macro_total) continue;
 
       int cost[8] = {0,0,0,0, 0,0,0,0};
+      int overhead[8] = {0,0,0,0, 0,0,0,0};
       int mb_mv_bits_0;
       int mb_gmv_bits_0;
       int mb_4mv_bits_0;
@@ -856,7 +918,7 @@
       if(cpi->FrameType == KEY_FRAME){
 	mb->mode = CODE_INTRA;
 	/* Transform, quantize, collect rho metrics */
-	TQMB(cpi, mb, qi, req, rho_count, 1);
+	TQMB(cpi, mb, j, qi, req, rho_count, 1, 0);
 	
       }else{
 
@@ -871,14 +933,22 @@
 	/* block coding cost is estimated from correlated SAD metrics */
 	/* At this point, all blocks that are in frame are still marked coded */
 
-	cost[CODE_INTER_NO_MV] = cost_inter_nomv(cpi, qi, mbi);
-	cost[CODE_INTRA] = cost_intra(cpi, qi, mbi, &intrabits);
-	cost[CODE_INTER_PLUS_MV] = cost_inter1mv(cpi, qi, mbi, 0, &mb_mv_bits_0);
-	cost[CODE_INTER_LAST_MV] = cost_inter(cpi, qi, mbi, last_mv, CODE_INTER_LAST_MV);
-	cost[CODE_INTER_PRIOR_LAST] = cost_inter(cpi, qi, mbi, prior_mv, CODE_INTER_PRIOR_LAST);
-	cost[CODE_USING_GOLDEN] = cost_inter(cpi, qi, mbi, (mv_t){0,0},CODE_USING_GOLDEN);
-	cost[CODE_GOLDEN_MV] = cost_inter1mv(cpi, qi, mbi, 1, &mb_gmv_bits_0);
-	cost[CODE_INTER_FOURMV] = cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1);
+	cost[CODE_INTER_NO_MV] = 
+	  cost_inter_nomv(cpi, qi, mbi, &overhead[CODE_INTER_NO_MV]);
+	cost[CODE_INTRA] = 
+	  cost_intra(cpi, qi, mbi, &intrabits, &overhead[CODE_INTRA]);
+	cost[CODE_INTER_PLUS_MV] = 
+	  cost_inter1mv(cpi, qi, mbi, 0, &mb_mv_bits_0, &overhead[CODE_INTER_PLUS_MV]);
+	cost[CODE_INTER_LAST_MV] = 
+	  cost_inter(cpi, qi, mbi, last_mv, CODE_INTER_LAST_MV, &overhead[CODE_INTER_LAST_MV]);
+	cost[CODE_INTER_PRIOR_LAST] = 
+	  cost_inter(cpi, qi, mbi, prior_mv, CODE_INTER_PRIOR_LAST, &overhead[CODE_INTER_PRIOR_LAST]);
+	cost[CODE_USING_GOLDEN] = 
+	  cost_inter(cpi, qi, mbi, (mv_t){0,0},CODE_USING_GOLDEN, &overhead[CODE_USING_GOLDEN]);
+	cost[CODE_GOLDEN_MV] = 
+	  cost_inter1mv(cpi, qi, mbi, 1, &mb_gmv_bits_0, &overhead[CODE_GOLDEN_MV]);
+	cost[CODE_INTER_FOURMV] = 
+	  cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1, &overhead[CODE_INTER_FOURMV]);
 	
 	/* train this too... because the bit cost of an MV should be
 	   considered in the context of LAST_MV and PRIOR_LAST. */
@@ -889,13 +959,16 @@
 	   already furthest ahead on bits and refine only that one */
 	if(cost[CODE_INTER_FOURMV]<cost[CODE_INTER_PLUS_MV] && cost[CODE_INTER_FOURMV]<cost[CODE_GOLDEN_MV]){
 	  oc_mcenc_refine4mv(cpi, mbi, block_err);
-	  cost[CODE_INTER_FOURMV] = cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1);
+	  cost[CODE_INTER_FOURMV] = 
+	    cost_inter4mv(cpi, qi, mbi, &mb_4mv_bits_0, &mb_4mv_bits_1, &overhead[CODE_INTER_FOURMV]);
 	}else if (cost[CODE_GOLDEN_MV]<cost[CODE_INTER_PLUS_MV]){
 	  oc_mcenc_refine1mv(cpi, mbi, 1, gerror);
-	  cost[CODE_GOLDEN_MV] = cost_inter1mv(cpi, qi, mbi, 1, &mb_gmv_bits_0);
+	  cost[CODE_GOLDEN_MV] = 
+	    cost_inter1mv(cpi, qi, mbi, 1, &mb_gmv_bits_0, &overhead[CODE_GOLDEN_MV]);
 	}else{
 	  oc_mcenc_refine1mv(cpi, mbi, 0, aerror);
-	  cost[CODE_INTER_PLUS_MV] = cost_inter1mv(cpi, qi, mbi, 0, &mb_mv_bits_0);
+	  cost[CODE_INTER_PLUS_MV] = 
+	    cost_inter1mv(cpi, qi, mbi, 0, &mb_mv_bits_0, &overhead[CODE_INTER_PLUS_MV]);
 	  cost[CODE_INTER_PLUS_MV] -= 384;
 	}
 
@@ -936,7 +1009,7 @@
 	mb->mode = mode;
 	
 	/* Transform, quantize, collect rho metrics */
-	if(!TQMB(cpi, mb, qi, req, rho_count, 0)){
+	if(!TQMB(cpi, mb, j, qi, req, rho_count, 0, overhead[mode])){
 
 	  /* ended up not coding the macroblock at all */
 	  mb->coded = 0;
@@ -944,8 +1017,6 @@
 
 	}else{
 
-	  /* still coding the MB */
-
 	  /* replace the block MVs for not-coded blocks with (0,0).*/   
 	  mb->coded = 0;
 	  for ( bi=0; bi<4; bi++ ){



More information about the commits mailing list