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

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Fri Mar 28 10:18:41 PDT 2008


Author: xiphmont
Date: 2008-03-28 10:18:41 -0700 (Fri, 28 Mar 2008)
New Revision: 14644

Modified:
   branches/theora-thusnelda/lib/enc/mode.c
Log:
Minor reflow to SAD/bitcost estimation calculation toward trying out Derf's halfpel optimization suggestion.



Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c	2008-03-28 15:41:24 UTC (rev 14643)
+++ branches/theora-thusnelda/lib/enc/mode.c	2008-03-28 17:18:41 UTC (rev 14644)
@@ -249,40 +249,6 @@
   return y[0] + ((ydel*xdel)>>OC_SAD_SHIFT);
 }
 
-/* equivalent to adding up the abs values of the AC components of a block */
-static int MBIntraCost420(CP_INSTANCE *cpi, int qi, int mbi, int all){
-  unsigned char *cp = cpi->frag_coded;
-  macroblock_t *mb = &cpi->macro[mbi];
-  int cost=0;
-  int fi;
-  /* all frags in a macroblock are valid so long as the macroblock itself is valid */
-  if(mbi < cpi->macro_total){ 
-    fi = mb->Ryuv[0][0];
-    if(all || cp[fi])
-      cost += BINMAP(mode_rate[qi][0][1],BIntraSAD(cpi,fi,0));
-    fi = mb->Ryuv[0][1];
-    if(all || cp[fi])
-      cost += BINMAP(mode_rate[qi][0][1],BIntraSAD(cpi,fi,0));
-    fi = mb->Ryuv[0][2];
-    if(all || cp[fi])
-      cost += BINMAP(mode_rate[qi][0][1],BIntraSAD(cpi,fi,0));
-    fi = mb->Ryuv[0][3];
-    if(all || cp[fi])
-      cost += BINMAP(mode_rate[qi][0][1],BIntraSAD(cpi,fi,0));
-
-    fi = mb->Ryuv[1][0];
-    if(all || cp[fi])
-      cost += BINMAP(mode_rate[qi][1][1],BIntraSAD(cpi,fi,1));
-    fi = mb->Ryuv[2][0];
-    if(all || cp[fi])
-      cost += BINMAP(mode_rate[qi][2][1],BIntraSAD(cpi,fi,2));
-   
-  }
-  
-  /* Bit costs are stored in the table with extra precision. Round them down to whole bits.*/
-  return cost;
-}
-
 static signed char mvmap[2][63] = {
   {     -15,-15,-14, -14,-13,-13,-12, -12,-11,-11,-10, -10, -9, -9, -8,
      -8, -7, -7, -6,  -6, -5, -5, -4,  -4, -3, -3, -2,  -2, -1, -1,  0,
@@ -308,14 +274,18 @@
 static int BInterSAD(CP_INSTANCE *cpi, int fi, int plane, int goldenp, mv_t mv, int qp){
   int sad = 0;
   unsigned char *b = cpi->frame + cpi->frag_buffer_index[fi];
+  //#if 1
+  //mv.x=mv.x/2*2;
+  //mv.y=mv.y/2*2;
+  //#endif
   int mx = mvmap[qp][mv.x+31];
   int my = mvmap[qp][mv.y+31];
   int mx2 = mvmap2[qp][mv.x+31];
   int my2 = mvmap2[qp][mv.y+31];
+
   int stride = cpi->stride[plane];
   unsigned char *r = (goldenp ? cpi->golden : cpi->lastrecon ) + 
     cpi->frag_buffer_index[fi] + my * stride + mx;
-  int j,k;
   
   if(mx2 || my2){
     unsigned char *r2 = r + my2 * stride + mx2;
@@ -330,73 +300,68 @@
     return sad;
 }
 
-static int MBInterCost420(CP_INSTANCE *cpi, int qi, int mbi, mv_t mv, int goldenp){
+static void MBCost(CP_INSTANCE *cpi, int qi, int mbi, int cost[8], int sad[8][3][4]){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
-  int cost = 0;
-  int fi;
+  int i,j;
 
-  fi=mb->Ryuv[0][0];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv,0));
-  fi=mb->Ryuv[0][1];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv,0));
-  fi=mb->Ryuv[0][2];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv,0));
-  fi=mb->Ryuv[0][3];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv,0));
-
-  fi=mb->Ryuv[1][0];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][1][0],BInterSAD(cpi,fi,1,goldenp,mv,1));
-  fi=mb->Ryuv[2][0];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][2][0],BInterSAD(cpi,fi,2,goldenp,mv,1));
-
-  /* Bit costs are stored in the table with extra precision. Round them down to whole bits.*/
-  return cost;
+  for(i=0;i<3;i++){
+    for(j=0;j<4;j++){
+      int fi=mb->Ryuv[i][j];
+      if(cp[fi]){
+	cost[0] += BINMAP(mode_rate[qi][i][0],sad[0][i][j]);
+	cost[1] += BINMAP(mode_rate[qi][i][1],sad[1][i][j]);
+	cost[2] += BINMAP(mode_rate[qi][i][0],sad[2][i][j]);
+	cost[3] += BINMAP(mode_rate[qi][i][0],sad[3][i][j]);
+	cost[4] += BINMAP(mode_rate[qi][i][0],sad[4][i][j]);
+	cost[5] += BINMAP(mode_rate[qi][i][0],sad[5][i][j]);
+	cost[6] += BINMAP(mode_rate[qi][i][0],sad[6][i][j]);
+	cost[7] += BINMAP(mode_rate[qi][i][0],sad[7][i][j]);
+      }
+    }
+  }
 }
 
-static int MBInter4Cost420(CP_INSTANCE *cpi, int qi, int mbi, mv_t mv[4], int goldenp){
+static void MBSAD420(CP_INSTANCE *cpi, int mbi, mv_t last, mv_t last2,
+			int sad[8][3][4]){
   unsigned char *cp = cpi->frag_coded;
   macroblock_t *mb = &cpi->macro[mbi];
-  int cost = 0;
+  int fi,i,j;
   mv_t ch;
-  int fi;
 
-  fi=mb->Ryuv[0][0];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv[0],0));
-  fi=mb->Ryuv[0][1];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv[1],0));
-  fi=mb->Ryuv[0][2];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv[2],0));
-  fi=mb->Ryuv[0][3];
-  if(cp[fi])
-    cost += BINMAP(mode_rate[qi][0][0],BInterSAD(cpi,fi,0,goldenp,mv[3],0));
+  for(i=0;i<4;i++){
+    for(j=0;j<3;j++){
+      fi=mb->Ryuv[j][i];
+      if(cp[fi]){
+	sad[0][j][i] = BInterSAD(cpi,fi,j,0,(mv_t){0,0},(j>0));
+	sad[1][j][i] = BIntraSAD(cpi,fi,j);
+	sad[2][j][i] = BInterSAD(cpi,fi,j,0,mb->analysis_mv[0][0],(j>0));
+	sad[3][j][i] = BInterSAD(cpi,fi,j,0,last,(j>0));
+	sad[4][j][i] = BInterSAD(cpi,fi,j,0,last2,(j>0));
+	sad[5][j][i] = BInterSAD(cpi,fi,j,1,(mv_t){0,0},(j>0));
+	sad[6][j][i] = BInterSAD(cpi,fi,j,1,mb->analysis_mv[0][1],(j>0));
+      }
+    }
+    fi=mb->Ryuv[0][i];
+    if(cp[fi])
+      sad[7][0][i] = BInterSAD(cpi,fi,0,0,mb->mv[i],0);
+  }
 
+  /* 4:2:0-specific */
   /* Calculate motion vector as the average of the Y plane ones. */
   /* Uncoded members are 0,0 and not special-cased */
-  ch.x = mv[0].x + mv[1].x + mv[2].x + mv[3].x;
-  ch.y = mv[0].y + mv[1].y + mv[2].y + mv[3].y;
+  ch.x = mb->mv[0].x + mb->mv[1].x + mb->mv[2].x + mb->mv[3].x;
+  ch.y = mb->mv[0].y + mb->mv[1].y + mb->mv[2].y + mb->mv[3].y;
   
   ch.x = ( ch.x >= 0 ? (ch.x + 2) / 4 : (ch.x - 2) / 4);
   ch.y = ( ch.y >= 0 ? (ch.y + 2) / 4 : (ch.y - 2) / 4);
-  
+
   fi=mb->Ryuv[1][0];
   if(cp[fi])
-    cost += BINMAP(mode_rate[qi][1][0],BInterSAD(cpi,fi,1,goldenp,ch,1));
+    sad[7][1][0] = BInterSAD(cpi,fi,1,0,ch,1);
   fi=mb->Ryuv[2][0];
   if(cp[fi])
-    cost += BINMAP(mode_rate[qi][2][0],BInterSAD(cpi,fi,2,goldenp,ch,1));
-
-  /* Bit costs are stored in the table with extra precision. Round them down to whole bits.*/
-  return cost;
+    sad[7][2][0] = BInterSAD(cpi,fi,2,0,ch,1);
 }
 
 void mb_get_dct_input(CP_INSTANCE *cpi,
@@ -468,7 +433,14 @@
   for(; sb<sb_end; sb++){
     for(j = 0; j<4; j++){ /* mode addressing is through Y plane, always 4 MB per SB */
       int mbi = sb->m[j];
-      ogg_uint32_t  cost[8] = {0,0,0,0, 0,0,0,0};
+      int cost[8] = {0,0,0,0, 0,0,0,0};
+      int sad[8][3][4];
+      int mb_mv_bits_0;
+      int mb_gmv_bits_0;
+      int mb_4mv_bits_0;
+      int mb_4mv_bits_1;
+      int mode;
+
       macroblock_t *mb = &cpi->macro[mbi];
 
       if(cpi->FrameType == KEY_FRAME){
@@ -485,130 +457,110 @@
        encoder and decoder at the start of each frame. */
 
       /* 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] = MBInterCost420(cpi,qi,mbi,(mv_t){0,0},0);
+      MBSAD420(cpi, mbi, last_mv, prior_mv, sad);
+      MBCost(cpi,qi,mbi,cost,sad);
 
       /* 'should this have been a keyframe in retrospect' tracking;
 	 includes none of the rest of the inter-style labelling and
 	 flagging overhead, but must count 'uncoded' frags within the
 	 frame */
-      intrabits += MBIntraCost420(cpi,qi,mbi,1);
+      intrabits += cost[1];
 
-      if(mb->coded == 0){
-
-	oc_mode_set(cpi,mb,CODE_INTER_NO_MV);
-	mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
-
-      }else{
-	int mb_mv_bits_0;
-	int mb_gmv_bits_0;
-	int mb_4mv_bits_0;
-	int mb_4mv_bits_1;
-	int mode;
-
-	cost[CODE_INTRA] = MBIntraCost420(cpi,qi,mbi,0);
-	cost[CODE_INTER_PLUS_MV] = MBInterCost420(cpi,qi,mbi,mb->analysis_mv[0][0],0);
-	cost[CODE_INTER_LAST_MV] = MBInterCost420(cpi,qi,mbi,last_mv,0);
-	cost[CODE_INTER_PRIOR_LAST] = MBInterCost420(cpi,qi,mbi,prior_mv,0);
-	cost[CODE_USING_GOLDEN] = MBInterCost420(cpi,qi,mbi,(mv_t){0,0},1);
-	cost[CODE_GOLDEN_MV] = MBInterCost420(cpi,qi,mbi,mb->analysis_mv[0][1],1);
-	cost[CODE_INTER_FOURMV] = MBInter4Cost420(cpi,qi,mbi,mb->mv,0);
-
-	/* add estimated labelling cost for each mode */
-	for(i = 0; i < 8; i++)
-	  cost[i] += oc_mode_cost(cpi,i) << OC_BIT_SCALE;
-
-	/* Add the motion vector bits for each mode that requires them.*/
-	mb_mv_bits_0  = MvBits[mb->analysis_mv[0][0].x + MAX_MV_EXTENT] + 
-	  MvBits[mb->analysis_mv[0][0].y + MAX_MV_EXTENT];
-	mb_gmv_bits_0 = MvBits[mb->analysis_mv[0][1].x + MAX_MV_EXTENT] + 
-	  MvBits[mb->analysis_mv[0][1].y + MAX_MV_EXTENT];
-	mb_4mv_bits_0 = mb_4mv_bits_1 = 0;
-
-	if(mb->coded & 1){
-	  mb_4mv_bits_0 += MvBits[mb->mv[0].x + MAX_MV_EXTENT] + 
-	    MvBits[mb->mv[0].y+MAX_MV_EXTENT];
-	  mb_4mv_bits_1 += 12;
-	}
-	if(mb->coded & 2){
-	  mb_4mv_bits_0 += MvBits[mb->mv[1].x+MAX_MV_EXTENT] + 
-	    MvBits[mb->mv[1].y+MAX_MV_EXTENT];
-	  mb_4mv_bits_1 += 12;
-	}
-	if(mb->coded & 4){
-	  mb_4mv_bits_0 += MvBits[mb->mv[2].x+MAX_MV_EXTENT] + 
-	    MvBits[mb->mv[2].y+MAX_MV_EXTENT];
-	  mb_4mv_bits_1 += 12;
-	}
-	if(mb->coded & 8){
-	  mb_4mv_bits_0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] + 
-	    MvBits[mb->mv[3].y+MAX_MV_EXTENT];
-	  mb_4mv_bits_1 += 12;
-	}
-	
-	/* We use the same opportunity cost method of estimating the
-	   cost of coding the motion vectors with the two different
-	   schemes as we do for estimating the cost of the mode
-	   labels. However, because there are only two schemes and
-	   they're both pretty simple, this can just be done inline.*/
-	cost[CODE_INTER_PLUS_MV] += 
-	  ((OC_MINI(cpi->MVBits_0 + mb_mv_bits_0, cpi->MVBits_1+12)-
-	    OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
-	cost[CODE_GOLDEN_MV] +=
-	  ((OC_MINI(cpi->MVBits_0 + mb_gmv_bits_0, cpi->MVBits_1+12)-
-	    OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
-	cost[CODE_INTER_FOURMV] +=
+      /* add estimated labelling cost for each mode */
+      for(i = 0; i < 8; i++)
+	cost[i] += oc_mode_cost(cpi,i) << OC_BIT_SCALE;
+      
+      /* Add the motion vector bits for each mode that requires them.*/
+      mb_mv_bits_0  = MvBits[mb->analysis_mv[0][0].x + MAX_MV_EXTENT] + 
+	MvBits[mb->analysis_mv[0][0].y + MAX_MV_EXTENT];
+      mb_gmv_bits_0 = MvBits[mb->analysis_mv[0][1].x + MAX_MV_EXTENT] + 
+	MvBits[mb->analysis_mv[0][1].y + MAX_MV_EXTENT];
+      mb_4mv_bits_0 = mb_4mv_bits_1 = 0;
+      
+      if(mb->coded & 1){
+	mb_4mv_bits_0 += MvBits[mb->mv[0].x + MAX_MV_EXTENT] + 
+	  MvBits[mb->mv[0].y+MAX_MV_EXTENT];
+	mb_4mv_bits_1 += 12;
+      }
+      if(mb->coded & 2){
+	mb_4mv_bits_0 += MvBits[mb->mv[1].x+MAX_MV_EXTENT] + 
+	  MvBits[mb->mv[1].y+MAX_MV_EXTENT];
+	mb_4mv_bits_1 += 12;
+      }
+      if(mb->coded & 4){
+	mb_4mv_bits_0 += MvBits[mb->mv[2].x+MAX_MV_EXTENT] + 
+	  MvBits[mb->mv[2].y+MAX_MV_EXTENT];
+	mb_4mv_bits_1 += 12;
+      }
+      if(mb->coded & 8){
+	mb_4mv_bits_0 += MvBits[mb->mv[3].x+MAX_MV_EXTENT] + 
+	  MvBits[mb->mv[3].y+MAX_MV_EXTENT];
+	mb_4mv_bits_1 += 12;
+      }
+      
+      /* We use the same opportunity cost method of estimating the
+	 cost of coding the motion vectors with the two different
+	 schemes as we do for estimating the cost of the mode
+	 labels. However, because there are only two schemes and
+	 they're both pretty simple, this can just be done inline.*/
+      cost[CODE_INTER_PLUS_MV] += 
+	((OC_MINI(cpi->MVBits_0 + mb_mv_bits_0, cpi->MVBits_1+12)-
+	  OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+      cost[CODE_GOLDEN_MV] +=
+	((OC_MINI(cpi->MVBits_0 + mb_gmv_bits_0, cpi->MVBits_1+12)-
+	  OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
+      cost[CODE_INTER_FOURMV] +=
 	  ((OC_MINI(cpi->MVBits_0 + mb_4mv_bits_0, cpi->MVBits_1 + mb_4mv_bits_1)-
 	    OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
-
-	/* train this too... because the bit cost of an MV should be
-	   considered in the context of LAST_MV and PRIOR_LAST. */
-	cost[CODE_INTER_PLUS_MV] -= 384;
-	
-	/* Finally, pick the mode with the cheapest estimated bit cost.*/
-	mode=0;
-	for(i=1;i<8;i++)
-	  if(cost[i]<cost[mode])
-	    mode=i;
-
-	/* add back such that inter/intra counting are relatively correct */
-	cost[CODE_INTER_PLUS_MV] += 384;
-	
-	switch(mode){
-	case CODE_INTER_PLUS_MV:
-	  cpi->MVBits_0 += mb_mv_bits_0;
-	  cpi->MVBits_1 += 12;
-	  prior_mv = last_mv;
-	  last_mv = mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][0];
-	  break;
-	case CODE_INTER_LAST_MV:
-	  mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = last_mv;
-	  break;
-	case CODE_INTER_PRIOR_LAST:
-	  mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = prior_mv;
-	  prior_mv = last_mv;
-	  last_mv = mb->mv[0];
-	  break;
-	case CODE_INTER_FOURMV:
-	  cpi->MVBits_0 += mb_4mv_bits_0;
-	  cpi->MVBits_1 += mb_4mv_bits_1;
-	  prior_mv = last_mv;
-	  last_mv = mb->mv[3]; /* if coded, it is still used forced to 0,0 according to spec */
-	  break;
-	case CODE_GOLDEN_MV:
-	  cpi->MVBits_0 += mb_gmv_bits_0;
-	  cpi->MVBits_1 += 12;
-	  mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][1];
-	  break;
-	default:
-	  mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
-	  break;
-	}
-	oc_mode_set(cpi,mb,mode);      
+      
+      /* train this too... because the bit cost of an MV should be
+	 considered in the context of LAST_MV and PRIOR_LAST. */
+      cost[CODE_INTER_PLUS_MV] -= 384;
+      
+      /* Finally, pick the mode with the cheapest estimated bit cost.*/
+      mode=0;
+      for(i=1;i<8;i++)
+	if(cost[i]<cost[mode])
+	  mode=i;
+      
+      /* add back such that inter/intra counting are relatively correct */
+      cost[CODE_INTER_PLUS_MV] += 384;
+      
+      switch(mode){
+      case CODE_INTER_PLUS_MV:
+	cpi->MVBits_0 += mb_mv_bits_0;
+	cpi->MVBits_1 += 12;
+	prior_mv = last_mv;
+	last_mv = mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][0];
+	break;
+      case CODE_INTER_LAST_MV:
+	mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = last_mv;
+	break;
+      case CODE_INTER_PRIOR_LAST:
+	mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = prior_mv;
+	prior_mv = last_mv;
+	last_mv = mb->mv[0];
+	break;
+      case CODE_INTER_FOURMV:
+	cpi->MVBits_0 += mb_4mv_bits_0;
+	cpi->MVBits_1 += mb_4mv_bits_1;
+	prior_mv = last_mv;
+	last_mv = mb->mv[3]; /* if coded, it is still used forced to 0,0 according to spec */
+	break;
+      case CODE_GOLDEN_MV:
+	cpi->MVBits_0 += mb_gmv_bits_0;
+	cpi->MVBits_1 += 12;
+	mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = mb->analysis_mv[0][1];
+	break;
+      default:
+	mb->mv[0] = mb->mv[1] = mb->mv[2] = mb->mv[3] = (mv_t){0,0};
+	break;
       }
+      oc_mode_set(cpi,mb,mode);      
 
       interbits += cost[mb->mode];
-
     }
   }
 



More information about the commits mailing list