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

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Thu Apr 10 19:47:37 PDT 2008


Author: xiphmont
Date: 2008-04-10 19:47:37 -0700 (Thu, 10 Apr 2008)
New Revision: 14699

Modified:
   branches/theora-thusnelda/lib/enc/dct_encode.c
   branches/theora-thusnelda/lib/enc/encode.c
   branches/theora-thusnelda/lib/enc/mode.c
Log:
Move transform and quantization inline with the rest of the macroblock mode loop


Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c	2008-04-11 02:27:50 UTC (rev 14698)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c	2008-04-11 02:47:37 UTC (rev 14699)
@@ -432,142 +432,3 @@
     
   }
 }
-
-static int ModeUsesMC[MAX_MODES] = { 0, 0, 1, 1, 1, 0, 1, 1 };
-
-static void BlockUpdateDifference (CP_INSTANCE * cpi, 
-				   unsigned char *FiltPtr,
-				   ogg_int16_t *DctInputPtr, 
-				   ogg_int32_t MvDivisor,
-				   int fi,
-				   ogg_uint32_t PixelsPerLine,
-				   int mode,
-				   mv_t mv) {
-
-  ogg_int32_t MvShift;
-  ogg_int32_t MvModMask;
-  ogg_int32_t  AbsRefOffset;
-  ogg_int32_t  AbsXOffset;
-  ogg_int32_t  AbsYOffset;
-  ogg_int32_t  MVOffset;        /* Baseline motion vector offset */
-  ogg_int32_t  ReconPtr2Offset; /* Offset for second reconstruction in
-                                   half pixel MC */
-  unsigned char  *ReconPtr1;    /* DCT reconstructed image pointers */
-  unsigned char  *ReconPtr2;    /* Pointer used in half pixel MC */
-  int bi = cpi->frag_buffer_index[fi];
-  unsigned char *thisrecon = &cpi->recon[bi];
-
-  if ( ModeUsesMC[mode] ){
-    switch(MvDivisor) {
-    case 2:
-      MvShift = 1;
-      MvModMask = 1;
-      break;
-    case 4:
-      MvShift = 2;
-      MvModMask = 3;
-      break;
-    default:
-      break;
-    }
-    
-    /* Set up the baseline offset for the motion vector. */
-    MVOffset = ((mv.y / MvDivisor) * PixelsPerLine) + (mv.x / MvDivisor);
-    
-    /* Work out the offset of the second reference position for 1/2
-       pixel interpolation.  For the U and V planes the MV specifies 1/4
-       pixel accuracy. This is adjusted to 1/2 pixel as follows ( 0->0,
-       1/4->1/2, 1/2->1/2, 3/4->1/2 ). */
-    ReconPtr2Offset = 0;
-    AbsXOffset = mv.x % MvDivisor;
-    AbsYOffset = mv.y % MvDivisor;
-    
-    if ( AbsXOffset ) {
-      if ( mv.x > 0 )
-	ReconPtr2Offset += 1;
-      else
-	ReconPtr2Offset -= 1;
-    }
-    
-    if ( AbsYOffset ) {
-      if ( mv.y > 0 )
-	ReconPtr2Offset += PixelsPerLine;
-      else
-	ReconPtr2Offset -= PixelsPerLine;
-    }
-    
-    if ( mode==CODE_GOLDEN_MV ) {
-      ReconPtr1 = &cpi->golden[bi];
-    } else {
-      ReconPtr1 = &cpi->lastrecon[bi];
-    }
-    
-    ReconPtr1 += MVOffset;
-    ReconPtr2 =  ReconPtr1 + ReconPtr2Offset;
-    
-    AbsRefOffset = abs((int)(ReconPtr1 - ReconPtr2));
-    
-    /* Is the MV offset exactly pixel alligned */
-    if ( AbsRefOffset == 0 ){
-      dsp_sub8x8(cpi->dsp, FiltPtr, ReconPtr1, DctInputPtr, PixelsPerLine);
-      dsp_copy8x8 (cpi->dsp, ReconPtr1, thisrecon, PixelsPerLine);
-    } else {
-      /* Fractional pixel MVs. */
-      /* Note that we only use two pixel values even for the diagonal */
-      dsp_sub8x8avg2(cpi->dsp, FiltPtr, ReconPtr1, ReconPtr2, DctInputPtr, PixelsPerLine);
-      dsp_copy8x8_half (cpi->dsp, ReconPtr1, ReconPtr2, thisrecon, PixelsPerLine);
-    }
-
-  } else { 
-    if ( ( mode==CODE_INTER_NO_MV ) ||
-	 ( mode==CODE_USING_GOLDEN ) ) {
-      if ( mode==CODE_INTER_NO_MV ) {
-	ReconPtr1 = &cpi->lastrecon[bi];
-      } else {
-	ReconPtr1 = &cpi->golden[bi];
-      }
-      
-      dsp_sub8x8(cpi->dsp, FiltPtr, ReconPtr1, DctInputPtr,PixelsPerLine);
-      dsp_copy8x8 (cpi->dsp, ReconPtr1, thisrecon, PixelsPerLine);
-    } else if ( mode==CODE_INTRA ) {
-      dsp_sub8x8_128(cpi->dsp, FiltPtr, DctInputPtr, PixelsPerLine);
-      dsp_set8x8(cpi->dsp, 128, thisrecon, PixelsPerLine);
-    }
-  }
-}
-
-void TransformQuantizeBlock (CP_INSTANCE *cpi, 
-			     coding_mode_t mode,
-			     int fi,
-			     mv_t mv){
-
-  unsigned char *FiltPtr = &cpi->frame[cpi->frag_buffer_index[fi]];
-  int qi = cpi->BaseQ; // temporary
-  int inter = (mode != CODE_INTRA);
-  int plane = (fi < cpi->frag_n[0] ? 0 : 
-	       (fi-cpi->frag_n[0] < cpi->frag_n[1] ? 1 : 2)); 
-  ogg_int32_t *q = cpi->iquant_tables[inter][plane][qi];
-  ogg_int16_t DCTInput[64];
-  ogg_int16_t DCTOutput[64];
-  ogg_int32_t   MvDivisor;      /* Defines MV resolution (2 = 1/2
-                                   pixel for Y or 4 = 1/4 for UV) */
-  /* Set plane specific values */
-  if (plane == 0){
-    MvDivisor = 2;                  /* 1/2 pixel accuracy in Y */
-  }else{
-    MvDivisor = 4;                  /* UV planes at 1/2 resolution of Y */
-  }
-
-  /* produces the appropriate motion compensation block, applies it to
-     the reconstruction buffer, and proces a difference block for
-     forward DCT */
-  BlockUpdateDifference(cpi, FiltPtr, DCTInput, 
-			MvDivisor, fi, cpi->stride[plane], mode, mv);
-
-  dsp_fdct_short(cpi->dsp, DCTInput, DCTOutput);
-
-  /* Quantize that transform data. */
-  quantize (cpi, q, DCTOutput, cpi->frag_dct[fi].data);
-  cpi->frag_dc[fi] = cpi->frag_dct[fi].data[0];
-
-}

Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c	2008-04-11 02:27:50 UTC (rev 14698)
+++ branches/theora-thusnelda/lib/enc/encode.c	2008-04-11 02:47:37 UTC (rev 14699)
@@ -153,55 +153,6 @@
   }
 }
 
-static ogg_uint32_t CodePlane ( CP_INSTANCE *cpi, int plane, int subsample){
-  int B;
-  unsigned char *cp = cpi->frag_coded;
-  macroblock_t *mp = cpi->macro;
-  macroblock_t *mp_end = cpi->macro+cpi->macro_total;
-  int fi;
-
-  switch(subsample){
-  case 1:
-    for ( ; mp<mp_end; mp++ ) {
-
-      for ( B=0; B<4; B++) {
-	fi = mp->Ryuv[plane][B];
-	if ( cp[fi] ) 
-	  TransformQuantizeBlock( cpi, mp->mode, fi, mp->mv[B] );
-      }
-    }
-    return 0;
-  case 2:
-    /* fill me in when we need to support 4:2:2 */
-    return 1;
-  case 4:
-    for ( ; mp<mp_end; mp++ ) {
-      int fi = mp->Hyuv[plane][0];
-      if ( cp[fi] ) {
-	
-	if(mp->mode == CODE_INTER_FOURMV){
-	  mv_t mv;
-	  
-	  /* Calculate motion vector as the average of the Y plane ones. */
-	  /* Uncoded members are 0,0 and not special-cased */
-	  mv.x = mp->mv[0].x + mp->mv[1].x + mp->mv[2].x + mp->mv[3].x;
-	  mv.y = mp->mv[0].y + mp->mv[1].y + mp->mv[2].y + mp->mv[3].y;
-	  
-	  mv.x = ( mv.x >= 0 ? (mv.x + 2) / 4 : (mv.x - 2) / 4);
-	  mv.y = ( mv.y >= 0 ? (mv.y + 2) / 4 : (mv.y - 2) / 4);
-
-	  TransformQuantizeBlock( cpi, mp->mode, fi, mv );
-	}else
-	  TransformQuantizeBlock( cpi, mp->mode, fi, mp->mv[0] );
-    
-      }  
-    }
-    return 0;
-  default:
-    return 1;
-  }
-}
-
 static void ChooseTokenTables (CP_INSTANCE *cpi, int huff[4]) {
   int i,plane;
   int best;
@@ -399,12 +350,6 @@
 
   dsp_save_fpu (cpi->dsp);
 
-  /* Encode and tokenise the Y, U and V components */
-  /* 4:2:0 for now */
-  CodePlane(cpi, 0, 1);
-  CodePlane(cpi, 1, 4);
-  CodePlane(cpi, 2, 4);
-
   PredictDC(cpi);
   DPCMTokenize(cpi);
 

Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c	2008-04-11 02:27:50 UTC (rev 14698)
+++ branches/theora-thusnelda/lib/enc/mode.c	2008-04-11 02:47:37 UTC (rev 14699)
@@ -445,8 +445,6 @@
 		  OC_MINI(cpi->MVBits_0, cpi->MVBits_1)) << OC_BIT_SCALE);
 }
 
-
-
 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;
@@ -496,12 +494,13 @@
 		      ogg_int16_t *block){
 
   int plane = fi>=cpi->frag_n[0]; /* sets plane to 'Y' or 'Chroma' */
-  int qp = (plane?1:0); 
+  int qp = (plane>0); /* 4:2:0 specific for now */
   int bi = cpi->frag_buffer_index[fi];
   unsigned char *frame_ptr = &cpi->frame[bi];
-  unsigned char *recon = ((mode == CODE_USING_GOLDEN || 
+  unsigned char *lastrecon = ((mode == CODE_USING_GOLDEN || 
 			   mode == CODE_GOLDEN_MV) ? 
-			  cpi->golden : cpi->lastrecon);
+			  cpi->golden : cpi->lastrecon)+bi;
+  unsigned char *thisrecon = cpi->recon+bi;
   int stride = cpi->stride[plane];
   
   switch(mode){
@@ -517,12 +516,14 @@
       int mx2 = mvmap2[qp][mv.x+31];
       int my2 = mvmap2[qp][mv.y+31];
       
-      unsigned char *r1 = recon + bi+ my * stride + mx;
+      unsigned char *r1 = lastrecon + my * stride + mx;
       
       if(mx2 || my2){
 	unsigned char *r2 = r1 + my2 * stride + mx2;
-	dsp_sub8x8avg2(cpi->dsp, frame_ptr, r1, r2, block, stride);
+	dsp_copy8x8_half (cpi->dsp, r1, r2, thisrecon, stride);
+	dsp_sub8x8(cpi->dsp, frame_ptr, thisrecon, block, stride);
       }else{
+	dsp_copy8x8 (cpi->dsp, r1, thisrecon, stride);
 	dsp_sub8x8(cpi->dsp, frame_ptr, r1, block, stride);
       }
     }
@@ -530,14 +531,110 @@
 
   case CODE_USING_GOLDEN:
   case CODE_INTER_NO_MV:
-    dsp_sub8x8(cpi->dsp, frame_ptr, recon+bi, block, stride);
+    dsp_copy8x8 (cpi->dsp, lastrecon, thisrecon, stride);
+    dsp_sub8x8(cpi->dsp, frame_ptr, lastrecon, block, stride);
     break;
   case CODE_INTRA:
     dsp_sub8x8_128(cpi->dsp, frame_ptr, block, stride);
+    dsp_set8x8(cpi->dsp, 128, thisrecon, stride);
     break;
   }
 }
 
+static void TQB (CP_INSTANCE *cpi, int mode, int fi, ogg_int32_t *q, mv_t mv){
+  if ( cpi->frag_coded[fi] ) {
+    ogg_int16_t buffer[128];
+    
+    /* motion comp */
+    mb_get_dct_input(cpi,mode,fi,mv,cpi->frag_dct[fi].data);
+    
+    /* transform */
+    dsp_fdct_short(cpi->dsp, cpi->frag_dct[fi].data, buffer);
+    
+    /* collect rho metrics */
+    
+    /* quantize */
+    quantize (cpi, q, buffer, cpi->frag_dct[fi].data);
+    cpi->frag_dc[fi] = cpi->frag_dct[fi].data[0];
+  }
+}
+
+static void TQMB ( CP_INSTANCE *cpi, macroblock_t *mb, int qi){
+  int pf = cpi->info.pixelformat;
+  int mode = mb->mode;
+  int inter = (mode != CODE_INTRA);
+  ogg_int32_t *q = cpi->iquant_tables[inter][0][qi];
+  int i;
+
+  for(i=0;i<4;i++)
+    TQB(cpi,mode,mb->Ryuv[0][i],q,mb->mv[i]);
+
+  switch(pf){
+  case OC_PF_420:
+    if(mode == CODE_INTER_FOURMV){
+      mv_t mv;
+	  
+      mv.x = mb->mv[0].x + mb->mv[1].x + mb->mv[2].x + mb->mv[3].x;
+      mv.y = mb->mv[0].y + mb->mv[1].y + mb->mv[2].y + mb->mv[3].y;
+      
+      mv.x = ( mv.x >= 0 ? (mv.x + 2) / 4 : (mv.x - 2) / 4);
+      mv.y = ( mv.y >= 0 ? (mv.y + 2) / 4 : (mv.y - 2) / 4);
+      
+      q = cpi->iquant_tables[inter][1][qi];
+      TQB(cpi,mode,mb->Ryuv[1][0],q,mv);
+      q = cpi->iquant_tables[inter][2][qi];
+      TQB(cpi,mode,mb->Ryuv[2][0],q,mv);
+    }else{ 
+      q = cpi->iquant_tables[inter][1][qi];
+      TQB(cpi,mode,mb->Ryuv[1][0],q,mb->mv[0]);
+      q = cpi->iquant_tables[inter][2][qi];
+      TQB(cpi,mode,mb->Ryuv[2][0],q,mb->mv[0]);
+    }
+    break;
+
+  case OC_PF_422:
+    if(mode == CODE_INTER_FOURMV){
+      mv_t mvA;
+      mv_t mvB;
+	  
+      mvA.x = mb->mv[0].x + mb->mv[1].x;
+      mvA.y = mb->mv[0].y + mb->mv[1].y;
+      mvA.x = ( mvA.x >= 0 ? (mvA.x + 1) / 2 : (mvA.x - 1) / 2);
+      mvA.y = ( mvA.y >= 0 ? (mvA.y + 1) / 2 : (mvA.y - 1) / 2);
+      mvB.x = mb->mv[0].x + mb->mv[1].x;
+      mvB.y = mb->mv[0].y + mb->mv[1].y;
+      mvB.x = ( mvB.x >= 0 ? (mvB.x + 1) / 2 : (mvB.x - 1) / 2);
+      mvB.y = ( mvB.y >= 0 ? (mvB.y + 1) / 2 : (mvB.y - 1) / 2);
+      
+      q = cpi->iquant_tables[inter][1][qi];
+      TQB(cpi,mode,mb->Ryuv[1][0],q,mvA);
+      TQB(cpi,mode,mb->Ryuv[1][1],q,mvB);
+
+      q = cpi->iquant_tables[inter][2][qi];
+      TQB(cpi,mode,mb->Ryuv[2][0],q,mvA);
+      TQB(cpi,mode,mb->Ryuv[2][1],q,mvB);
+
+    }else{ 
+      q = cpi->iquant_tables[inter][1][qi];
+      TQB(cpi,mode,mb->Ryuv[1][0],q,mb->mv[0]);
+      TQB(cpi,mode,mb->Ryuv[1][1],q,mb->mv[0]);
+      q = cpi->iquant_tables[inter][2][qi];
+      TQB(cpi,mode,mb->Ryuv[2][0],q,mb->mv[0]);
+      TQB(cpi,mode,mb->Ryuv[2][1],q,mb->mv[0]);
+    }
+    break;
+
+  case OC_PF_444:
+    q = cpi->iquant_tables[inter][1][qi];
+    for(i=0;i<4;i++)
+      TQB(cpi,mode,mb->Ryuv[1][i],q,mb->mv[i]);
+    q = cpi->iquant_tables[inter][2][qi];
+    for(i=0;i<4;i++)
+      TQB(cpi,mode,mb->Ryuv[2][i],q,mb->mv[i]);
+    break;
+  }
+}
+
 int PickModes(CP_INSTANCE *cpi, int recode){
   unsigned char qi = cpi->BaseQ; // temporary
   superblock_t *sb = cpi->super[0];
@@ -702,12 +799,15 @@
 	}
       }
 #endif
+
+      /* Transform, quantize, collect rho metrics */
+      TQMB(cpi, mb, qi);
+
     }
   }
 
-
   if(cpi->FrameType != KEY_FRAME){
-
+    
     if(interbits>intrabits) return 1; /* short circuit */
     
     /* finish adding flagging overhead costs to inter bit counts */



More information about the commits mailing list