Adding support for multiple block sizes in intra_pred and intra_stats
authorNathan E. Egge <negge@dgql.org>
Wed, 16 Jan 2013 18:02:46 +0000 (13:02 -0500)
committerNathan E. Egge <negge@dgql.org>
Wed, 16 Jan 2013 18:02:46 +0000 (13:02 -0500)
src/intra.c
src/intra.h
tools/intra_pred.c
tools/stats_tools.c
tools/stats_tools.h
tools/trans.c

index 3da366a..a63c276 100644 (file)
@@ -27,6 +27,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
 #include "filter.h"
 #include "intra.h"
 
+const od_intra_mult_func OD_INTRA_MULT[OD_NBSIZES]={
+  od_intra_pred4x4_mult,
+  NULL,
+  NULL
+};
+
 void od_intra_pred4x4_mult(const od_coeff *_c,int _stride,int _mode,double *_p){
   int i;
   int j;
index 051165e..3a9a870 100644 (file)
@@ -32,6 +32,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
 
 # define OD_INTRA_NCONTEXTS (8)
 
+typedef void (*od_intra_mult_func)(const od_coeff *_c,int _stride,int _mode,
+ double *_p);
+
+extern const od_intra_mult_func OD_INTRA_MULT[OD_NBSIZES];
+
 extern const double OD_INTRA_PRED_WEIGHTS_4x4[OD_INTRA_NMODES][4][4][2*4][2*4];
 extern const unsigned char OD_INTRA_PRED_PROB_4x4[3][OD_INTRA_NMODES][OD_INTRA_NCONTEXTS];
 
index 7618223..cc70fff 100644 (file)
@@ -41,12 +41,9 @@ static void pred_data_add_block(pred_data *_this,const od_coeff *_block,
   int    i;
   _this->w+=_w;
   for(by=0;by<=1;by++){
-    for(bx=0;bx<=2;bx++){
+    for(bx=0;bx<=2-by;bx++){
       int             bo;
       const od_coeff *block;
-      if(by==1&&bx==2){
-        continue;
-      }
       bo=B_SZ*B_SZ*(3*by+bx);
       block=&_block[_stride*B_SZ*(by-1)+B_SZ*(bx-1)];
       for(j=0;j<B_SZ;j++){
@@ -70,13 +67,13 @@ static void pred_data_update(pred_data *_this,int _mode){
   int     i;
   int     j;
   int     k;
-  double  scale[5*B_SZ*B_SZ];
-  double  xtx[2*4*B_SZ*B_SZ][4*B_SZ*B_SZ];
-  double  xty[4*B_SZ*B_SZ][B_SZ*B_SZ];
-  double *xtxp[2*4*B_SZ*B_SZ];
-  double  s[4*B_SZ*B_SZ];
-  double  beta_0[B_SZ*B_SZ];
-  double  beta_1[4*B_SZ*B_SZ][B_SZ*B_SZ];
+  static double  scale[5*B_SZ*B_SZ];
+  static double  xtx[2*4*B_SZ*B_SZ][4*B_SZ*B_SZ];
+  static double  xty[4*B_SZ*B_SZ][B_SZ*B_SZ];
+  static double *xtxp[2*4*B_SZ*B_SZ];
+  static double  s[4*B_SZ*B_SZ];
+  static double  beta_0[B_SZ*B_SZ];
+  static double  beta_1[4*B_SZ*B_SZ][B_SZ*B_SZ];
 
   /* compute the scale factors */
   for(i=0;i<5*B_SZ*B_SZ;i++){
@@ -321,10 +318,7 @@ static void ip_print_blocks(void *_ctx,const unsigned char *_data,int _stride,
   mode=img->mode[_bj*img->nxblocks+_bi];
   fprintf(stderr,"%i",mode);
   for(by=0;by<=1;by++){
-    for(bx=0;bx<=2;bx++){
-      if(by==1&&bx==2){
-        continue;
-      }
+    for(bx=0;bx<=2-by;bx++){
       block=&img->fdct[img->fdct_stride*B_SZ*(_bj+by)+B_SZ*(_bi+bx)];
       for(j=0;j<B_SZ;j++){
         for(i=0;i<B_SZ;i++){
index bd01816..353bf48 100644 (file)
@@ -479,10 +479,14 @@ int od_select_mode_bits(const od_coeff *_block,int _stride,double *_weight,
     double bits;
     int    j;
     int    i;
+#if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
 #if 0
-    od_intra_pred4x4_mult(_block,_stride,mode,p);
+    (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(_block,_stride,mode,p);
+#else
+    (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(_block,_stride,mode,p);
+#endif
 #else
-    ne_intra_pred4x4_mult(_block,_stride,mode,p);
+# error "Need a predictor implementation for this block size."
 #endif
     bits=0;
     for(j=0;j<B_SZ;j++){
@@ -525,10 +529,14 @@ int od_select_mode_satd(const od_coeff *_block,int _stride,double *_weight){
     double satd;
     int    j;
     int    i;
+#if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
 #if 0
-    od_intra_pred4x4_mult(_block,_stride,mode,p);
+    (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(_block,_stride,mode,p);
+#else
+    (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(_block,_stride,mode,p);
+#endif
 #else
-    ne_intra_pred4x4_mult(_block,_stride,mode,p);
+# error "Need a predictor implementation for this block size."
 #endif
     satd=0;
     for(j=0;j<B_SZ;j++){
@@ -742,10 +750,14 @@ void image_data_pred_block(image_data *_this,int _bi,int _bj){
   int       i;
   mode=_this->mode[_this->nxblocks*_bj+_bi];
   block=&_this->fdct[_this->fdct_stride*B_SZ*(_bj+1)+B_SZ*(_bi+1)];
+#if B_SZ_LOG>=OD_LOG_BSIZE0&&B_SZ_LOG<OD_LOG_BSIZE0+OD_NBSIZES
 #if 0
-  od_intra_pred4x4_mult(block,_this->fdct_stride,mode,p);
+    (*OD_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(block,_this->fdct_stride,mode,p);
+#else
+    (*NE_INTRA_MULT[B_SZ_LOG-OD_LOG_BSIZE0])(block,_this->fdct_stride,mode,p);
+#endif
 #else
-  ne_intra_pred4x4_mult(block,_this->fdct_stride,mode,p);
+# error "Need a predictor implementation for this block size."
 #endif
   pred=&_this->pred[_this->pred_stride*B_SZ*_bj+B_SZ*_bi];
   for(j=0;j<B_SZ;j++){
@@ -1020,12 +1032,9 @@ void ne_intra_pred4x4_mult(const od_coeff *_c,int _stride,int _mode,double *_p){
     for(i=0;i<4;i++){
       _p[4*j+i]=NE_PRED_OFFSETS_4x4[_mode][j][i];
       for(by=0;by<=1;by++){
-        for(bx=0;bx<=2;bx++){
-         const od_coeff *b;
-          if(by==1&&bx==2){
-            break;
-          }
-         b=&_c[_stride*4*(by-1)+4*(bx-1)];
+        for(bx=0;bx<=2-by;bx++){
+          const od_coeff *b;
+          b=&_c[_stride*4*(by-1)+4*(bx-1)];
           for(k=0;k<4;k++){
             for(l=0;l<4;l++){
               _p[4*j+i]+=
@@ -1038,6 +1047,64 @@ void ne_intra_pred4x4_mult(const od_coeff *_c,int _stride,int _mode,double *_p){
   }
 }
 
+void ne_intra_pred8x8_mult(const od_coeff *_c,int _stride,int _mode,double *_p){
+  int j;
+  int i;
+  int by;
+  int bx;
+  int k;
+  int l;
+  for(j=0;j<8;j++){
+    for(i=0;i<8;i++){
+      _p[8*j+i]=NE_PRED_OFFSETS_8x8[_mode][j][i];
+      for(by=0;by<=1;by++){
+        for(bx=0;bx<=2-by;bx++){
+          const od_coeff *b;
+          b=&_c[_stride*8*(by-1)+8*(bx-1)];
+          for(k=0;k<8;k++){
+            for(l=0;l<8;l++){
+              _p[8*j+i]+=
+               b[_stride*k+l]*NE_PRED_WEIGHTS_8x8[_mode][j][i][by*8+k][bx*8+l];
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+void ne_intra_pred16x16_mult(const od_coeff *_c,int _stride,int _mode,double *_p){
+  int j;
+  int i;
+  int by;
+  int bx;
+  int k;
+  int l;
+  for(j=0;j<16;j++){
+    for(i=0;i<16;i++){
+      _p[16*j+i]=NE_PRED_OFFSETS_16x16[_mode][j][i];
+      for(by=0;by<=1;by++){
+        for(bx=0;bx<=2-by;bx++){
+          const od_coeff *b;
+          b=&_c[_stride*16*(by-1)+8*(bx-1)];
+          for(k=0;k<16;k++){
+            for(l=0;l<16;l++){
+              _p[16*j+i]+=
+               b[_stride*k+l]*NE_PRED_WEIGHTS_16x16[_mode][j][i][by*16+k][bx*16+l];
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+const od_intra_mult_func NE_INTRA_MULT[OD_NBSIZES]={
+  ne_intra_pred4x4_mult,
+  ne_intra_pred8x8_mult,
+  ne_intra_pred16x16_mult
+};
+
 void print_betas(FILE *_fp){
   int m;
   int i;
@@ -1093,10 +1160,7 @@ void print_betas(FILE *_fp){
         for(by=0;by<=1;by++){
           for(k=0;k<B_SZ;k++){
             fprintf(_fp,"        {");
-            for(bx=0;bx<=2;bx++){
-              if(by==1&&bx==2){
-                break;
-              }
+            for(bx=0;bx<=2-by;bx++){
               for(l=0;l<B_SZ;l++){
 #if B_SZ==4
                 fprintf(_fp,"%s  %- 24.18G",bx>0||l>0?",":"",NE_PRED_WEIGHTS_4x4[m][j][i][B_SZ*by+k][B_SZ*bx+l]);
index ad1d32e..609b0cc 100644 (file)
@@ -116,6 +116,8 @@ extern int NE_FILTER_PARAMS4[4];
 extern const od_filter_func NE_PRE_FILTER[OD_NBSIZES];
 extern const od_filter_func NE_POST_FILTER[OD_NBSIZES];
 
+extern const od_intra_mult_func NE_INTRA_MULT[OD_NBSIZES];
+
 extern double NE_PRED_OFFSETS_4x4[OD_INTRA_NMODES][4][4];
 extern double NE_PRED_WEIGHTS_4x4[OD_INTRA_NMODES][4][4][2*4][3*4];
 
index 429c4c6..6af9a69 100644 (file)
@@ -342,8 +342,6 @@ static void trans_ctx_search(trans_ctx *_this){
       }
     }
   }
-#else
-# error
 #endif
 
   fprintf(stdout,"cg=%G\n",coding_gain(r));