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

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Wed Jul 9 01:23:30 PDT 2008


Author: xiphmont
Date: 2008-07-09 01:23:30 -0700 (Wed, 09 Jul 2008)
New Revision: 15105

Modified:
   branches/theora-thusnelda/lib/enc/codec_internal.h
   branches/theora-thusnelda/lib/enc/dct_encode.c
   branches/theora-thusnelda/lib/enc/mode.c
Log:
In-progress code cleanup in tokenization; make it a little easier to grok before diving into per-token opt which will render it nicely opaque again.



Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h	2008-07-07 20:40:38 UTC (rev 15104)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h	2008-07-09 08:23:30 UTC (rev 15105)
@@ -258,7 +258,6 @@
 
   int              eob_run[64];
   int              eob_pre[64];
-  int              eob_yrun[64];
   int              eob_ypre[64];
 
   oc_mode_scheme_chooser chooser;
@@ -319,6 +318,7 @@
 extern void dct_tokenize_init (CP_INSTANCE *cpi);
 extern void dct_tokenize_AC (CP_INSTANCE *cpi, int fi, ogg_int16_t *dct, int chroma);
 extern void dct_tokenize_finish (CP_INSTANCE *cpi);
+extern void dct_tokenize_ac_chroma (CP_INSTANCE *cpi);
 
 extern void WriteQTables(CP_INSTANCE *cpi,oggpack_buffer *opb);
 extern void InitQTables( CP_INSTANCE *cpi );

Modified: branches/theora-thusnelda/lib/enc/dct_encode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/dct_encode.c	2008-07-07 20:40:38 UTC (rev 15104)
+++ branches/theora-thusnelda/lib/enc/dct_encode.c	2008-07-09 08:23:30 UTC (rev 15105)
@@ -30,17 +30,53 @@
   64,64,64,64,64,64,64,64,
   64,64,64,64,64,64,64,64};
 
+typedef struct {
+  int coeff;
+  int count;
+  int chroma;
+  int pre;
+  int run;
+} token_checkpoint_t;
+
+void tokenize_rollback(CP_INSTANCE *cpi, token_checkpoint_t *stack,int n){
+  int i;
+  for(i=n-1;i>=0;i--){
+    int coeff = stack[i].coeff;
+    cpi->dct_token_count[coeff] = stack[i].count; 
+    cpi->eob_run[coeff] = stack[i].run;
+    cpi->eob_pre[coeff] = stack[i].pre;
+  }
+}
+
+void tokenize_commit(CP_INSTANCE *cpi, token_checkpoint_t *stack, int n){
+  int i;
+  for(i=0;i<n;i++){
+    int coeff = stack[i].coeff;
+    int pos = stack[i].count;
+    int token = cpi->dct_token[coeff][pos];
+    int chroma = stack[i].chroma;
+
+    if (coeff == 1){
+      /* AC == 1*/
+    int i,offset = acoffset[1];
+    for ( i = 0; i < AC_HUFF_CHOICES; i++)
+      cpi->ac1_bits[chroma][i] += cpi->HuffCodeLengthArray_VP3x[offset+i][token];
+    }else{
+      /* AC > 1*/
+      int i,offset = acoffset[coeff];
+      for ( i = 0; i < AC_HUFF_CHOICES; i++)
+	cpi->acN_bits[chroma][i] += cpi->HuffCodeLengthArray_VP3x[offset+i][token];
+    }
+  }
+}
+
 static void add_token(CP_INSTANCE *cpi, int chroma, int coeff, 
-		      unsigned char token, ogg_uint16_t eb, int fi){
-  
+		      unsigned char token, ogg_uint16_t eb){
   cpi->dct_token[coeff][cpi->dct_token_count[coeff]] = token;
   cpi->dct_token_eb[coeff][cpi->dct_token_count[coeff]] = eb;
-#ifdef COLLECT_METRICS
-  cpi->dct_token_frag[coeff][cpi->dct_token_count[coeff]] = fi;
-#endif
-  if(!chroma)cpi->dct_token_ycount[coeff]++;
   cpi->dct_token_count[coeff]++;
 
+  /* coeff 0 (DC) is always undconditionally/immediately committed */
   if(coeff == 0){
     /* DC */
     int i;
@@ -57,21 +93,20 @@
     for ( i = 0; i < AC_HUFF_CHOICES; i++)
       cpi->acN_bits[chroma][i] += cpi->HuffCodeLengthArray_VP3x[offset+i][token];
   }
+
 }
 
 static void prepend_token(CP_INSTANCE *cpi, int chroma, int coeff, 
-			  unsigned char token, ogg_uint16_t eb, int fi){
+			  unsigned char token, ogg_uint16_t eb){
 
   cpi->dct_token[coeff]--;
   cpi->dct_token_eb[coeff]--;
 #ifdef COLLECT_METRICS
   cpi->dct_token_frag[coeff]--;
-  cpi->dct_token_frag[coeff][0] = fi;
 #endif
   cpi->dct_token[coeff][0] = token;
   cpi->dct_token_eb[coeff][0] = eb;
   cpi->dct_token_count[coeff]++;
-  if(!chroma)cpi->dct_token_ycount[coeff]++;
 
   if(coeff == 0){
     /* DC */
@@ -120,99 +155,151 @@
   }
 }
 
-static void emit_eob_run(CP_INSTANCE *cpi, int chroma, int pos, int run){
+static void add_eob_run(CP_INSTANCE *cpi, int pos, int run){
   int token=0,eb=0;
-  tokenize_eob_run(run, &token, &eb);
-  add_token(cpi, chroma, pos, token, eb, 0);
+  int chroma = !(run&0x8000);
+  tokenize_eob_run(run&0x7fff, &token, &eb);
+  add_token(cpi, chroma, pos, token, eb);
 }
 
 static void prepend_eob_run(CP_INSTANCE *cpi, int chroma, int pos, int run){
   int token=0,eb=0;
   tokenize_eob_run(run, &token, &eb);
-  prepend_token(cpi, chroma, pos, token, eb, 0);
+  prepend_token(cpi, chroma, pos, token, eb);
 }
 
-static void tokenize_dctval (CP_INSTANCE *cpi, 
-			     int chroma, 
-			     int coeff,
-			     ogg_int16_t DataValue,
-			     int fi){
+static void emit_raw(CP_INSTANCE *cpi, 
+		     int chroma,
+		     int fi,
+		     int coeff,
+		     int token,
+		     int eb){
+  
+  /* Emit pending EOB run if any */
+  if(cpi->eob_run[coeff]){
+    add_eob_run(cpi,coeff,cpi->eob_run[coeff]);
+    cpi->eob_run[coeff]=0;
+  }
+#ifdef COLLECT_METRICS
+  cpi->dct_token_frag[coeff][cpi->dct_token_count[coeff]] = fi;
+#endif
+  add_token(cpi,chroma,coeff,token,eb);
 
-  int AbsDataVal = abs(DataValue);
-  int neg = (DataValue<0);
+}
 
-  if ( AbsDataVal == 1 ){
+static int emit_token(CP_INSTANCE *cpi, 
+		      int chroma,
+		      int fi,
+		      int coeff,
+		      int coeff2,
+		      int val){
+  
+  
+  ogg_uint32_t absval = abs(val);
+  int neg = (val<0);
+  int zero_run = coeff2-coeff;
+  int ret = 1;
+  int token;
+  int eb=0;
 
-    add_token(cpi, chroma, coeff, (neg ? MINUS_ONE_TOKEN : ONE_TOKEN), 0, fi);
+  /* Emit pending EOB run if any */
+  if(cpi->eob_run[coeff]){
+    add_eob_run(cpi,coeff,cpi->eob_run[coeff]);
+    cpi->eob_run[coeff]=0;
+  }
+#ifdef COLLECT_METRICS
+  cpi->dct_token_frag[coeff][cpi->dct_token_count[coeff]] = fi;
+#endif
 
-  } else if ( AbsDataVal == 2 ) {
-
-    add_token(cpi, chroma, coeff, (neg ? MINUS_TWO_TOKEN : TWO_TOKEN), 0, fi);
-
-  } else if ( AbsDataVal <= MAX_SINGLE_TOKEN_VALUE ) {
-
-    add_token(cpi, chroma, coeff, LOW_VAL_TOKENS + (AbsDataVal - DCT_VAL_CAT2_MIN), neg, fi);
-
-  } else if ( AbsDataVal <= 8 ) {
-
-    add_token(cpi, chroma, coeff, DCT_VAL_CATEGORY3, (AbsDataVal - DCT_VAL_CAT3_MIN) + (neg << 1), fi);
-
-  } else if ( AbsDataVal <= 12 ) {
-
-    add_token(cpi, chroma, coeff, DCT_VAL_CATEGORY4, (AbsDataVal - DCT_VAL_CAT4_MIN) + (neg << 2), fi);
-
-  } else if ( AbsDataVal <= 20 ) {
-
-    add_token(cpi, chroma, coeff, DCT_VAL_CATEGORY5, (AbsDataVal - DCT_VAL_CAT5_MIN) + (neg << 3), fi);
-
-  } else if ( AbsDataVal <= 36 ) {
-
-    add_token(cpi, chroma, coeff, DCT_VAL_CATEGORY6, (AbsDataVal - DCT_VAL_CAT6_MIN) + (neg << 4), fi);
-
-  } else if ( AbsDataVal <= 68 ) {
-
-    add_token(cpi, chroma, coeff, DCT_VAL_CATEGORY7, (AbsDataVal - DCT_VAL_CAT7_MIN) + (neg << 5), fi);
-
+  if (zero_run){
+    int adj = (coeff!=1); /* implement a minor restriction on
+			     stack 1 so that we know during DC
+			     fixups that extended a dctrun token
+			     from stack 1 will never overflow */
+    if ((absval==1) && (zero_run<17+adj)){
+      if ( zero_run <= 5 ) {
+	token = DCT_RUN_CATEGORY1+zero_run-1; 
+	eb    = neg;
+      }else if ( zero_run <= 9 ) {
+	token = DCT_RUN_CATEGORY1B; 
+	eb    = zero_run-6+(neg<<2);
+      }else{
+	token = DCT_RUN_CATEGORY1C;
+	eb    = zero_run-10+(neg<<3);
+      }
+    }else if((absval==2 || absval==3) && (zero_run < 3+adj)){
+      if ( zero_run == 1 ) {
+	token = DCT_RUN_CATEGORY2;
+	eb    = absval-2+(neg<<1);
+      }else{
+	token = DCT_RUN_CATEGORY2B;
+	eb    = (neg<<2)+((absval-2)<<1)+zero_run-2;
+      }
+    }else{
+      if ( zero_run <= 8 )
+	token = DCT_SHORT_ZRL_TOKEN;
+      else
+	token = DCT_ZRL_TOKEN;
+      eb = zero_run-1;
+      if(val) ret=0;
+    }
+  } else if ( absval == 1 ){
+    token = (neg ? MINUS_ONE_TOKEN : ONE_TOKEN);
+  } else if ( absval == 2 ) {
+    token = (neg ? MINUS_TWO_TOKEN : TWO_TOKEN);
+  } else if ( absval <= MAX_SINGLE_TOKEN_VALUE ) {
+    token = LOW_VAL_TOKENS + (absval - DCT_VAL_CAT2_MIN);
+    eb    = neg;
+  } else if ( absval <= 8 ) {
+    token = DCT_VAL_CATEGORY3;
+    eb    = (absval - DCT_VAL_CAT3_MIN) + (neg << 1);
+  } else if ( absval <= 12 ) {
+    token = DCT_VAL_CATEGORY4;
+    eb    = (absval - DCT_VAL_CAT4_MIN) + (neg << 2);
+  } else if ( absval <= 20 ) {
+    token = DCT_VAL_CATEGORY5;
+    eb    = (absval - DCT_VAL_CAT5_MIN) + (neg << 3);
+  } else if ( absval <= 36 ) {
+    token = DCT_VAL_CATEGORY6;
+    eb    = (absval - DCT_VAL_CAT6_MIN) + (neg << 4);
+  } else if ( absval <= 68 ) {
+    token = DCT_VAL_CATEGORY7;
+    eb    = (absval - DCT_VAL_CAT7_MIN) + (neg << 5);
   } else {
+    token = DCT_VAL_CATEGORY8;
+    eb    = (absval - DCT_VAL_CAT8_MIN) + (neg << 9);
+  } 
 
-    add_token(cpi, chroma, coeff, DCT_VAL_CATEGORY8, (AbsDataVal - DCT_VAL_CAT8_MIN) + (neg << 9), fi);
+  add_token(cpi,chroma,coeff,token,eb);
 
-  } 
+  return ret;
 }
 
-static void tokenize_dctrun (CP_INSTANCE *cpi, 
-			     int chroma, 
-			     int coeff,
-			     unsigned char RunLength,
-			     ogg_int16_t DataValue,
-			     int fi){
+static void increment_run(CP_INSTANCE *cpi, 
+			  int chroma,
+			  int fi,
+			  int pre,
+			  int coeff){
 
-  ogg_uint32_t AbsDataVal = abs( (ogg_int32_t)DataValue );
-  int neg = (DataValue<0);
+  if(pre && cpi->dct_token_count[coeff] == 0){
+    /* track pre-run */
+    cpi->eob_pre[coeff]++;
+  }else{
+    if((cpi->eob_run[coeff]&0x7fff) == 4095){
+      add_eob_run(cpi,coeff,cpi->eob_run[coeff]);
+      cpi->eob_run[coeff] = 0;
+    }
+    
+    cpi->eob_run[coeff]++;
+    cpi->eob_run[coeff]|= !chroma<<15;
+  }	  
+#ifdef COLLECT_METRICS
+  cpi->dct_eob_fi_stack[coeff][cpi->dct_eob_fi_count[coeff]++]=fi;
+#endif
+}
 
-  /* Values are tokenised as category value and a number of additional
-     bits  that define the category.  */
 
-  if ( AbsDataVal == 1 ) {
 
-    if ( RunLength <= 5 ) 
-      add_token(cpi,chroma,coeff, DCT_RUN_CATEGORY1 + RunLength - 1, neg, fi);
-    else if ( RunLength <= 9 ) 
-      add_token(cpi,chroma,coeff, DCT_RUN_CATEGORY1B, RunLength - 6 + (neg<<2), fi);
-    else 
-      add_token(cpi,chroma,coeff, DCT_RUN_CATEGORY1C, RunLength - 10 + (neg<<3), fi);
-
-  } else if ( AbsDataVal <= 3 ) {
-
-    if ( RunLength == 1 ) 
-      add_token(cpi,chroma,coeff, DCT_RUN_CATEGORY2, AbsDataVal - 2 + (neg<<1), fi);
-    else
-      add_token(cpi,chroma,coeff, DCT_RUN_CATEGORY2B, 
-		(neg<<2) + ((AbsDataVal-2)<<1) + RunLength - 2, fi);
-
-  }
-}
-
 static int decode_eob_token(int token, int eb){
   switch(token){
   case DCT_EOB_TOKEN:
@@ -234,50 +321,48 @@
   }
 }
 
-static int decode_zrl_token(int token, int eb){
+static int decode_token(int token, int eb, int *val){
   switch(token){
   case DCT_SHORT_ZRL_TOKEN:
   case DCT_ZRL_TOKEN:
+    *val=0;
     return eb+1;
-  default:
-    return 0;
-  }
-}
-
-static int decode_dct_token(int token, int eb){
-  switch(token){
   case ONE_TOKEN:
-    return 1;
+    *val = 1;
+    return 0;
   case MINUS_ONE_TOKEN:
-    return -1;
+    *val = -1;
+    return 0;
   case TWO_TOKEN:
-    return 2;
+    *val = 2;
+    return 0;
   case MINUS_TWO_TOKEN:
-    return -2;
+    *val = -2;
+    return 0;
   case LOW_VAL_TOKENS:
   case LOW_VAL_TOKENS+1:
   case LOW_VAL_TOKENS+2:
   case LOW_VAL_TOKENS+3:
-    return (eb ? -(DCT_VAL_CAT2_MIN+token-LOW_VAL_TOKENS) : DCT_VAL_CAT2_MIN+token-LOW_VAL_TOKENS);
+    *val = (eb ? -(DCT_VAL_CAT2_MIN+token-LOW_VAL_TOKENS) : DCT_VAL_CAT2_MIN+token-LOW_VAL_TOKENS);
+    return 0;
   case DCT_VAL_CATEGORY3:
-    return ((eb & 0x2) ? -(DCT_VAL_CAT3_MIN+(eb&0x1)) : DCT_VAL_CAT3_MIN+(eb&0x1));
+    *val = ((eb & 0x2) ? -(DCT_VAL_CAT3_MIN+(eb&0x1)) : DCT_VAL_CAT3_MIN+(eb&0x1));
+    return 0;
   case DCT_VAL_CATEGORY4:
-    return ((eb & 0x4) ? -(DCT_VAL_CAT4_MIN+(eb&0x3)) : DCT_VAL_CAT4_MIN+(eb&0x3));
+    *val = ((eb & 0x4) ? -(DCT_VAL_CAT4_MIN+(eb&0x3)) : DCT_VAL_CAT4_MIN+(eb&0x3));
+    return 0;
   case DCT_VAL_CATEGORY5:
-    return ((eb & 0x8) ? -(DCT_VAL_CAT5_MIN+(eb&0x7)) : DCT_VAL_CAT5_MIN+(eb&0x7));
+    *val = ((eb & 0x8) ? -(DCT_VAL_CAT5_MIN+(eb&0x7)) : DCT_VAL_CAT5_MIN+(eb&0x7));
+    return 0;
   case DCT_VAL_CATEGORY6:
-    return ((eb & 0x10) ? -(DCT_VAL_CAT6_MIN+(eb&0xf)) : DCT_VAL_CAT6_MIN+(eb&0xf));
+    *val = ((eb & 0x10) ? -(DCT_VAL_CAT6_MIN+(eb&0xf)) : DCT_VAL_CAT6_MIN+(eb&0xf));
+    return 0;
   case DCT_VAL_CATEGORY7:
-    return ((eb & 0x20) ? -(DCT_VAL_CAT7_MIN+(eb&0x1f)) : DCT_VAL_CAT7_MIN+(eb&0x1f));
+    *val = ((eb & 0x20) ? -(DCT_VAL_CAT7_MIN+(eb&0x1f)) : DCT_VAL_CAT7_MIN+(eb&0x1f));
+    return 0;
   case DCT_VAL_CATEGORY8:
-    return ((eb & 0x200) ? -(DCT_VAL_CAT8_MIN+(eb&0x1ff)) : DCT_VAL_CAT8_MIN+(eb&0x1ff));
-  default:
+    *val = ((eb & 0x200) ? -(DCT_VAL_CAT8_MIN+(eb&0x1ff)) : DCT_VAL_CAT8_MIN+(eb&0x1ff));
     return 0;
-  }
-}
-
-static int decode_dctrun_token(int token, int eb, int *val){
-  switch(token){
   case DCT_RUN_CATEGORY1:
   case DCT_RUN_CATEGORY1+1:
   case DCT_RUN_CATEGORY1+2:
@@ -310,10 +395,8 @@
 
 void dct_tokenize_AC(CP_INSTANCE *cpi, int fi, ogg_int16_t *dct, int chroma){
   int coeff = 1; /* skip DC for now */
-  
   while(coeff < BLOCK_SIZE){
     ogg_int16_t val = dct[coeff];
-    int zero_run;
     int i = coeff;
     
     while( !val && (++i < BLOCK_SIZE) )
@@ -323,54 +406,11 @@
       
       /* if there are no other tokens in this group yet, set up to be
 	 prepended later.  */
-      if(cpi->dct_token_count[coeff] == 0 && coeff>1){
-	/* track pre-run */
-	cpi->eob_pre[coeff]++;
-	if(!chroma)cpi->eob_ypre[coeff]++;
-      }else{
-	if(cpi->eob_run[coeff] == 4095){
-	    emit_eob_run(cpi,(cpi->eob_yrun[coeff]==0),coeff,4095);
-	    cpi->eob_run[coeff] = 0;
-	    cpi->eob_yrun[coeff] = 0;
-	}
-	
-	cpi->eob_run[coeff]++;
-	if(!chroma)cpi->eob_yrun[coeff]++;
-      }	  
-#ifdef COLLECT_METRICS
-      cpi->dct_eob_fi_stack[coeff][cpi->dct_eob_fi_count[coeff]++]=fi;
-#endif
+      increment_run(cpi,chroma,fi,coeff>1,coeff);
       coeff = BLOCK_SIZE;
     }else{
       
-      if(cpi->eob_run[coeff]){
-	emit_eob_run(cpi,(cpi->eob_yrun[coeff]==0),coeff,cpi->eob_run[coeff]);
-	cpi->eob_run[coeff]=0;
-	cpi->eob_yrun[coeff]=0;
-      }
-      
-      zero_run = i-coeff;
-      if (zero_run){
-	ogg_uint32_t absval = abs(val);
-	int adj = (coeff>1); /* implement a minor restriction on
-				stack 1 so that we know during DC
-				fixups that extended a dctrun token
-				from stack 1 will never overflow */
-	if ( ((absval == 1) && (zero_run < 17+adj)) ||
-	     ((absval <= 3) && (zero_run < 3+adj))){
-	  tokenize_dctrun( cpi, chroma, coeff, zero_run, val, fi);
-	  coeff = i+1;
-	}else{
-	  if ( zero_run <= 8 )
-	    add_token(cpi, chroma, coeff, DCT_SHORT_ZRL_TOKEN, zero_run - 1, fi);
-	  else
-	    add_token(cpi, chroma, coeff, DCT_ZRL_TOKEN, zero_run - 1, fi);
-	  coeff = i;
-	}
-      }else{
-	tokenize_dctval(cpi, chroma, coeff, val, fi);
-	coeff = i+1;
-      }
+      coeff = i+emit_token(cpi, chroma, fi, coeff, i, val);
     }
   }
 }
@@ -397,48 +437,21 @@
     if(val){
       /* nonzero DC val, no coeff 1 stack 'fixup'. */
 
-      /* Emit pending DC EOB run if any */
-      if(cpi->eob_run[0]){
-	emit_eob_run(cpi,(cpi->eob_yrun[0]==0),0,cpi->eob_run[0]);
-	cpi->eob_run[0]=0;
-	cpi->eob_yrun[0]=0;
-      }
-      /* Emit DC value token */
-      tokenize_dctval(cpi, chroma, 0, val, fi);
+      emit_token(cpi,chroma,fi,0,0,val);
 
       /* there was a nonzero DC value, so there's no alteration to the
 	 track1 stack for this fragment; track/regenerate stack 1
 	 state unchanged */
       if(*run1){
 	/* in the midst of an EOB run in stack 1 */
-	if(cpi->dct_token_count[1]==0){
-	  /* track pre-run */
-	  cpi->eob_pre[1]++;
-	  if(!chroma)cpi->eob_ypre[1]++;
-	}else{
-	  if(cpi->eob_run[1] == 4095){
-	    emit_eob_run(cpi,(cpi->eob_yrun[1]==0),1,4095);
-	    cpi->eob_run[1] = 0;
-	    cpi->eob_yrun[1] = 0;
-	  }
-	  cpi->eob_run[1]++;
-	  if(!chroma)cpi->eob_yrun[1]++;
-	}	  	  
+	increment_run(cpi,chroma,fi,1,1);
 	(*run1)--;
-#ifdef COLLECT_METRICS
-	cpi->dct_eob_fi_stack[1][cpi->dct_eob_fi_count[1]++]=fi;
-#endif
+
       }else{
+
 	/* non-EOB run token to emit for stack 1 */
+	emit_raw(cpi,chroma,fi,1,token1,eb1);
 
-	/* emit stack 1 eobrun if any */
-	if(cpi->eob_run[1]){
-	  emit_eob_run(cpi,(cpi->eob_yrun[1]==0),1,cpi->eob_run[1]);
-	  cpi->eob_run[1]=cpi->eob_yrun[1]=0;
-	}
-	
-	/* emit stack 1 token */
-	add_token(cpi, chroma, 1, token1, eb1, fi);
       }
 
     }else{
@@ -448,23 +461,15 @@
 	 requires a stack 1 fixup. */
       
       if(*run1){
-	/* current stack 1 token an EOB run; conceptually move this fragment's EOBness to stack 0 */
 
-	if(cpi->eob_run[0] == 4095){
-	  emit_eob_run(cpi,(cpi->eob_yrun[0]==0),0,4095);
-	  cpi->eob_run[0] = 0;
-	  cpi->eob_yrun[0] = 0;
-	}
-	cpi->eob_run[0]++;
-	if(!chroma)cpi->eob_yrun[0]++;	      
-#ifdef COLLECT_METRICS
-	cpi->dct_eob_fi_stack[0][cpi->dct_eob_fi_count[0]++]=fi;
-#endif
+	/* current stack 1 token an EOB run; conceptually move this fragment's EOBness to stack 0 */
+	increment_run(cpi,chroma,fi,0,0);
 	      
 	/* decrement current EOB run for coeff 1 without adding to coded run */
 	(*run1)--;
 
       }else{
+	int run,val=0;
 
 	/* stack 1 token is one of: zerorun, dctrun or dctval */
 	/* A zero-run token is expanded and moved to token stack 0 (stack 1 entry dropped) */
@@ -476,53 +481,10 @@
 	   so we know there's no chance of overrunning the
 	   representable range */
 
-	/* Emit DC EOB run if any pending */
-	if(cpi->eob_run[0]){
-	  emit_eob_run(cpi,(cpi->eob_yrun[0]==0),0,cpi->eob_run[0]);
-	  cpi->eob_run[0]=0;
-	  cpi->eob_yrun[0]=0;
-	}
-	  
-	if(token1 <= DCT_ZRL_TOKEN){
-	  /* zero-run.  Extend and move it */
-	  int run = decode_zrl_token(token1,eb1);
-	  
-	  /* Emit zerorun token */
-	  if ( run < 8 )
-	    add_token(cpi, chroma, 0, DCT_SHORT_ZRL_TOKEN, run, fi);
-	  else
-	    add_token(cpi, chroma, 0, DCT_ZRL_TOKEN, run, fi);
+	run = decode_token(token1,eb1,&val)+1;
 
-	  /* do not recode stack 1 token */
-
-	} else if(token1 <= DCT_VAL_CATEGORY8){
-
-	  /* DCT value token; will it fit into a dctrun? */
-	  int val = decode_dct_token(token1,eb1);
-
-	  if(abs(val)<=3){
-	    /* emit a dctrun in stack 0, do not recode stack 1 token */
-	    tokenize_dctrun( cpi, chroma, 0, 1, val, fi);
-	  }else{
-	    /* Code stack 0 short zero run */
-	    add_token(cpi, chroma, 0, DCT_SHORT_ZRL_TOKEN, 0, fi);
-	    
-	    /* emit stack 1 eobrun if any */
-	    if(cpi->eob_run[1]){
-	      emit_eob_run(cpi,(cpi->eob_yrun[1]==0),1,cpi->eob_run[1]);
-	      cpi->eob_run[1]=cpi->eob_yrun[1]=0;
-	    }
-	
-	    /* emit stack 1 token */
-	    add_token(cpi, chroma, 1, token1, eb1, fi);
-
-	  }
-	} else {
-	  /* dctrun token; extend the run by one and move it to stack 0 */
-	  int val;
-	  int run = decode_dctrun_token(token1,eb1,&val)+1;
-	  tokenize_dctrun( cpi, chroma, 0, run, val, fi);
-	  /* do not recode stack 1 token */
+	if(!emit_token(cpi,chroma,fi,0,run,val)){
+	  emit_raw(cpi,chroma,fi,1,token1,eb1);
 	}
       }
     }
@@ -530,7 +492,6 @@
     /* update token counter if not in a run */
     if (!*run1) (*idx1)++;
     
-
   }
 }
 
@@ -539,13 +500,10 @@
 
   memset(cpi->eob_run, 0, sizeof(cpi->eob_run));
   memset(cpi->eob_pre, 0, sizeof(cpi->eob_pre));
-  memset(cpi->eob_yrun, 0, sizeof(cpi->eob_yrun));
-  memset(cpi->eob_ypre, 0, sizeof(cpi->eob_ypre));
   memset(cpi->dc_bits, 0, sizeof(cpi->dc_bits));
   memset(cpi->ac1_bits, 0, sizeof(cpi->ac1_bits));
   memset(cpi->acN_bits, 0, sizeof(cpi->acN_bits));
   memset(cpi->dct_token_count, 0, sizeof(cpi->dct_token_count));
-  memset(cpi->dct_token_ycount, 0, sizeof(cpi->dct_token_ycount));
 #ifdef COLLECT_METRICS
   memset(cpi->dct_eob_fi_count, 0, sizeof(cpi->dct_eob_fi_count));
 #endif
@@ -561,6 +519,16 @@
   }
 }
 
+void dct_tokenize_ac_chroma (CP_INSTANCE *cpi){
+  int i;
+  for(i=1;i<64;i++){
+    cpi->dct_token_ycount[i]=cpi->dct_token_count[i];
+    if(cpi->eob_run[i])
+      cpi->dct_token_ycount[i]++; /* there will be another y plane token after welding */
+    cpi->eob_ypre[i]=cpi->eob_pre[i];
+  }
+}
+
 /* post-facto DC tokenization (has to be completed after DC predict)
    coeff 1 fixups and eobrun welding */
 void dct_tokenize_finish (CP_INSTANCE *cpi){
@@ -573,11 +541,10 @@
      reparse the stack in the DC code loop.  The current state will be
      recreated by the end of DC encode */
 
-  if(cpi->eob_run[1]) emit_eob_run(cpi,(cpi->eob_yrun[1]==0),1,cpi->eob_run[1]);
+  if(cpi->eob_run[1]) add_eob_run(cpi,1,cpi->eob_run[1]);
   memset(cpi->ac1_bits, 0, sizeof(cpi->ac1_bits));
   cpi->dct_token_count[1]=0;
-  cpi->dct_token_ycount[1]=0;
-  cpi->eob_ypre[1]=cpi->eob_pre[1]=cpi->eob_yrun[1]=cpi->eob_run[1]=0;
+  cpi->eob_pre[1]=cpi->eob_run[1]=0;
 #ifdef COLLECT_METRICS
   /* reset and reuse as a counter */
   cpi->dct_eob_fi_count[1]=0;
@@ -592,6 +559,13 @@
     }
   }
 
+  for(i=0;i<2;i++){
+    cpi->dct_token_ycount[i]=cpi->dct_token_count[i];
+    if(cpi->eob_run[i])
+      cpi->dct_token_ycount[i]++; /* there will be another y plane token after welding */
+    cpi->eob_ypre[i]=cpi->eob_pre[i];
+  }
+
   for (; sbi < cpi->super_total; sbi++ ){
     superblock_t *sb = &cpi->super[0][sbi];
     int bi;
@@ -607,7 +581,6 @@
   {
     int coeff = 0;
     int run = 0;
-    int chroma = 0; /* plane of next run token to emit */
     
     for(i=0;i<BLOCK_SIZE;i++){
       if(cpi->eob_pre[i]){
@@ -615,25 +588,22 @@
 	
 	/* special case the ongoing run + eob is at or over the max run size;
 	   we know the ongoing run is < 4095 or it would have been flushed already. */
-	if(run && run + cpi->eob_pre[i] >= 4095){ /* 1 */
-	  emit_eob_run(cpi,chroma,coeff,4095);
-	  cpi->eob_pre[i] -= 4095-run; 
-	  cpi->eob_ypre[i] -= 4095-run; 
+	if(run && (run&0x7fff) + cpi->eob_pre[i] >= 4095){ /* 1 */
+	  add_eob_run(cpi,coeff,4095 | (run&0x8000));
+	  cpi->eob_pre[i] -= 4095-(run&0x7fff); 
+	  cpi->eob_ypre[i] -= 4095-(run&0x7fff); 
 	  run = 0;
 	  coeff = i;
-	  chroma = (cpi->eob_ypre[i]<=0);
-	  /* if(cpi->eob_ypre[i]<0)cpi->eob_ypre[i]=0; redundant */
 	}
 	
 	if(run){
 	  if(cpi->dct_token_count[i]){ /* 2 */
 	    /* group is not only an EOB run; emit the run token */
-	    emit_eob_run(cpi,chroma,coeff,run + cpi->eob_pre[i]);
+	    add_eob_run(cpi,coeff,run + cpi->eob_pre[i]);
 	    cpi->eob_ypre[i] = 0;
 	    cpi->eob_pre[i] = 0;
 	    run = cpi->eob_run[i];
 	    coeff = i;
-	    chroma = (cpi->eob_yrun[i]<=0);
 	  }else{ /* 3 */
 	    /* group consists entirely of EOB run.  Add, iterate */
 	    run += cpi->eob_pre[i];
@@ -647,45 +617,48 @@
 	    while(cpi->eob_pre[i] >= 4095){ /* 4 */
 	      int lchroma = (cpi->eob_pre[i]-4095 >= cpi->eob_ypre[i]);
 	      prepend_eob_run(cpi,lchroma,i,4095);
+	      if(!lchroma)cpi->dct_token_ycount[i]++;
 	      cpi->eob_pre[i] -= 4095;
 	    }
 	    if(cpi->eob_pre[i]){ /* 5 */
 	      int lchroma = (cpi->eob_ypre[i]<=0); /* possible when case 1 triggered */
 	      prepend_eob_run(cpi, lchroma, i, cpi->eob_pre[i]);
+	      if(!lchroma)cpi->dct_token_ycount[i]++;
 	      cpi->eob_pre[i] = 0;
 	      cpi->eob_ypre[i] = 0;
 	    }
 	    run = cpi->eob_run[i];
 	    coeff = i;
-	    chroma = (cpi->eob_yrun[i]<=0);
 	  }else{
 	    /* group consists entirely of EOB run.  Add, flush overs, iterate */
+	    int lchroma = (cpi->eob_ypre[i]<=0);
 	    while(cpi->eob_pre[i] >= 4095){
-	      int lchroma = (cpi->eob_ypre[i]<=0);
-	      emit_eob_run(cpi,lchroma,i,4095);
+	      add_eob_run(cpi,i,4095|(!lchroma<<15));
+	      if(!lchroma)cpi->dct_token_ycount[i]++;
 	      cpi->eob_pre[i] -= 4095;
 	      cpi->eob_ypre[i] -= 4095;
+	      lchroma = (cpi->eob_ypre[i]<=0);
 	    }
-	    run = cpi->eob_pre[i];
+	    run = cpi->eob_pre[i] | (!lchroma<<15);
 	    coeff = i;
-	    chroma = (cpi->eob_ypre[i]<=0);
+	    /* source is pre-run, so the eventual eob_emit_run also needs to increment ycount if coded into Y plane */
+	    if(!lchroma)cpi->dct_token_ycount[i]++;
 	  }
 	}
       }else{
 	/* no eob run to begin group */
 	if(i==0 || cpi->dct_token_count[i]){
 	  if(run)
-	    emit_eob_run(cpi,chroma,coeff,run);
+	    add_eob_run(cpi,coeff,run);
 	  
 	  run = cpi->eob_run[i];
 	  coeff = i;
-	  chroma = (cpi->eob_yrun[i]<=0);
 	}
       }
     }
     
     if(run)
-      emit_eob_run(cpi,chroma,coeff,run);
+      add_eob_run(cpi,coeff,run);
     
   }
 }

Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c	2008-07-07 20:40:38 UTC (rev 15104)
+++ branches/theora-thusnelda/lib/enc/mode.c	2008-07-09 08:23:30 UTC (rev 15105)
@@ -1074,6 +1074,8 @@
     fr_finishsb(cpi,&fr);
   }
 
+  dct_tokenize_ac_chroma(cpi);
+
   /* code chroma U */
   sb = cpi->super[1];
   sb_end = sb + cpi->super_n[1];



More information about the commits mailing list