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

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Thu Dec 27 07:26:35 PST 2007


Author: xiphmont
Date: 2007-12-27 07:26:33 -0800 (Thu, 27 Dec 2007)
New Revision: 14326

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_lookup.h
   branches/theora-thusnelda/lib/enc/encoder_toplevel.c
   branches/theora-thusnelda/lib/enc/frinit.c
Log:
Begin the process of 'beefing up' the macroblock abstraction to support the analysis fields as needed by Derf's MV code.

This moves all mode information to MB, moves several abstractions closer to supporting 4:2:2 and 4:4:4, and fixes a heap bug by eliminating the offending code.



Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h	2007-12-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h	2007-12-27 15:26:33 UTC (rev 14326)
@@ -111,15 +111,20 @@
 } mv_t;
 
 typedef struct macroblock {
+  /* the blocks comprising this macroblock */
   int y[4]; // raster order
   int u;
   int v;
+
+  coding_mode_t mode;
+  mv_t mv[4];
+
 } macroblock_t;
 
 #define SB_MB_BLFRAG(sb,mbnum) ((sb).f[ ((mbnum)<2? ((mbnum)==0?0:4) : ((mbnum)==2?8:14)) ])
 typedef struct superblock {
   int f[16]; // hilbert order
-  int m[4];  // hilbert order
+  int m[16]; // hilbert order; 4 for Y, 4 for UZ in 4:4:4, 8 for UV in 4:2:2, 16 for UV in 4:2:0
 } superblock_t;
 
 typedef ogg_int16_t    quant_table[64];
@@ -151,7 +156,6 @@
 
   /* SuperBlock, MacroBLock and Fragment Information */
   unsigned char   *frag_coded;
-  coding_mode_t   *frag_mode;
   ogg_uint32_t    *frag_buffer_index;
   mv_t            *frag_mv;
   unsigned char   *frag_nonzero;
@@ -192,9 +196,6 @@
   /*********************************************************************/
   /* Token Buffers */
 
-  int             *coded_fi_list;
-  int              coded_fi_count;
-
   unsigned char   *dct_token_storage;
   ogg_uint16_t    *dct_token_eb_storage;
   unsigned char   *dct_token[64];
@@ -276,7 +277,7 @@
 
 extern void DPCMTokenize (CP_INSTANCE *cpi);
 
-extern void TransformQuantizeBlock (CP_INSTANCE *cpi, int fi) ;
+extern void TransformQuantizeBlock (CP_INSTANCE *cpi, coding_mode_t mode, 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-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/dct_decode.c	2007-12-27 15:26:33 UTC (rev 14326)
@@ -35,8 +35,7 @@
   }
 }
 
-static void ExpandBlock ( CP_INSTANCE *cpi, int fi){
-  int           mode = cpi->frag_mode[fi];
+static void ExpandBlock ( CP_INSTANCE *cpi, coding_mode_t mode, int fi){
   int           qi = cpi->BaseQ; // temporary 
   int           plane = (fi<cpi->frag_n[0] ? 0 : (fi-cpi->frag_n[0]<cpi->frag_n[1] ? 1 : 2));
   int           inter = (mode != CODE_INTRA);
@@ -446,11 +445,29 @@
 }
 
 void ReconRefFrames (CP_INSTANCE *cpi){
-  int *fip = cpi->coded_fi_list;
-  
-  while(*fip>=0){
-    ExpandBlock( cpi, *fip );
-    fip++;
+  int i;
+  unsigned char *cp = cpi->frag_coded;
+  macroblock_t *mp = cpi->macro;
+
+  for (i=0; i<cpi->macro_total; i++, mp++ ) {
+    coding_mode_t mode = mp->mode;
+    int fi = mp->y[0];
+    if ( cp[fi] ) ExpandBlock( cpi, mode, fi );
+
+    fi = mp->y[1];
+    if ( cp[fi] ) ExpandBlock( cpi, mode, fi );
+
+    fi = mp->y[2];
+    if ( cp[fi] ) ExpandBlock( cpi, mode, fi );
+
+    fi = mp->y[3];
+    if ( cp[fi] ) ExpandBlock( cpi, mode, fi );
+
+    fi = mp->u;
+    if ( cp[fi] ) ExpandBlock( cpi, mode, fi );
+
+    fi = mp->v;
+    if ( cp[fi] ) ExpandBlock( cpi, mode, fi );
   }
 
   memcpy(cpi->lastrecon,cpi->recon,sizeof(*cpi->recon)*cpi->frame_size);

Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c	2007-12-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c	2007-12-27 15:26:33 UTC (rev 14326)
@@ -206,74 +206,81 @@
 
 static void tokenize_groups(CP_INSTANCE *cpi,
 			    int *eob_run, int *eob_plane, int *eob_ypre, int *eob_uvpre){
-  int *fip = cpi->coded_fi_list;
+  int SB,B;
+  unsigned char *cp=cpi->frag_coded;
 
-  while(*fip>=0){
-    int coeff = 0;
-    int plane = (*fip >= cpi->frag_n[0]);
-    dct_t *dct = &cpi->frag_dct[*fip];
-    cpi->frag_nonzero[*fip] = 0;
-    
-    while(coeff < BLOCK_SIZE){
-      ogg_int16_t val = dct->data[coeff];
-      int zero_run;
-      int i = coeff;
-  
-      cpi->frag_nonzero[*fip] = coeff;
-      
-      while( !val && (++i < BLOCK_SIZE) )
-	val = dct->data[i];
-      
-      if ( i == BLOCK_SIZE ){
+  for ( SB=0; SB<cpi->super_total; SB++ ){
+    superblock_t *sp = &cpi->super[0][SB];
+    for ( B=0; B<16; B++ ) {
+      int fi = sp->f[B];
+      if ( cp[fi] ) {
 
-	/* if there are no other tokens in this group yet, set up to be
-	   prepended later.  Group 0 is the exception (can't be
-	   prepended) */
-	if(cpi->dct_token_count[coeff] == 0 && coeff){
-	  if(!plane)
-	    eob_ypre[coeff]++;
-	  else
-	    eob_uvpre[coeff]++;
-	}else{
-	  if(eob_run[coeff] == 4095){
-	    emit_eob_run(cpi,eob_plane[coeff],coeff,4095);
-	    eob_run[coeff] = 0;
-	  }
+	int coeff = 0;
+	int plane = (fi >= cpi->frag_n[0]);
+	dct_t *dct = &cpi->frag_dct[fi];
+	cpi->frag_nonzero[fi] = 0;
+	
+	while(coeff < BLOCK_SIZE){
+	  ogg_int16_t val = dct->data[coeff];
+	  int zero_run;
+	  int i = coeff;
 	  
-	  if(eob_run[coeff]==0)
-	    eob_plane[coeff]=plane;
+	  cpi->frag_nonzero[fi] = coeff;
 	  
-	  eob_run[coeff]++;
-	}
-	coeff = BLOCK_SIZE;
-      }else{
-	
-	if(eob_run[coeff]){
-	  emit_eob_run(cpi,eob_plane[coeff],coeff,eob_run[coeff]);
-	  eob_run[coeff]=0;
-	}
-	
-	zero_run = i-coeff;
-	if (zero_run){
-	  ogg_uint32_t absval = abs(val);
-	  if ( ((absval == 1) && (zero_run <= 17)) ||
-	       ((absval <= 3) && (zero_run <= 3)) ) {
-	    TokenizeDctRunValue( cpi, plane, coeff, zero_run, val);
-	    coeff = i+1;
+	  while( !val && (++i < BLOCK_SIZE) )
+	    val = dct->data[i];
+	  
+	  if ( i == BLOCK_SIZE ){
+	    
+	    /* if there are no other tokens in this group yet, set up to be
+	       prepended later.  Group 0 is the exception (can't be
+	       prepended) */
+	    if(cpi->dct_token_count[coeff] == 0 && coeff){
+	      if(!plane)
+		eob_ypre[coeff]++;
+	      else
+		eob_uvpre[coeff]++;
+	    }else{
+	      if(eob_run[coeff] == 4095){
+		emit_eob_run(cpi,eob_plane[coeff],coeff,4095);
+		eob_run[coeff] = 0;
+	      }
+	      
+	      if(eob_run[coeff]==0)
+		eob_plane[coeff]=plane;
+	      
+	      eob_run[coeff]++;
+	    }
+	    coeff = BLOCK_SIZE;
 	  }else{
-	    if ( zero_run <= 8 )
-	      add_token(cpi, plane, coeff, DCT_SHORT_ZRL_TOKEN, zero_run - 1);
-	    else
-	      add_token(cpi, plane, coeff, DCT_ZRL_TOKEN, zero_run - 1);
-	    coeff = i;
+	    
+	    if(eob_run[coeff]){
+	      emit_eob_run(cpi,eob_plane[coeff],coeff,eob_run[coeff]);
+	      eob_run[coeff]=0;
+	    }
+	    
+	    zero_run = i-coeff;
+	    if (zero_run){
+	      ogg_uint32_t absval = abs(val);
+	      if ( ((absval == 1) && (zero_run <= 17)) ||
+		   ((absval <= 3) && (zero_run <= 3)) ) {
+		TokenizeDctRunValue( cpi, plane, coeff, zero_run, val);
+		coeff = i+1;
+	      }else{
+		if ( zero_run <= 8 )
+		  add_token(cpi, plane, coeff, DCT_SHORT_ZRL_TOKEN, zero_run - 1);
+		else
+		  add_token(cpi, plane, coeff, DCT_ZRL_TOKEN, zero_run - 1);
+		coeff = i;
+	      }
+	    }else{
+	      TokenizeDctValue( cpi, plane, coeff, val );
+	      coeff = i+1;
+	    }
 	  }
-	}else{
-	  TokenizeDctValue( cpi, plane, coeff, val );
-	  coeff = i+1;
 	}
       }
     }
-    fip++;
   }
 }
 
@@ -516,9 +523,9 @@
 }
 
 void TransformQuantizeBlock (CP_INSTANCE *cpi, 
+			     coding_mode_t mode,
 			     int fi){
-  
-  coding_mode_t mode = cpi->frag_mode[fi];
+
   unsigned char *cp = &cpi->frag_coded[fi];
 
   unsigned char *FiltPtr = &cpi->frame[cpi->frag_buffer_index[fi]];

Modified: branches/theora-thusnelda/lib/enc/encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encode.c	2007-12-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/encode.c	2007-12-27 15:26:33 UTC (rev 14326)
@@ -20,166 +20,183 @@
 #include "codec_internal.h"
 #include "encoder_lookup.h"
 
-static void PredictDC(CP_INSTANCE *cpi){
-  ogg_int32_t plane;
-  int k,m,n;
+static void predict_frag(CP_INSTANCE  *cpi,
+			 ogg_int16_t  *Last,
+			 
+			 macroblock_t *mb, 
+			 macroblock_t *mb_left, 
+			 macroblock_t *mb_downleft,
+			 macroblock_t *mb_down,
+			 macroblock_t *mb_downright, 
+			 
+			 int fi,
+			 int fi_down){
 
-  /* value left value up-left, value up, value up-right, missing
-      values skipped. */
-  int v[4];
-
-  /* fragment number left, up-left, up, up-right */
-  int fn[4];
-
-  /* predictor count. */
-  int pcount;
-
-  /*which predictor constants to use */
-  ogg_int16_t wpc;
-
-  /* last used inter predictor (Raster Order) */
-  ogg_int16_t Last[3];  /* last value used for given frame */
-
-  coding_mode_t *mp = cpi->frag_mode;
   unsigned char *cp = cpi->frag_coded;
-  dct_t         *dct = cpi->frag_dct;
   ogg_int16_t   *dc = cpi->frag_dc;
-  int fi = 0;
+  dct_t        *dct = cpi->frag_dct;
+  int wpc = 0;
 
-  /* for y,u,v */
-  for ( plane = 0; plane < 3 ; plane++) {
-
-    for(k=0;k<3;k++)Last[k]=0;
-    fn[0]=1;
-    fn[1]=cpi->frag_h[plane]+1;
-    fn[2]=cpi->frag_h[plane];
-    fn[3]=cpi->frag_h[plane]-1;
+  /* only do 2 prediction if fragment coded and on non intra or
+     if all fragments are intra */
+  if(cp[fi]) {
     
-    /* 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++, fi++) {
+    int WhichFrame = Mode2Frame[mb->mode];
+    
+    /* L, DL, D, DR */
+    if(mb_left && cp[fi-1] && Mode2Frame[mb_left->mode] == WhichFrame)
+      wpc|=1;
+    if(mb_downleft && cp[fi_down-1] && Mode2Frame[mb_downleft->mode] == WhichFrame)
+      wpc|=2;
+    if(mb_down && cp[fi_down] && Mode2Frame[mb_down->mode] == WhichFrame)
+      wpc|=4;
+    if(mb_downright && cp[fi_down+1] && Mode2Frame[mb_downright->mode] == WhichFrame)
+      wpc|=8;
 
-        /* only do 2 prediction if fragment coded and on non intra or
-           if all fragments are intra */
-        if(cp[fi]) {
+    if(wpc){
+      ogg_int16_t DC = 0;
 
-          int WhichFrame = Mode2Frame[mp[fi]];
+      if(wpc&0x1) DC += pc[wpc][0]*dc[fi-1];
+      if(wpc&0x2) DC += pc[wpc][1]*dc[fi_down-1];
+      if(wpc&0x4) DC += pc[wpc][2]*dc[fi_down];
+      if(wpc&0x8) DC += pc[wpc][3]*dc[fi_down+1];
 
-          /* Check Borderline Cases */
-          int WhichCase = (n==0) + ((m==0) << 1) + ((n+1 == cpi->frag_h[plane]) << 2);
+      /* if we need to do a shift */
+      if(pc[wpc][4]) {
+	/* If negative add in the negative correction factor */
+	DC += (HIGHBITDUPPED(DC) & pc[wpc][5]);
+	/* Shift in lieu of a divide */
+	DC >>= pc[wpc][4];
+      }
+      
+      /* check for outranging on the two predictors that can outrange */
+      if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){
+	if( abs(DC - dc[fi_down]) > 128) {
+	  DC = dc[fi_down];
+	} else if( abs(DC - dc[fi-1]) > 128) {
+	  DC = dc[fi-1];
+	} else if( abs(DC - dc[fi_down-1]) > 128) {
+	  DC = dc[fi_down-1];
+	}
+      }
+      
+      dct[fi].data[0] = dc[fi] - DC;
+    
+    }else{
+      dct[fi].data[0] = dc[fi] - Last[WhichFrame];
+    }
 
-          /* fragment valid for prediction use if coded and it comes
-             from same frame as the one we are predicting */
-          for(k=pcount=wpc=0; k<4; k++) {
-            int pflag = 1<<k;
-            if((bc_mask[WhichCase]&pflag)){
-	      int fni = fi - fn[k];	
-	      if(cp[fni] &&
-		 (Mode2Frame[mp[fni]] == WhichFrame)){
-		v[pcount]=dc[fni];
-		wpc|=pflag;
-		pcount++;
-	      }
-	    }
-          }
+    /* Save the last fragment coded for whatever frame we are
+       predicting from */
+    
+    Last[WhichFrame] = dc[fi];
+  }
+}
 
-          if(wpc==0) {
+static void PredictDC(CP_INSTANCE *cpi){
+  ogg_int32_t plane;
+  ogg_int16_t Last[3];  /* last value used for given frame */
+  int y,y2,x,fi = 0;
 
-            /* fall back to the last coded fragment */
-            dct[fi].data[0] = dc[fi] - Last[WhichFrame];
+  /* for y,u,v; handles arbitrary plane subsampling arrangement.  Shouldn't need to be altered for 4:2:2 or 4:4:4 */
+  for ( plane = 0; plane < 3 ; plane++) {
+    macroblock_t *mb_row = cpi->macro;
+    macroblock_t *mb_down = NULL;
+    int fi_stride = cpi->frag_h[plane];
+    int v = cpi->macro_v;
+    int h = cpi->macro_h;
 
-          } else {
+    for(x=0;x<3;x++)Last[x]=0;
 
-            /* don't do divide if divisor is 1 or 0 */
-            ogg_int16_t DC = pc[wpc][0]*v[0];
-            for(k=1; k<pcount; k++)
-              DC += pc[wpc][k]*v[k];
-	    
-            /* if we need to do a shift */
-            if(pc[wpc][4] != 0 ) {
-	      
-              /* If negative add in the negative correction factor */
-              DC += (HIGHBITDUPPED(DC) & pc[wpc][5]);
-              /* Shift in lieu of a divide */
-              DC >>= pc[wpc][4];
+    for ( y = 0 ; y < v ; y++) {
+      for ( y2 = 0 ; y2 <= (cpi->macro_v < cpi->frag_v[plane]) ; y2++) {
 
-            }
+	macroblock_t *mb = mb_row;
+	macroblock_t *mb_left = NULL;
+	macroblock_t *mb_downleft = NULL;
+	macroblock_t *mb_downright = ((1<h && mb_down) ? mb_down+1: NULL);	    
 
-            /* check for outranging on the two predictors that can outrange */
-            if((wpc&(PU|PUL|PL)) == (PU|PUL|PL)){
-              if( abs(DC - v[2]) > 128) {
-                DC = v[2];
-              } else if( abs(DC - v[0]) > 128) {
-                DC = v[0];
-              } else if( abs(DC - v[1]) > 128) {
-                DC = v[1];
-              }
-            }
-
-            dct[fi].data[0] = dc[fi] - DC;
-          }
-
-          /* Save the last fragment coded for whatever frame we are
-             predicting from */
-
-          Last[WhichFrame] = dc[fi];
-
-        }
+	if(h < cpi->frag_h[plane]){
+	  for ( x = 0 ; x < h ; x++) {
+	    predict_frag(cpi,Last,mb, mb_left,mb_downleft,mb_down,mb_down, fi,fi-fi_stride);
+	    predict_frag(cpi,Last,mb, mb,mb_down,mb_down,mb_downright, fi+1,fi-fi_stride+1);
+	    fi+=2;
+	    mb_left = mb;
+	    mb_downleft = mb_down;
+	    
+	    mb++;
+	    if(mb_down){
+	      mb_down++;
+	      mb_downright = (x+2<h ? mb_down+1: NULL);	    
+	    }
+	  }
+	}else{
+	  for ( x = 0 ; x < h ; x++) {
+	    
+	    predict_frag(cpi,Last,mb, mb_left,mb_downleft,mb_down,mb_downright, fi,fi-fi_stride);
+	    fi++;
+	    mb_left = mb;
+	    mb_downleft = mb_down;
+	    
+	    mb++;
+	    if(mb_down){
+	      mb_down++;
+	      mb_downright = (x+2<h ? mb_down+1: NULL);	    
+	    }	    
+	  }
+	}
+	mb_down = mb_row;
       }
+      
+      mb_row += h;
     }
   }
 }
 
-
-static ogg_uint32_t CodePlane ( CP_INSTANCE *cpi,
-				int plane ){
-
-  ogg_uint32_t SBs = cpi->super_n[plane];
+static ogg_uint32_t CodePlane ( CP_INSTANCE *cpi, int plane, int subsample){
+  ogg_uint32_t n = cpi->super_n[plane];
   ogg_uint32_t SB, MB, B;
-  coding_mode_t *mp = cpi->frag_mode;
   unsigned char *cp = cpi->frag_coded;
+  superblock_t *sp = cpi->super[plane];
 
-  /* actually transform and quantize the image now that we've decided
-     on the modes Parse in quad-tree ordering */
-
-  for ( SB=0; SB<SBs; SB++ ){
-    superblock_t *sp = &cpi->super[plane][SB];
-    int frag=0;
-
-    int SBi = SB;
-    if(plane>0)SBi+=cpi->super_n[0];
-    if(plane>1)SBi+=cpi->super_n[1];
-
-    for ( MB=0; MB<4; MB++ ) {
-      int coded = 0;
-      int mode = 0;
-
-      for ( B=0; B<4; B++, frag++ ) {
-	int fi = sp->f[frag];
-
-	if ( cp[fi] ) {
-
-	  /* transform and quantize block */
-	  TransformQuantizeBlock( cpi, fi );
+  switch(subsample){
+  case 1:
+    for ( SB=0; SB<n; SB++,sp++ ){
+      int frag = 0;
+      
+      for ( MB=0; MB<4; MB++ ) {
+	macroblock_t *mp = &cpi->macro[sp->m[MB]];
+	unsigned char coded = 0;
+	
+	for ( B=0; B<4; B++, frag++ ) {
+	  int fi = sp->f[frag];
 	  
-	  /* 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 ( cp[fi] ) {
-	    cpi->coded_fi_list[cpi->coded_fi_count++]=fi;
-	    coded = 1;
-	    mode = mp[fi];	    
+	    TransformQuantizeBlock( cpi, mp->mode, fi );
+	    coded |= cp[fi];
 	  }
 	}
-      }
-     
-      /* If the MB is marked as coded and we are in the Y plane */
-      /* collect coding metric */
-      if ( coded && plane == 0 ) cpi->ModeCount[mode] ++;
-
-    }  
+	if ( plane == 0 && coded ) 
+	  cpi->ModeCount[mp->mode] ++;
+	
+      }  
+    }
+    return 0;
+  case 2:
+    /* fill me in when we need to support 4:2:2 */
+    return 1;
+  case 4:
+    for ( SB=0; SB<n; SB++,sp++ ){
+      for ( MB=0; MB<16; MB++ ) { /* MB:B :: 1:1 */
+	int fi = sp->f[MB];
+	if ( cp[fi] ) 
+	  TransformQuantizeBlock( cpi, cpi->macro[sp->m[MB]].mode, fi );
+      }  
+    }
+    return 0;
+  default:
+    return 1;
   }
-  return 0;
 }
 
 static void EncodeDcTokenList (CP_INSTANCE *cpi) {
@@ -292,7 +309,6 @@
   const unsigned char  *ModeScheme;
 
   unsigned char *cp = cpi->frag_coded;
-  coding_mode_t *mp = cpi->frag_mode;
   int SB,MB,B;
 
   oggpack_buffer *opb=cpi->oggbuffer;
@@ -378,7 +394,7 @@
   
       if(cp[fi]){
 	/* Add the appropriate mode entropy token. */
-	int index = ModeScheme[mp[fi]];
+	int index = ModeScheme[mbp->mode];
 	oggpackB_write( opb, ModeWords[index],
 			(ogg_uint32_t)ModeBits[index] );
       }
@@ -391,7 +407,6 @@
   const ogg_uint32_t * MvBitsPtr;
 
   ogg_uint32_t SB, MB, B;
-  coding_mode_t *mp = cpi->frag_mode;
   unsigned char *cp = cpi->frag_coded;
   mv_t          *mv = cpi->frag_mv;
 
@@ -419,11 +434,11 @@
       for(B=1; !cp[fi] && B<4; B++ ) fi = mbp->y[B];
       if(B==4) continue;
 
-      if(mp[fi]==CODE_INTER_PLUS_MV || mp[fi]==CODE_GOLDEN_MV){
+      if(mbp->mode==CODE_INTER_PLUS_MV || mbp->mode==CODE_GOLDEN_MV){
 	/* One MV for the macroblock */
 	oggpackB_write( opb, MvPatternPtr[mv[fi].x], MvBitsPtr[mv[fi].x] );
 	oggpackB_write( opb, MvPatternPtr[mv[fi].y], MvBitsPtr[mv[fi].y] );
-      }else if (mp[fi] == CODE_INTER_FOURMV){
+      }else if (mbp->mode == CODE_INTER_FOURMV){
 	/* MV for each codedblock */
 	for(B=0; B<4; B++ ){
 	  fi = mbp->y[B];
@@ -441,17 +456,15 @@
 
   /* reset all coding metadata  */
   memset(cpi->ModeCount, 0, MAX_MODES*sizeof(*cpi->ModeCount));
-  cpi->coded_fi_count = 0;
 
   dsp_save_fpu (cpi->dsp);
 
   /* Encode and tokenise the Y, U and V components */
-  CodePlane(cpi, 0);
-  CodePlane(cpi, 1);
-  CodePlane(cpi, 2);
+  /* 4:2:0 for now */
+  CodePlane(cpi, 0, 1);
+  CodePlane(cpi, 1, 4);
+  CodePlane(cpi, 2, 4);
 
-  cpi->coded_fi_list[cpi->coded_fi_count]=-1;
-  
   PredictDC(cpi);
   DPCMTokenize(cpi);
 
@@ -476,10 +489,12 @@
 ogg_uint32_t PickIntra( CP_INSTANCE *cpi ){
 
   int i;
-  for(i=0;i<cpi->frag_total;i++){
-    cpi->frag_mode[i] = CODE_INTRA;
+  for(i=0;i<cpi->frag_total;i++)
     cpi->frag_coded[i] = 1;
-  }
+
+  for(i=0;i<cpi->macro_total;i++)
+    cpi->macro[i].mode = CODE_INTRA;
+
   return 0;
 }
 
@@ -489,11 +504,9 @@
   cpi->MVBits_1 += 12; /* Simple six bits per mv component fallback */
 }
 
-static void SetFragMotionVectorAndMode(CP_INSTANCE *cpi,
-				       int fi,
-				       mv_t *mv,
-				       int mode){
-  cpi->frag_mode[fi] = mode;
+static void SetFragMotionVector(CP_INSTANCE *cpi,
+				int fi,
+				mv_t *mv){
   cpi->frag_mv[fi] = *mv;
 }
 
@@ -501,12 +514,14 @@
 				      macroblock_t *mp,
 				      mv_t *mv,
 				      int mode){
-  SetFragMotionVectorAndMode(cpi, mp->y[0], mv, mode);
-  SetFragMotionVectorAndMode(cpi, mp->y[1], mv, mode);
-  SetFragMotionVectorAndMode(cpi, mp->y[2], mv, mode);
-  SetFragMotionVectorAndMode(cpi, mp->y[3], mv, mode);
-  SetFragMotionVectorAndMode(cpi, mp->u, mv, mode);
-  SetFragMotionVectorAndMode(cpi, mp->v, mv, mode);
+  mp->mode = mode;
+  mp->mv[0] = *mv;
+  SetFragMotionVector(cpi, mp->y[0], mv);
+  SetFragMotionVector(cpi, mp->y[1], mv);
+  SetFragMotionVector(cpi, mp->y[2], mv);
+  SetFragMotionVector(cpi, mp->y[3], mv);
+  SetFragMotionVector(cpi, mp->u, mv);
+  SetFragMotionVector(cpi, mp->v, mv);
 }
 
 ogg_uint32_t PickModes(CP_INSTANCE *cpi,
@@ -800,12 +815,17 @@
 	  FourMVect[4].y = (FourMVect[4].y - 2) / 4;
 	FourMVect[5].y = FourMVect[4].y;
 
-	SetFragMotionVectorAndMode(cpi,mbp->y[0], &FourMVect[0],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(cpi,mbp->y[1], &FourMVect[1],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(cpi,mbp->y[2], &FourMVect[2],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(cpi,mbp->y[3], &FourMVect[3],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(cpi,mbp->u, &FourMVect[4],CODE_INTER_FOURMV);
-	SetFragMotionVectorAndMode(cpi,mbp->v, &FourMVect[5],CODE_INTER_FOURMV);
+	mbp->mode = CODE_INTER_FOURMV;
+	mbp->mv[0] = FourMVect[0];
+	mbp->mv[1] = FourMVect[1];
+	mbp->mv[2] = FourMVect[2];
+	mbp->mv[3] = FourMVect[3];
+	SetFragMotionVector(cpi,mbp->y[0], &FourMVect[0]);
+	SetFragMotionVector(cpi,mbp->y[1], &FourMVect[1]);
+	SetFragMotionVector(cpi,mbp->y[2], &FourMVect[2]);
+	SetFragMotionVector(cpi,mbp->y[3], &FourMVect[3]);
+	SetFragMotionVector(cpi,mbp->u, &FourMVect[4]);
+	SetFragMotionVector(cpi,mbp->v, &FourMVect[5]);
 
 	/* Note the four MVs values for current macro-block. */
 	CountMotionVector( cpi, &FourMVect[0]);

Modified: branches/theora-thusnelda/lib/enc/encoder_lookup.h
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_lookup.h	2007-12-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/encoder_lookup.h	2007-12-27 15:26:33 UTC (rev 14326)
@@ -125,24 +125,23 @@
 #define HIGHBITDUPPED(X) (((ogg_int16_t) X)  >> 15)
 
 /* predictor multiplier up-left, up, up-right,left, shift
-   Entries are packed in the order L, UL, U, UR, with missing entries
-   moved to the end (before the shift parameters). */
+   Entries are unpacked in the order L, UL, U, UR */
 static const ogg_int16_t pc[16][6]={
   {0,0,0,0,0,0},
   {1,0,0,0,0,0},      /* PL */
-  {1,0,0,0,0,0},      /* PUL */
+  {0,1,0,0,0,0},      /* PUL */
   {1,0,0,0,0,0},      /* PUL|PL */
-  {1,0,0,0,0,0},      /* PU */
-  {1,1,0,0,1,1},      /* PU|PL */
-  {0,1,0,0,0,0},      /* PU|PUL */
+  {0,0,1,0,0,0},      /* PU */
+  {1,0,1,0,1,1},      /* PU|PL */
+  {0,0,1,0,0,0},      /* PU|PUL */
   {29,-26,29,0,5,31}, /* PU|PUL|PL */
-  {1,0,0,0,0,0},      /* PUR */
-  {75,53,0,0,7,127},  /* PUR|PL */
-  {1,1,0,0,1,1},      /* PUR|PUL */
-  {75,0,53,0,7,127},  /* PUR|PUL|PL */
-  {1,0,0,0,0,0},      /* PUR|PU */
-  {75,0,53,0,7,127},  /* PUR|PU|PL */
-  {3,10,3,0,4,15},    /* PUR|PU|PUL */
+  {0,0,0,1,0,0},      /* PUR */
+  {75,0,0,53,7,127},  /* PUR|PL */
+  {0,1,0,1,1,1},      /* PUR|PUL */
+  {75,0,0,53,7,127},  /* PUR|PUL|PL */
+  {0,0,1,0,0,0},      /* PUR|PU */
+  {75,0,0,53,7,127},  /* PUR|PU|PL */
+  {0,3,10,3,4,15},    /* PUR|PU|PUL */
   {29,-26,29,0,5,31}  /* PUR|PU|PUL|PL */
 };
 

Modified: branches/theora-thusnelda/lib/enc/encoder_toplevel.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_toplevel.c	2007-12-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/encoder_toplevel.c	2007-12-27 15:26:33 UTC (rev 14326)
@@ -77,9 +77,11 @@
   ogg_uint32_t  KFIndicator = 0;
   int fi = 0;
 
+  for ( i = 0; i < cpi->macro_total; i++) 
+    cpi->macro[i].mode = CODE_INTER_NO_MV;  /* Default coding mode */
+
   /* Clear down the macro block level mode and MV arrays. */
   for ( i = 0; i < cpi->frag_total; i++, fi++ ) {
-    cpi->frag_mode[fi] = CODE_INTER_NO_MV;  /* Default coding mode */
     cpi->frag_coded[fi] = 1; /* TEMPORARY */
     cpi->frag_mv[fi].x=0;
     cpi->frag_mv[fi].y=0;

Modified: branches/theora-thusnelda/lib/enc/frinit.c
===================================================================
--- branches/theora-thusnelda/lib/enc/frinit.c	2007-12-27 06:22:31 UTC (rev 14325)
+++ branches/theora-thusnelda/lib/enc/frinit.c	2007-12-27 15:26:33 UTC (rev 14326)
@@ -46,9 +46,6 @@
   if(cpi->frag_coded) _ogg_free(cpi->frag_coded);
   cpi->frag_coded = 0;
 
-  if(cpi->frag_mode) _ogg_free(cpi->frag_mode);
-  cpi->frag_mode = 0;
-
   if(cpi->frag_buffer_index) _ogg_free(cpi->frag_buffer_index);
   cpi->frag_buffer_index = 0;
 
@@ -64,9 +61,6 @@
   if(cpi->frag_dc) _ogg_free(cpi->frag_dc);
   cpi->frag_dc = 0;
 
-  if(cpi->coded_fi_list) _ogg_free(cpi->coded_fi_list);
-  cpi->coded_fi_list = 0;
-
   if(cpi->macro) _ogg_free(cpi->macro);
   cpi->macro = 0;
 
@@ -142,16 +136,12 @@
 
   /* +1; the last entry is the 'invalid' frag, which is always set to not coded as it doesn't really exist */
   cpi->frag_coded = calloc(cpi->frag_total+1, sizeof(*cpi->frag_coded)); 
-  cpi->frag_mode = calloc(cpi->frag_total, sizeof(*cpi->frag_mode));
   cpi->frag_buffer_index = calloc(cpi->frag_total, sizeof(*cpi->frag_buffer_index));
   cpi->frag_mv = calloc(cpi->frag_total, sizeof(*cpi->frag_mv));
   cpi->frag_nonzero = calloc(cpi->frag_total, sizeof(*cpi->frag_nonzero));
   cpi->frag_dct = calloc(cpi->frag_total, sizeof(*cpi->frag_dct));
   cpi->frag_dc = calloc(cpi->frag_total, sizeof(*cpi->frag_dc));
 
-  /* possibly to be eliminated eventually when tokenize is rolled into transform */
-  cpi->coded_fi_list = calloc(cpi->frag_total, sizeof(*cpi->coded_fi_list));
-
   /* +1; the last entry is the 'invalid' mb, which contains only 'invalid' frags */
   cpi->macro = calloc(cpi->macro_total+1, sizeof(*cpi->macro));
 
@@ -189,6 +179,7 @@
       offset+=cpi->frag_n[plane];
     }
     
+    /* Y */
     for(row=0;row<cpi->super_v[0];row++){
       for(col=0;col<cpi->super_h[0];col++){
 	int superindex = row*cpi->super_h[0] + col;
@@ -205,6 +196,41 @@
 	}
       }
     }
+
+    /* U (assuming 4:2:0 for now) */
+    for(row=0;row<cpi->super_v[1];row++){
+      for(col=0;col<cpi->super_h[1];col++){
+	int superindex = row*cpi->super_h[1] + col;
+	for(mb=0;mb<16;mb++){
+	  /* translate to macroblock index */
+	  int mrow = row*4 + fhilberty[mb];
+	  int mcol = col*4 + fhilbertx[mb];
+	  if(mrow<cpi->macro_v && mcol<cpi->macro_h){
+	    int macroindex = mrow*cpi->macro_h + mcol;
+	    cpi->super[1][superindex].m[mb] = macroindex;
+	  }else
+	    cpi->super[1][superindex].m[mb] = cpi->macro_total;
+	}
+      }
+    }
+
+    /* V (assuming 4:2:0 for now) */
+    for(row=0;row<cpi->super_v[2];row++){
+      for(col=0;col<cpi->super_h[2];col++){
+	int superindex = row*cpi->super_h[2] + col;
+	for(mb=0;mb<16;mb++){
+	  /* translate to macroblock index */
+	  int mrow = row*4 + fhilberty[mb];
+	  int mcol = col*4 + fhilbertx[mb];
+	  if(mrow<cpi->macro_v && mcol<cpi->macro_h){
+	    int macroindex = mrow*cpi->macro_h + mcol;
+	    cpi->super[2][superindex].m[mb] = macroindex;
+	  }else
+	    cpi->super[2][superindex].m[mb] = cpi->macro_total;
+	}
+      }
+    }
+
   }
 
   /* fill in macroblock fragment pointers; raster (MV coding) order */



More information about the commits mailing list