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

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Mon Dec 17 23:46:56 PST 2007


Author: xiphmont
Date: 2007-12-17 23:46:54 -0800 (Mon, 17 Dec 2007)
New Revision: 14309

Modified:
   branches/theora-thusnelda/lib/enc/codec_internal.h
   branches/theora-thusnelda/lib/enc/dct_decode.c
   branches/theora-thusnelda/lib/enc/dct_encode.c
   branches/theora-thusnelda/lib/enc/encode.c
   branches/theora-thusnelda/lib/enc/encoder_toplevel.c
   branches/theora-thusnelda/lib/enc/frarray.c
   branches/theora-thusnelda/lib/enc/frinit.c
   branches/theora-thusnelda/lib/enc/mcomp.c
Log:
Some cache-friendly memory rearrangement.  This takes things, in some
ways, closer to the original encoder code but with less
duplication/inconsistency/clutter.

Ongoing incremental changes; it might not look like this commit makes
much sense.  Babysteps.



Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h	2007-12-18 07:46:54 UTC (rev 14309)
@@ -109,8 +109,6 @@
 typedef struct fragment fragment_t;
 
 struct fragment {
-  int coded;
-  coding_mode_t mode;
   mv_t mv;
   ogg_int16_t pred_dc;
   ogg_int16_t dct[64];
@@ -157,9 +155,12 @@
   unsigned char   *recon;
   unsigned char   *golden;
   unsigned char   *lastrecon;
-  ogg_uint32_t    frame_size;
+  ogg_uint32_t     frame_size;
 
   /* SuperBlock, MacroBLock and Fragment Information */
+  unsigned char   *frag_coded[3];
+  coding_mode_t   *frag_mode[3];
+
   fragment_t      *frag[3];
   macroblock_t    *macro;
   superblock_t    *super[3];
@@ -279,7 +280,7 @@
 
 extern void DPCMTokenize (CP_INSTANCE *cpi);
 
-extern void TransformQuantizeBlock (CP_INSTANCE *cpi, fragment_t *fp) ;
+extern void TransformQuantizeBlock (CP_INSTANCE *cpi, int fi) ;
 
 extern void WriteQTables(CP_INSTANCE *cpi,oggpack_buffer *opb);
 

Modified: branches/theora-thusnelda/lib/enc/dct_decode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_decode.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/dct_decode.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -35,14 +35,15 @@
   }
 }
 
-static void ExpandBlock ( CP_INSTANCE *cpi, fragment_t *fp){
-  int            mode = fp->mode;
-  int            qi = cpi->BaseQ; // temporary 
-  int            plane = (fp<cpi->frag[1] ? 0 : (fp<cpi->frag[2] ? 1 : 2));
-  int            inter = (mode != CODE_INTRA);
-  ogg_int16_t    reconstruct[64];
+static void ExpandBlock ( CP_INSTANCE *cpi, int fi){
+  fragment_t   *fp = &cpi->frag[0][fi]; 
+  int           mode = cpi->frag_mode[0][fi];
+  int           qi = cpi->BaseQ; // temporary 
+  int           plane = (fp<cpi->frag[1] ? 0 : (fp<cpi->frag[2] ? 1 : 2));
+  int           inter = (mode != CODE_INTRA);
+  ogg_int16_t   reconstruct[64];
   ogg_int16_t  *quantizers = cpi->quant_tables[inter][plane][qi];
-  ogg_int16_t   *data = fp->dct;
+  ogg_int16_t  *data = fp->dct;
   
   /* Invert quantisation and DCT to get pixel data. */
   switch(fp->nonzero){
@@ -162,12 +163,13 @@
 		       unsigned char * SrcReconPtr ) {
   ogg_uint32_t  i,plane;
   fragment_t *fp = cpi->frag[0];
-  
+  unsigned char *cp = cpi->frag_coded[0];
+
   /* Copy over only updated blocks.*/
   for(plane=0;plane<3;plane++){  
     int PlaneLineStep = cpi->stride[plane];
     for ( i = 0; i < cpi->frag_n[plane]; i++,fp++ ) {
-      if ( fp->coded ) {
+      if ( cp[i] ) {
 	int pi= fp->buffer_index;
 	unsigned char *src = &SrcReconPtr[ pi ];
 	unsigned char *dst = &DestReconPtr[ pi ];
@@ -231,6 +233,7 @@
   ogg_int32_t FLimit = cpi->quant_info.loop_filter_limits[cpi->BaseQ]; // temp
   int j,m,n;
   fragment_t *fp;
+  unsigned char *cp;
 
   if ( FLimit == 0 ) return;
   SetupBoundingValueArray_Generic(BoundingValues, FLimit);
@@ -239,6 +242,7 @@
     ogg_int32_t LineFragments = cpi->frag_h[j];
     ogg_int32_t LineLength = cpi->stride[j];
     fp = cpi->frag[j];
+    cp = cpi->frag_coded[j];
 
     /**************************************************************
      First Row
@@ -246,28 +250,29 @@
     /* first column conditions */
     /* only do 2 prediction if fragment coded and on non intra or if
        all fragments are intra */
-    if( fp->coded){
+    if( cp[0]){
       /* Filter right hand border only if the block to the right is
          not coded */
-      if ( !fp[1].coded ){
+      if ( !cp[1] ){
         dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			fp[0].buffer_index+6,
 			LineLength,BoundingValuePtr);
       }
 
       /* Bottom done if next row set */
-      if( !fp[LineFragments].coded ){
+      if( !cp[LineFragments] ){
         dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 		       fp[LineFragments].buffer_index,
 		       LineLength, BoundingValuePtr);
       }
     }
     fp++;
+    cp++;
 
     /***************************************************************/
     /* middle columns  */
     for ( n = 1 ; n < cpi->frag_h[j] - 1 ; n++, fp++) {
-      if( fp->coded){
+      if( cp[0]){
         /* Filter Left edge always */
         dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			fp[0].buffer_index-2,
@@ -275,14 +280,14 @@
 
         /* Filter right hand border only if the block to the right is
            not coded */
-        if ( !fp[1].coded ){
+        if ( !cp[1] ){
           dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			  fp[0].buffer_index+6,
 			  LineLength, BoundingValuePtr);
         }
 
         /* Bottom done if next row set */
-        if( !fp[LineFragments].coded ){
+        if( !cp[LineFragments] ){
           dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 			 fp[LineFragments].buffer_index,
 			 LineLength, BoundingValuePtr);
@@ -293,20 +298,21 @@
 
     /***************************************************************/
     /* Last Column */
-    if(fp->coded){
+    if(cp[0]){
       /* Filter Left edge always */
       dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 		      fp[0].buffer_index - 2 ,
 		      LineLength, BoundingValuePtr);
       
       /* Bottom done if next row set */
-      if( !fp[LineFragments].coded ){
+      if( !cp[LineFragments] ){
         dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 		       fp[LineFragments].buffer_index,
 		       LineLength, BoundingValuePtr);
       }
     }
     fp++;
+    cp++;
 
     /***************************************************************/
     /* Middle Rows */
@@ -317,7 +323,7 @@
       /* first column conditions */
       /* only do 2 prediction if fragment coded and on non intra or if
          all fragments are intra */
-      if( fp->coded){
+      if( cp[0] ){
         /* TopRow is always done */
         dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 		       fp[0].buffer_index,
@@ -325,25 +331,26 @@
 
         /* Filter right hand border only if the block to the right is
            not coded */
-        if ( !fp[1].coded ){
+        if ( !cp[1] ){
           dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			  fp[0].buffer_index + 6,
 			  LineLength, BoundingValuePtr);
         }
 	
         /* Bottom done if next row set */
-        if( !fp[LineFragments].coded ){
+        if( !cp[LineFragments] ){
           dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 			 fp[LineFragments].buffer_index,
 			 LineLength, BoundingValuePtr);
         }
       }
       fp++;
+      cp++;
 
       /*****************************************************************/
       /* middle columns  */
       for ( n = 1 ; n < cpi->frag_h[j] - 1 ; n++, fp++){
-        if( fp->coded){
+        if( cp[0] ){
           /* Filter Left edge always */
           dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			  fp[0].buffer_index - 2,
@@ -356,14 +363,14 @@
 	  
           /* Filter right hand border only if the block to the right
              is not coded */
-          if ( !fp[1].coded ){
+          if ( !cp[1] ){
             dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			    fp[0].buffer_index + 6,
 			    LineLength, BoundingValuePtr);
           }
 
           /* Bottom done if next row set */
-          if( !fp[LineFragments].coded ){
+          if( !cp[LineFragments] ){
             dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 			   fp[LineFragments].buffer_index,
 			   LineLength, BoundingValuePtr);
@@ -373,7 +380,7 @@
 
       /******************************************************************/
       /* Last Column */
-      if(fp->coded){
+      if(cp[0]){
         /* Filter Left edge always*/
         dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			fp[0].buffer_index - 2,
@@ -385,13 +392,14 @@
 		       LineLength, BoundingValuePtr);
 	
         /* Bottom done if next row set */
-        if( !fp[LineFragments].coded ){
+        if( !cp[LineFragments] ){
           dsp_FilterVert(cpi->dsp,cpi->lastrecon+
 			 fp[LineFragments].buffer_index,
 			 LineLength, BoundingValuePtr);
         }
       }
       fp++;
+      cp++;
     }
 
     /*******************************************************************/
@@ -400,7 +408,7 @@
     /* first column conditions */
     /* only do 2 prediction if fragment coded and on non intra or if
        all fragments are intra */
-    if(fp->coded){
+    if(cp[0]){
 
       /* TopRow is always done */
       dsp_FilterVert(cpi->dsp,cpi->lastrecon+
@@ -409,18 +417,19 @@
 
       /* Filter right hand border only if the block to the right is
          not coded */
-      if ( !fp[1].coded ){
+      if ( !cp[1] ){
         dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			fp[0].buffer_index + 6,
 			LineLength, BoundingValuePtr);
       }
     }
     fp++;
+    cp++;
 
     /******************************************************************/
     /* middle columns  */
     for ( n = 1 ; n < cpi->frag_h[j] - 1 ; n++, fp++){
-      if( fp->coded){
+      if( cp[0] ){
         /* Filter Left edge always */
         dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			fp[0].buffer_index - 2,
@@ -433,7 +442,7 @@
 
         /* Filter right hand border only if the block to the right is
            not coded */
-        if ( !fp[1].coded ){
+        if ( !cp[1] ){
           dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 			  fp[0].buffer_index + 6,
 			  LineLength, BoundingValuePtr);
@@ -443,7 +452,7 @@
 
     /******************************************************************/
     /* Last Column */
-    if( fp->coded){
+    if( cp[0] ){
       /* Filter Left edge always */
       dsp_FilterHoriz(cpi->dsp,cpi->lastrecon+
 		      fp[0].buffer_index - 2,
@@ -456,6 +465,7 @@
       
     }
     fp++;
+    cp++;
   }
 }
 
@@ -463,7 +473,7 @@
   fragment_t *fp = cpi->coded_tail;
   
   while(fp){
-    ExpandBlock( cpi, fp );
+    ExpandBlock( cpi, fp-cpi->frag[0] );
     fp = fp->next;
   }
 

Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -516,11 +516,15 @@
 }
 
 void TransformQuantizeBlock (CP_INSTANCE *cpi, 
-			     fragment_t *fp){
+			     int fi){
+  
+  fragment_t *fp = &cpi->frag[0][fi];
+  coding_mode_t mode = cpi->frag_mode[0][fi];
+  unsigned char *cp = &cpi->frag_coded[0][fi];
 
   unsigned char *FiltPtr = &cpi->frame[fp->buffer_index];
   int qi = cpi->BaseQ; // temporary
-  int inter = (fp->mode != CODE_INTRA);
+  int inter = (mode != CODE_INTRA);
   int plane = (fp < cpi->frag[1] ? 0 : (fp < cpi->frag[2] ? 1 : 2)); 
   ogg_int32_t *q = cpi->iquant_tables[inter][plane][qi];
   ogg_int16_t DCTInput[64];
@@ -540,7 +544,7 @@
      the reconstruction buffer, and proces a difference block for
      forward DCT */
   BlockUpdateDifference(cpi, FiltPtr, DCTInput, ReconPtr1,
-			MvDivisor, fp, cpi->stride[plane], fp->mode);
+			MvDivisor, fp, cpi->stride[plane], mode);
   
   /* Proceed to encode the data into the encode buffer if the encoder
      is enabled. */
@@ -550,9 +554,9 @@
   /* Quantize that transform data. */
   quantize (cpi, q, DCTOutput, fp->dct);
 
-  if ( (fp->mode == CODE_INTER_NO_MV) &&
+  if ( (mode == CODE_INTER_NO_MV) &&
        ( AllZeroDctData(fp->dct) ) ) {
-    fp->coded = 0;
+    *cp = 0;
   }
 
 }

Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/encode.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -42,6 +42,9 @@
 
   int WhichFrame;
   int WhichCase;
+  coding_mode_t *mp = cpi->frag_mode[0];
+  unsigned char *cp = cpi->frag_coded[0];
+  int fi = 0;
 
   /* for y,u,v */
   for ( plane = 0; plane < 3 ; plane++) {
@@ -59,15 +62,15 @@
 
     /* do prediction on all of Y, U or V */
     for ( m = 0 ; m < cpi->frag_v[plane] ; m++) {
-      for ( n = 0 ; n < cpi->frag_h[plane] ; n++, fp++) {
+      for ( n = 0 ; n < cpi->frag_h[plane] ; n++, fp++, fi++) {
         fp->pred_dc = fp->dct[0];
 
         /* only do 2 prediction if fragment coded and on non intra or
            if all fragments are intra */
-        if( fp->coded ) {
+        if(cp[fi]) {
           /* Type of Fragment */
 
-          WhichFrame = Mode2Frame[fp->mode];
+          WhichFrame = Mode2Frame[mp[fi]];
 
           /* Check Borderline Cases */
           WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == cpi->frag_h[plane]) << 2);
@@ -77,9 +80,10 @@
           for(k=pcount=wpc=0; k<4; k++) {
             int pflag = 1<<k;
             if((bc_mask[WhichCase]&pflag)){
-	      fragment_t *fnp=fp - fn[k];	      
-	      if(fnp->coded &&
-		 (Mode2Frame[fnp->mode] == WhichFrame)){
+	      fragment_t *fnp=fp - fn[k];	
+	      int fni = fi - fn[k];	
+	      if(cp[fni] &&
+		 (Mode2Frame[mp[fni]] == WhichFrame)){
 		v[pcount]=fnp->dct[0];
 		wpc|=pflag;
 		pcount++;
@@ -140,7 +144,9 @@
 
   ogg_uint32_t SBs = cpi->super_n[plane];
   ogg_uint32_t SB, MB, B;
-  
+  coding_mode_t *mp = cpi->frag_mode[0];
+  unsigned char *cp = cpi->frag_coded[0];
+
   /* actually transform and quantize the image now that we've decided
      on the modes Parse in quad-tree ordering */
 
@@ -158,16 +164,17 @@
 
       for ( B=0; B<4; B++, frag++ ) {
 	fragment_t *fp = sp->f[frag];
+	int fi = fp - cpi->frag[0];
 
-	if ( fp && fp->coded ) {
+	if ( fp && cp[fi] ) {
 
 	  /* transform and quantize block */
-	  TransformQuantizeBlock( cpi, fp );
+	  TransformQuantizeBlock( cpi, fi );
 	  
 	  /* Has the block got struck off (no MV and no data
 	     generated after DCT) If not then mark it and the
 	     assosciated MB as coded. */
-	  if ( fp->coded ) {
+	  if ( cp[fi] ) {
 
 	    if(cpi->coded_head){
 	      cpi->coded_head->next = fp;
@@ -178,7 +185,7 @@
 
 	    /* MB is still coded */
 	    coded = 1;
-	    mode = fp->mode;
+	    mode = mp[fi];
 	    
 	  }
 	}
@@ -302,6 +309,8 @@
   const ogg_int32_t *ModeBits;
   const unsigned char  *ModeScheme;
 
+  unsigned char *cp = cpi->frag_coded[0];
+  coding_mode_t *mp = cpi->frag_mode[0];
   int SB,MB,B;
 
   oggpack_buffer *opb=cpi->oggbuffer;
@@ -380,14 +389,22 @@
   for ( SB=0 ; SB < cpi->super_n[0]; SB++ ){
     superblock_t *sp = &cpi->super[0][SB];
     for ( MB=0; MB<4; MB++ ) {
-      macroblock_t *mp = sp->m[MB];
+      macroblock_t *mbp = sp->m[MB];
       fragment_t *fp;
-      if(!mp) continue;
-      fp = mp->y[0];
-      for(B=1; (!fp || !fp->coded) && B<4; B++ ) fp = mp->y[B];
-      if(fp && fp->coded){
+      int fi;
+
+      if(!mbp) continue;
+
+      fp = mbp->y[0];
+      fi = (fp ? fp - cpi->frag[0] : -1);
+
+      for(B=1; (!fp || !cp[fi]) && B<4; B++ ){
+	fp = mbp->y[B];
+	fi = (fp ? fp - cpi->frag[0] : -1);
+      }
+      if(fp && cp[fi]){
 	/* Add the appropriate mode entropy token. */
-	int index = ModeScheme[fp->mode];
+	int index = ModeScheme[mp[fi]];
 	oggpackB_write( opb, ModeWords[index],
 			(ogg_uint32_t)ModeBits[index] );
       }
@@ -400,6 +417,8 @@
   const ogg_uint32_t * MvBitsPtr;
 
   ogg_uint32_t SB, MB, B;
+  coding_mode_t *mp = cpi->frag_mode[0];
+  unsigned char *cp = cpi->frag_coded[0];
 
   oggpack_buffer *opb=cpi->oggbuffer;
 
@@ -419,21 +438,30 @@
   for ( SB=0 ; SB < cpi->super_n[0]; SB++ ){
     superblock_t *sp = &cpi->super[0][SB];
     for ( MB=0; MB<4; MB++ ) {
-      macroblock_t *mp = sp->m[MB];
+      macroblock_t *mbp = sp->m[MB];
       fragment_t *fp;
-      if(!mp) continue;
-      fp = mp->y[0];
-      for(B=1; !fp && B<4; B++ ) fp = mp->y[B];
-      if(!fp) continue;
-      if(fp->mode==CODE_INTER_PLUS_MV || fp->mode==CODE_GOLDEN_MV){
+      int fi;
+
+      if(!mbp) continue;
+
+      fp = mbp->y[0];
+      fi = (fp ? fp - cpi->frag[0] : -1);
+      for(B=1; !fp && !cp[fi] && B<4; B++ ){
+	fp = mbp->y[B];
+	fi = (fp ? fp - cpi->frag[0] : -1);
+      }
+
+      if(!fp || !cp[fi]) continue;
+      if(mp[fi]==CODE_INTER_PLUS_MV || mp[fi]==CODE_GOLDEN_MV){
 	/* One MV for the macroblock */
 	oggpackB_write( opb, MvPatternPtr[fp->mv.x], MvBitsPtr[fp->mv.x] );
 	oggpackB_write( opb, MvPatternPtr[fp->mv.y], MvBitsPtr[fp->mv.y] );
-      }else if (fp->mode == CODE_INTER_FOURMV){
+      }else if (mp[fi] == CODE_INTER_FOURMV){
 	/* MV for each codedblock */
 	for(B=0; B<4; B++ ){
-	  fp = mp->y[B];
-	  if(fp){
+	  fp = mbp->y[B];
+	  fi = (fp ? fp - cpi->frag[0] : -1);
+	  if(fp && cp[fi]){
 	    oggpackB_write( opb, MvPatternPtr[fp->mv.x], MvBitsPtr[fp->mv.x] );
 	    oggpackB_write( opb, MvPatternPtr[fp->mv.y], MvBitsPtr[fp->mv.y] );
 	  }
@@ -484,8 +512,8 @@
 
   int i;
   for(i=0;i<cpi->frag_total;i++){
-    cpi->frag[0][i].mode = CODE_INTRA;
-    cpi->frag[0][i].coded = 1;
+    cpi->frag_mode[0][i] = CODE_INTRA;
+    cpi->frag_coded[0][i] = 1;
   }
   return 0;
 }
@@ -496,27 +524,31 @@
   cpi->MVBits_1 += 12; /* Simple six bits per mv component fallback */
 }
 
-static void SetFragMotionVectorAndMode(fragment_t *fp,
+static void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
+				       int fi,
 				       mv_t *mv,
 				       int mode){
+  fragment_t *fp = &cpi->frag[0][fi];
   fp->mv = *mv;
-  fp->mode = mode;
+  cpi->frag_mode[0][fi] = mode;
 }
 
-static void SetMBMotionVectorsAndMode(macroblock_t *mp,
+static void SetMBMotionVectorsAndMode(CP_INSTANCE *cpi,
+				      macroblock_t *mp,
 				      mv_t *mv,
 				      int mode){
-  SetFragMotionVectorAndMode(mp->y[0], mv, mode);
-  SetFragMotionVectorAndMode(mp->y[1], mv, mode);
-  SetFragMotionVectorAndMode(mp->y[2], mv, mode);
-  SetFragMotionVectorAndMode(mp->y[3], mv, mode);
-  SetFragMotionVectorAndMode(mp->u, mv, mode);
-  SetFragMotionVectorAndMode(mp->v, mv, mode);
+  fragment_t *fp0 = cpi->frag[0];
+  SetFragMotionVectorAndMode(cpi, mp->y[0] - fp0, mv, mode);
+  SetFragMotionVectorAndMode(cpi, mp->y[1] - fp0, mv, mode);
+  SetFragMotionVectorAndMode(cpi, mp->y[2] - fp0, mv, mode);
+  SetFragMotionVectorAndMode(cpi, mp->y[3] - fp0, mv, mode);
+  SetFragMotionVectorAndMode(cpi, mp->u - fp0, mv, mode);
+  SetFragMotionVectorAndMode(cpi, mp->v - fp0, mv, mode);
 }
 
 ogg_uint32_t PickModes(CP_INSTANCE *cpi,
                        ogg_uint32_t *InterError, ogg_uint32_t *IntraError) {
-
+  
   ogg_uint32_t  SB, MB, B; 
   ogg_uint32_t  MBIntraError;           /* Intra error for macro block */
   ogg_uint32_t  MBGFError;              /* Golden frame macro block error */
@@ -548,6 +580,8 @@
   int           MBCodedFlag;
   unsigned char QIndex = cpi->BaseQ; // temporary
 
+  unsigned char *cp = cpi->frag_coded[0];
+
   /* initialize error scores */
   *InterError = 0;
   *IntraError = 0;
@@ -587,7 +621,8 @@
       MBCodedFlag = 0;
       for ( B=0; B<4; B++ ) {
 	fragment_t *fp = mp->y[B];
-	if ( fp && fp->coded ){
+	int fi = (fp ? fp - cpi->frag[0] : -1);
+	if ( fp && cp[fi] ){
 	  MBCodedFlag = 1;
 	  break;
 	}
@@ -754,15 +789,15 @@
 
       if ( (BestError > cpi->InterTripOutThresh) &&
 	   (10 * BestError > MBIntraError * 7 ) ) {
-	SetMBMotionVectorsAndMode(mp,&ZeroVect,CODE_INTRA);
+	SetMBMotionVectorsAndMode(cpi,mp,&ZeroVect,CODE_INTRA);
       } else if ( BestError == MBInterError ) {
-	SetMBMotionVectorsAndMode(mp,&ZeroVect,CODE_INTER_NO_MV);
+	SetMBMotionVectorsAndMode(cpi,mp,&ZeroVect,CODE_INTER_NO_MV);
       } else if ( BestError == MBGFError ) {
-	SetMBMotionVectorsAndMode(mp,&ZeroVect,CODE_USING_GOLDEN);
+	SetMBMotionVectorsAndMode(cpi,mp,&ZeroVect,CODE_USING_GOLDEN);
       } else if ( BestError == MBLastInterError ) {
-	SetMBMotionVectorsAndMode(mp,&LastInterMVect,CODE_INTER_LAST_MV);
+	SetMBMotionVectorsAndMode(cpi,mp,&LastInterMVect,CODE_INTER_LAST_MV);
       } else if ( BestError == MBPriorLastInterError ) {
-	SetMBMotionVectorsAndMode(mp,&PriorLastInterMVect,CODE_INTER_PRIOR_LAST);
+	SetMBMotionVectorsAndMode(cpi,mp,&PriorLastInterMVect,CODE_INTER_PRIOR_LAST);
 
 	/* Swap the prior and last MV cases over */
 	TmpMVect = PriorLastInterMVect;
@@ -771,7 +806,7 @@
 
       } else if ( BestError == MBInterMVError ) {
 
-	SetMBMotionVectorsAndMode(mp,&InterMVect,CODE_INTER_PLUS_MV);
+	SetMBMotionVectorsAndMode(cpi,mp,&InterMVect,CODE_INTER_PLUS_MV);
 
 	/* Update Prior last mv with last mv */
 	PriorLastInterMVect.x = LastInterMVect.x;
@@ -785,7 +820,7 @@
 
       } else if ( BestError == MBGF_MVError ) {
 
-	SetMBMotionVectorsAndMode(mp,&GFMVect,CODE_GOLDEN_MV);
+	SetMBMotionVectorsAndMode(cpi,mp,&GFMVect,CODE_GOLDEN_MV);
 
 	/* Note last inter GF MV for future use */
 	LastGFMVect.x = GFMVect.x;
@@ -813,12 +848,15 @@
 	  FourMVect[4].y = (FourMVect[4].y - 2) / 4;
 	FourMVect[5].y = FourMVect[4].y;
 
-	SetFragMotionVectorAndMode(mp->y[0], &FourMVect[0],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(mp->y[1], &FourMVect[1],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(mp->y[2], &FourMVect[2],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(mp->y[3], &FourMVect[3],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(mp->u, &FourMVect[4],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(mp->v, &FourMVect[5],CODE_INTER_FOURMV);
+	{
+	  fragment_t *f0 = cpi->frag[0];
+	  SetFragMotionVectorAndMode(cpi,mp->y[0]-f0, &FourMVect[0],CODE_INTER_FOURMV);
+	  SetFragMotionVectorAndMode(cpi,mp->y[1]-f0, &FourMVect[1],CODE_INTER_FOURMV);
+	  SetFragMotionVectorAndMode(cpi,mp->y[2]-f0, &FourMVect[2],CODE_INTER_FOURMV);
+	  SetFragMotionVectorAndMode(cpi,mp->y[3]-f0, &FourMVect[3],CODE_INTER_FOURMV);
+	  SetFragMotionVectorAndMode(cpi,mp->u-f0, &FourMVect[4],CODE_INTER_FOURMV);
+	  SetFragMotionVectorAndMode(cpi,mp->v-f0, &FourMVect[5],CODE_INTER_FOURMV);
+	}
 
 	/* Note the four MVs values for current macro-block. */
 	CountMotionVector( cpi, &FourMVect[0]);
@@ -834,7 +872,7 @@
 
       } else {
 
-	SetMBMotionVectorsAndMode(mp,&ZeroVect,CODE_INTRA);
+	SetMBMotionVectorsAndMode(cpi, mp,&ZeroVect,CODE_INTRA);
 
       }
 

Modified: branches/theora-thusnelda/lib/enc/encoder_toplevel.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_toplevel.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/encoder_toplevel.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -32,7 +32,7 @@
   /* code all blocks */
   for(i=0;i<3;i++)
     for(j=0;j<cpi->frag_n[i];j++)
-      cpi->frag[i][j].coded=1;
+      cpi->frag_coded[i][j]=1;
   
   /* Set up for a KEY FRAME */
   cpi->FrameType = KEY_FRAME;
@@ -72,13 +72,17 @@
 }
 
 static int CompressFrame( CP_INSTANCE *cpi ) {
-  ogg_uint32_t  i,j;
+  ogg_uint32_t InterError;
+  ogg_uint32_t IntraError;
+  ogg_uint32_t  i;
   ogg_uint32_t  KFIndicator = 0;
   fragment_t *fp = cpi->frag[0];
+  int fi = 0;
 
   /* Clear down the macro block level mode and MV arrays. */
-  for ( i = 0; i < cpi->frag_total; i++, fp++ ) {
-    fp->mode = CODE_INTER_NO_MV;  /* Default coding mode */
+  for ( i = 0; i < cpi->frag_total; i++, fp++, fi++ ) {
+    cpi->frag_mode[0][fi] = CODE_INTER_NO_MV;  /* Default coding mode */
+    cpi->frag_coded[0][fi] = 1; /* TEMPORARY */
     fp->mv.x=0;
     fp->mv.y=0;
   }
@@ -86,48 +90,30 @@
   /* Default to delta frames. */
   cpi->FrameType = DELTA_FRAME;
 
-  /* Clear down the difference arrays for the current frame. */
-  for(i=0;i<3;i++)
-    for(j=0;j<cpi->frag_n[i];j++)
-      cpi->frag[i][j].coded=0;
-
-  {
-    /*  pick all the macroblock modes and motion vectors */
-    ogg_uint32_t InterError;
-    ogg_uint32_t IntraError;
-    
-    /* for now, mark all blocks to be coded... */
-    /* TEMPORARY */
-    for(i=0;i<3;i++)
-      for(j=0;j<cpi->frag_n[i];j++)
-	cpi->frag[i][j].coded=1;
-    
-    /* Select modes and motion vectors for each of the blocks : return
-       an error score for inter and intra */
-    PickModes( cpi, &InterError, &IntraError );
-
-    /* decide whether we really should have made this frame a key frame */
-    /* forcing out a keyframe if the max interval is up is done at a higher level */
-    if( cpi->info.keyframe_auto_p){
-      if( ( 2* IntraError < 5 * InterError )
-          && ( KFIndicator >= (ogg_uint32_t)
-               cpi->info.keyframe_auto_threshold)
-          && ( cpi->LastKeyFrame > cpi->info.keyframe_mindistance)
-          ){
-        CompressKeyFrame(cpi);  /* Code a key frame */
-        return 0;
-      }
-
+  /* Select modes and motion vectors for each of the blocks : return
+     an error score for inter and intra */
+  PickModes( cpi, &InterError, &IntraError );
+  
+  /* decide whether we really should have made this frame a key frame */
+  /* forcing out a keyframe if the max interval is up is done at a higher level */
+  if( cpi->info.keyframe_auto_p){
+    if( ( 2* IntraError < 5 * InterError )
+	&& ( KFIndicator >= (ogg_uint32_t)
+	     cpi->info.keyframe_auto_threshold)
+	&& ( cpi->LastKeyFrame > cpi->info.keyframe_mindistance)
+	){
+      CompressKeyFrame(cpi);  /* Code a key frame */
+      return 0;
     }
-
-    /* Increment the frames since last key frame count */
-    cpi->LastKeyFrame++;
-
-    /* Proceed with the frame update. */
-    UpdateFrame(cpi);
-
+    
   }
+  
+  /* Increment the frames since last key frame count */
+  cpi->LastKeyFrame++;
 
+  /* Proceed with the frame update. */
+  UpdateFrame(cpi);
+  
   return 0;
 }
 

Modified: branches/theora-thusnelda/lib/enc/frarray.c
===================================================================
--- branches/theora-thusnelda/lib/enc/frarray.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/frarray.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -114,6 +114,7 @@
   int run_break = 0;
   int partial=0;
   int fully = 1;
+  unsigned char *cp = cpi->frag_coded[0];
 
   /* code the partially coded SB flags */
   for( SB = 0; SB < cpi->super_total; SB++ ) {
@@ -123,8 +124,10 @@
 
     for ( B=0; B<16; B++ ) {
       fragment_t *fp = sp->f[B];
+      int fi = (fp ? fp-cpi->frag[0] : -1);
+
       if ( fp ) {
-	if ( fp->coded ) {
+	if ( cp[fi] ) {
 	  coded = 1; /* SB at least partly coded */
 	}else{
 	  fully = 0;
@@ -168,8 +171,9 @@
     
     for ( B=0; B<16; B++ ) {
       fragment_t *fp = sp->f[B];
+      int fi = (fp ? fp-cpi->frag[0] : -1);
       if ( fp ) {
-	if ( fp->coded ) {
+	if ( cp[fi] ) {
 	  coded = 1;
 	}else{
 	  fully = 0;
@@ -212,8 +216,9 @@
 
     for ( B=0; B<16; B++ ) {
       fragment_t *fp = sp->f[B];      
+      int fi = (fp ? fp-cpi->frag[0] : -1);
       if ( fp ) {
-	if ( fp->coded ) {
+	if ( cp[fi] ) {
 	  coded = 1;
 	}else{
 	  fully = 0; /* SB not fully coded */
@@ -225,19 +230,20 @@
 
     for ( B=0; B<16; B++ ) {
       fragment_t *fp = sp->f[B];      
+      int fi = (fp ? fp-cpi->frag[0] : -1);
       if(fp){
 	if(run_last == -1){
-	  oggpackB_write( cpi->oggbuffer, fp->coded, 1);      
-	  run_last = fp->coded;
+	  oggpackB_write( cpi->oggbuffer, cp[fi], 1);      
+	  run_last = cp[fi];
 	}
 	
-	if(run_last == fp->coded){
+	if(run_last == cp[fi]){
 	  run_count++;
 	}else{
 	  FrArrayCodeBlockRun( cpi, run_count );
 	  run_count=1;
 	}
-	run_last=fp->coded;
+	run_last=cp[fi];
       }
     }
   }

Modified: branches/theora-thusnelda/lib/enc/frinit.c
===================================================================
--- branches/theora-thusnelda/lib/enc/frinit.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/frinit.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -48,6 +48,16 @@
   cpi->frag[1] = 0;
   cpi->frag[2] = 0;
 
+  if(cpi->frag_coded[0]) _ogg_free(cpi->frag_coded[0]);
+  cpi->frag_coded[0] = 0;
+  cpi->frag_coded[1] = 0;
+  cpi->frag_coded[2] = 0;
+
+  if(cpi->frag_mode[0]) _ogg_free(cpi->frag_mode[0]);
+  cpi->frag_mode[0] = 0;
+  cpi->frag_mode[1] = 0;
+  cpi->frag_mode[2] = 0;
+
   if(cpi->macro) _ogg_free(cpi->macro);
   cpi->macro = 0;
 
@@ -125,6 +135,14 @@
   cpi->frag[1] = cpi->frag[0] + cpi->frag_n[0];
   cpi->frag[2] = cpi->frag[1] + cpi->frag_n[1];
 
+  cpi->frag_coded[0] = calloc(cpi->frag_total, sizeof(**cpi->frag_coded));
+  cpi->frag_coded[1] = cpi->frag_coded[0] + cpi->frag_n[0];
+  cpi->frag_coded[2] = cpi->frag_coded[1] + cpi->frag_n[1];
+
+  cpi->frag_mode[0] = calloc(cpi->frag_total, sizeof(**cpi->frag_mode));
+  cpi->frag_mode[1] = cpi->frag_mode[0] + cpi->frag_n[0];
+  cpi->frag_mode[2] = cpi->frag_mode[1] + cpi->frag_n[1];
+
   cpi->macro = calloc(cpi->macro_total, sizeof(*cpi->macro));
 
   cpi->super[0] = calloc(cpi->super_total, sizeof(**cpi->super));

Modified: branches/theora-thusnelda/lib/enc/mcomp.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mcomp.c	2007-12-15 17:51:33 UTC (rev 14308)
+++ branches/theora-thusnelda/lib/enc/mcomp.c	2007-12-18 07:46:54 UTC (rev 14309)
@@ -147,16 +147,19 @@
 
   ogg_uint32_t  IntraError = 0;
   dsp_save_fpu (cpi->dsp);
+  unsigned char *cp = cpi->frag_coded[0];
 
+  fragment_t *f0 = cpi->frag[0];
+  
   /* Add together the intra errors for those blocks in the macro block
      that are coded (Y only) */
-  if ( mp->y[0] && mp->y[0]->coded )
+  if ( mp->y[0] && cp[mp->y[0]-f0] )
     IntraError += dsp_intra8x8_err (cpi->dsp, &cpi->frame[mp->y[0]->buffer_index],cpi->stride[0]);
-  if ( mp->y[1] && mp->y[1]->coded )
+  if ( mp->y[1] && cp[mp->y[1]-f0] )
     IntraError += dsp_intra8x8_err (cpi->dsp, &cpi->frame[mp->y[1]->buffer_index],cpi->stride[0]);
-  if ( mp->y[2] && mp->y[2]->coded )
+  if ( mp->y[2] && cp[mp->y[2]-f0] )
     IntraError += dsp_intra8x8_err (cpi->dsp, &cpi->frame[mp->y[2]->buffer_index],cpi->stride[0]);
-  if ( mp->y[3] && mp->y[3]->coded )
+  if ( mp->y[3] && cp[mp->y[3]-f0] )
     IntraError += dsp_intra8x8_err (cpi->dsp, &cpi->frame[mp->y[3]->buffer_index],cpi->stride[0]);
 
   dsp_restore_fpu (cpi->dsp);
@@ -177,6 +180,9 @@
   
   unsigned char * SrcPtr1;
   unsigned char * RefPtr1;
+  unsigned char *cp = cpi->frag_coded[0];
+
+  fragment_t *f0 = cpi->frag[0];
   
   dsp_save_fpu (cpi->dsp);
   
@@ -196,26 +202,26 @@
 
   /* Add together the errors for those blocks in the macro block that
      are coded (Y only) */
-  if ( mp->y[0] && mp->y[0]->coded ) {
+  if ( mp->y[0] && cp[mp->y[0]-f0] ) {
     SrcPtr1 = &SrcPtr[mp->y[0]->buffer_index];
     RefPtr1 = &RefPtr[mp->y[0]->buffer_index + RefPixelOffset];
     InterError += GetInterErr(cpi, SrcPtr1, RefPtr1, &RefPtr1[RefPtr2Offset] );
   }
 
-  if ( mp->y[1] && mp->y[1]->coded ) {
+  if ( mp->y[1] && cp[mp->y[1]-f0] ) {
     SrcPtr1 = &SrcPtr[mp->y[1]->buffer_index];
     RefPtr1 = &RefPtr[mp->y[1]->buffer_index + RefPixelOffset];
     InterError += GetInterErr(cpi, SrcPtr1, RefPtr1, &RefPtr1[RefPtr2Offset] );
     
   }
   
-  if ( mp->y[2] && mp->y[2]->coded ) {
+  if ( mp->y[2] && cp[mp->y[2]-f0] ) {
     SrcPtr1 = &SrcPtr[mp->y[2]->buffer_index];
     RefPtr1 = &RefPtr[mp->y[2]->buffer_index + RefPixelOffset];
     InterError += GetInterErr(cpi, SrcPtr1, RefPtr1, &RefPtr1[RefPtr2Offset] );
   }
 
-  if ( mp->y[3] && mp->y[3]->coded ) {
+  if ( mp->y[3] && cp[mp->y[3]-f0] ) {
     SrcPtr1 = &SrcPtr[mp->y[3]->buffer_index];
     RefPtr1 = &RefPtr[mp->y[3]->buffer_index + RefPixelOffset];
     InterError += GetInterErr(cpi, SrcPtr1, RefPtr1, &RefPtr1[RefPtr2Offset] );
@@ -252,15 +258,18 @@
   unsigned char   BestHalfOffset;
   unsigned char * RefDataPtr1;
   unsigned char * RefDataPtr2;
+  unsigned char *cp = cpi->frag_coded[0];
 
+  fragment_t *f0 = cpi->frag[0];
+
   dsp_save_fpu (cpi->dsp);
 
   /* Note which of the four blocks in the macro block are to be
      included in the search. */
-  disp[0] = (mp->y[0] && mp->y[0]->coded);
-  disp[1] = (mp->y[1] && mp->y[1]->coded);
-  disp[2] = (mp->y[2] && mp->y[2]->coded);
-  disp[3] = (mp->y[3] && mp->y[3]->coded);
+  disp[0] = (mp->y[0] && cp[mp->y[0]-f0]);
+  disp[1] = (mp->y[1] && cp[mp->y[1]-f0]);
+  disp[2] = (mp->y[2] && cp[mp->y[2]-f0]);
+  disp[3] = (mp->y[3] && cp[mp->y[3]-f0]);
 
   if(disp[0]){
     SrcPtr[0] = &cpi->frame[mp->y[0]->buffer_index];
@@ -428,15 +437,18 @@
   unsigned char * RefDataPtr1;
   unsigned char * RefDataPtr2;
   int off;
+  unsigned char *cp = cpi->frag_coded[0];
 
+  fragment_t *f0 = cpi->frag[0];
+
   dsp_save_fpu (cpi->dsp);
 
   /* Note which of the four blocks in the macro block are to be
      included in the search. */
-  disp[0] = (mp->y[0] && mp->y[0]->coded);
-  disp[1] = (mp->y[1] && mp->y[1]->coded);
-  disp[2] = (mp->y[2] && mp->y[2]->coded);
-  disp[3] = (mp->y[3] && mp->y[3]->coded);
+  disp[0] = (mp->y[0] && cp[mp->y[0]-f0]);
+  disp[1] = (mp->y[1] && cp[mp->y[1]-f0]);
+  disp[2] = (mp->y[2] && cp[mp->y[2]-f0]);
+  disp[3] = (mp->y[3] && cp[mp->y[3]-f0]);
 
   if(disp[0]){
     SrcPtr[0] = &cpi->frame[mp->y[0]->buffer_index];
@@ -648,15 +660,19 @@
 					macroblock_t *mp,
                                         mv_t *MV ) {
   ogg_uint32_t  InterMVError;
+  unsigned char *cp = cpi->frag_coded[0];
+
+  fragment_t *f0 = cpi->frag[0];
+
   dsp_save_fpu (cpi->dsp);
 
   /* For the moment the 4MV mode is only deemed to be valid 
      if all four Y blocks are to be updated */
   /* This may be adapted later. */
-  if ( mp->y[0] && mp->y[0]->coded &&
-       mp->y[1] && mp->y[1]->coded &&
-       mp->y[2] && mp->y[2]->coded &&
-       mp->y[3] && mp->y[3]->coded ) {
+  if ( mp->y[0] && cp[mp->y[0]-f0] &&
+       mp->y[1] && cp[mp->y[1]-f0] &&
+       mp->y[2] && cp[mp->y[2]-f0] &&
+       mp->y[3] && cp[mp->y[3]-f0] ) {
     
     /* Reset the error score. */
     InterMVError = 0;



More information about the commits mailing list