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

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Sat Apr 19 06:38:12 PDT 2008


Author: xiphmont
Date: 2008-04-19 06:38:11 -0700 (Sat, 19 Apr 2008)
New Revision: 14779

Modified:
   branches/theora-thusnelda/lib/enc/codec_internal.h
   branches/theora-thusnelda/lib/enc/encoder_quant.c
   branches/theora-thusnelda/lib/enc/mode.c
Log:
Get a bit of the rho-domain code into SVN; does not yet do anything.  
Beginning as a test of CPU performance impact.



Modified: branches/theora-thusnelda/lib/enc/codec_internal.h
===================================================================
--- branches/theora-thusnelda/lib/enc/codec_internal.h	2008-04-19 02:11:37 UTC (rev 14778)
+++ branches/theora-thusnelda/lib/enc/codec_internal.h	2008-04-19 13:38:11 UTC (rev 14779)
@@ -152,10 +152,10 @@
   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];
+typedef ogg_int16_t    quant_table[64]; 
 typedef quant_table    quant_tables[64];
 
-typedef ogg_int32_t    iquant_table[64];
+typedef ogg_int32_t    iquant_table[64];  
 typedef iquant_table   iquant_tables[64];
 
 typedef struct {
@@ -255,6 +255,9 @@
 
   /********************************************************************/
   /* Fragment SAD->bitrate estimation tracking metrics */
+  unsigned char    rho_lookup[2][3][64][OC_QUANT_MAX>>2];
+  ogg_uint32_t     rho_count[65]; 
+
 #ifdef COLLECT_METRICS
   int             *frag_mbi;
   int             *frag_sad;

Modified: branches/theora-thusnelda/lib/enc/encoder_quant.c
===================================================================
--- branches/theora-thusnelda/lib/enc/encoder_quant.c	2008-04-19 02:11:37 UTC (rev 14778)
+++ branches/theora-thusnelda/lib/enc/encoder_quant.c	2008-04-19 13:38:11 UTC (rev 14779)
@@ -164,14 +164,14 @@
 	  q=((ogg_uint32_t)qinfo->dc_scale[qi]*base[0]/100)<<2;
 	  q=OC_CLAMPI(OC_DC_QUANT_MIN[qti],q,OC_QUANT_MAX);
 	  cpi->quant_tables[qti][pli][qi][0]=(ogg_uint16_t)q;
-	  cpi->iquant_tables[qti][pli][qi][0]=(ogg_int32_t)(0.5 + (double)SHIFT16/q);
+	  cpi->iquant_tables[qti][pli][qi][0]=(ogg_int32_t)(((1<<31))/q+1);
 
 	  /*Now scale AC coefficients from the proper table.*/
 	  for(ci=1;ci<64;ci++){
 	    q=((ogg_uint32_t)qinfo->ac_scale[qi]*base[ci]/100)<<2;
 	    q=OC_CLAMPI(OC_AC_QUANT_MIN[qti],q,OC_QUANT_MAX);
 	    cpi->quant_tables[qti][pli][qi][zigzag_index[ci]]=(ogg_uint16_t)q;
-	    cpi->iquant_tables[qti][pli][qi][ci]=(ogg_int32_t)(0.5 + (double)SHIFT16/q);
+	    cpi->iquant_tables[qti][pli][qi][ci]=(ogg_int32_t)(((1<<31))/q+1);
 	  }
 	  
 	  if(++qi>=qi_end)break;
@@ -201,9 +201,16 @@
   
   /* Note that we add half divisor to effect rounding on positive number */
   for( i = 0; i < 64; i++) {
-    int val = ( (q[i] * in[i] + (1<<15)) >> 16 );
-    if(val>511)val=511;
-    if(val<-511)val=-511;
-    out[zigzag_index[i]] = val;
+    // the extra precision version to perfectly match dequant and thus rho metrics.  It's about a 2% speed penalty. 
+    int val = (((q[i]>>15)*in[i]) + (1<<15) + (((q[i]&0x7fff)*in[i])>>15)) >>16;
+    if(val==0){
+	out[zigzag_index[i]] = 0;
+    }else if(val>511){
+      out[zigzag_index[i]] = 511;
+    }else if (val<-511){
+      out[zigzag_index[i]] = -511;
+    }else{
+      out[zigzag_index[i]] = val;
+    }
   }
 }

Modified: branches/theora-thusnelda/lib/enc/mode.c
===================================================================
--- branches/theora-thusnelda/lib/enc/mode.c	2008-04-19 02:11:37 UTC (rev 14778)
+++ branches/theora-thusnelda/lib/enc/mode.c	2008-04-19 13:38:11 UTC (rev 14779)
@@ -487,6 +487,186 @@
     sad[7][2][0] = BInterSAD(cpi,fi,2,0,ch);
 }
 
+#include "quant_lookup.h"
+static int find_nonzero_transition(quant_tables *q, int pos, ogg_int16_t val){
+  int i;
+  
+  val = (abs(val)<<1);
+
+  if( val < (*q)[32][pos]){
+    if( val < (*q)[48][pos]){
+      if( val < (*q)[56][pos]){
+	if( val < (*q)[60][pos]){
+	  if( val < (*q)[62][pos]){
+	    if( val < (*q)[63][pos])return 64;
+	    return 63;
+	  }else{
+	    if( val < (*q)[61][pos])return 62;
+	    return 61;
+	  }
+	}else{
+	  if( val < (*q)[58][pos]){
+	    if( val < (*q)[59][pos])return 60;
+	    return 59;
+	  }else{
+	    if( val < (*q)[57][pos])return 58;
+	    return 57;
+	  }
+	}
+      }else{
+	if( val < (*q)[52][pos]){
+	  if( val < (*q)[54][pos]){
+	    if( val < (*q)[55][pos])return 56;
+	    return 55;
+	  }else{
+	    if( val < (*q)[53][pos])return 54;
+	    return 53;
+	  }
+	}else{
+	  if( val < (*q)[50][pos]){
+	    if( val < (*q)[51][pos])return 52;
+	    return 51;
+	  }else{
+	    if( val < (*q)[49][pos])return 50;
+	    return 49;
+	  }
+	}
+      }
+    }else{
+      if( val < (*q)[40][pos]){
+	if( val < (*q)[44][pos]){
+	  if( val < (*q)[46][pos]){
+	    if( val < (*q)[47][pos])return 48;
+	    return 47;
+	  }else{
+	    if( val < (*q)[45][pos])return 46;
+	    return 45;
+	  }
+	}else{
+	  if( val < (*q)[42][pos]){
+	    if( val < (*q)[43][pos])return 44;
+	    return 43;
+	  }else{
+	    if( val < (*q)[41][pos])return 42;
+	    return 41;
+	  }
+	}
+      }else{
+	if( val < (*q)[36][pos]){
+	  if( val < (*q)[38][pos]){
+	    if( val < (*q)[39][pos])return 40;
+	    return 39;
+	  }else{
+	    if( val < (*q)[37][pos])return 38;
+	    return 37;
+	  }
+	}else{
+	  if( val < (*q)[34][pos]){
+	    if( val < (*q)[35][pos])return 36;
+	    return 35;
+	  }else{
+	    if( val < (*q)[33][pos])return 34;
+	    return 33;
+	  }
+	}
+      }
+    }
+  }else{
+    if( val < (*q)[16][pos]){
+      if( val < (*q)[24][pos]){
+	if( val < (*q)[28][pos]){
+	  if( val < (*q)[30][pos]){
+	    if( val < (*q)[31][pos])return 32;
+	    return 31;
+	  }else{
+	    if( val < (*q)[29][pos])return 30;
+	    return 29;
+	  }
+	}else{
+	  if( val < (*q)[26][pos]){
+	    if( val < (*q)[27][pos])return 28;
+	    return 27;
+	  }else{
+	    if( val < (*q)[25][pos])return 26;
+	    return 25;
+	  }
+	}
+      }else{
+	if( val < (*q)[20][pos]){
+	  if( val < (*q)[22][pos]){
+	    if( val < (*q)[23][pos])return 24;
+	    return 23;
+	  }else{
+	    if( val < (*q)[21][pos])return 22;
+	    return 21;
+	  }
+	}else{
+	  if( val < (*q)[18][pos]){
+	    if( val < (*q)[19][pos])return 20;
+	    return 19;
+	  }else{
+	    if( val < (*q)[17][pos])return 18;
+	    return 17;
+	  }
+	}
+      }
+    }else{
+      if( val < (*q)[8][pos]){
+	if( val < (*q)[12][pos]){
+	  if( val < (*q)[14][pos]){
+	    if( val < (*q)[15][pos])return 16;
+	    return 15;
+	  }else{
+	    if( val < (*q)[13][pos])return 14;
+	    return 13;
+	  }
+	}else{
+	  if( val < (*q)[10][pos]){
+	    if( val < (*q)[11][pos])return 12;
+	    return 11;
+	  }else{
+	    if( val < (*q)[9][pos])return 10;
+	    return 9;
+	  }
+	}
+      }else{
+	if( val < (*q)[4][pos]){
+	  if( val < (*q)[6][pos]){
+	    if( val < (*q)[7][pos])return 8;
+	    return 7;
+	  }else{
+	    if( val < (*q)[5][pos])return 6;
+	    return 5;
+	  }
+	}else{
+	  if( val < (*q)[2][pos]){
+	    if( val < (*q)[3][pos])return 4;
+	    return 3;
+	  }else{
+	    if( val < (*q)[1][pos])return 2;
+	    if( val < (*q)[0][pos])return 1;
+	  }
+	}
+      }
+    }
+  }
+
+  return 0;
+}
+
+/* rho computation and quant/dequant should be in bed together.  They're not... yet */
+static void collect_rho(CP_INSTANCE *cpi, int mode, int plane, ogg_int16_t *buffer){
+  int pos[64];
+  int i;
+  int interp = (mode != CODE_INTRA);
+  quant_tables *q = &cpi->quant_tables[interp][plane];
+
+  for(i=0;i<64;i++){
+    int ii = zigzag_index[i];
+    pos[ii] = find_nonzero_transition(q,ii,buffer[i]);
+  }
+}
+
 static void TQB (CP_INSTANCE *cpi, int mode, int fi, ogg_int32_t *iq, ogg_int16_t *q, mv_t mv, int plane){
   if ( cpi->frag_coded[fi] ) {
     ogg_int16_t buffer[64];
@@ -544,7 +724,8 @@
     dsp_fdct_short(cpi->dsp, data, buffer);
     
     /* collect rho metrics */
-    
+    collect_rho(cpi, mode, plane, buffer);
+
     /* quantize */
     quantize (cpi, iq, buffer, data);
     cpi->frag_dc[fi] = cpi->frag_dct[fi].data[0];



More information about the commits mailing list