enable selecting&transmitting to for intra mode entropy

This commit added a 3 bit index to the bitstream, the index is used to
look into the intra mode coding entropy context table. The commit uses
the mode stats to calculate the cost of transmitting modes using 8
possible entropy distributions, and selects the distribution that
provides the lowest cost to do the actual mode coding.

Initial test show this provides additional .2%~.3% gain over quantizer
adaptive intra mode coding. So the adaptive intra mode coding provides
a total of .5%(psnr) to .6% gain(ssim) combined for all-key-encoding

To build and test, configure with
--enable-experimental --enable-qimode

Change-Id: I7c41cd8bfb352bc1fe7c5da1848a58faea5ed74a
diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c
index fb9aa2e..a7d8a2a 100644
--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -207,6 +207,9 @@
     /* Default disable buffer to buffer copying */
     oci->copy_buffer_to_gf = 0;
     oci->copy_buffer_to_arf = 0;
+#if CONFIG_QIMODE
+    oci->kf_ymode_probs_update = 0;
+#endif
 }
 
 void vp8_remove_common(VP8_COMMON *oci)
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h
index e5d8bf5..782e0a9 100644
--- a/vp8/common/blockd.h
+++ b/vp8/common/blockd.h
@@ -25,7 +25,7 @@
 #define TRUE    1
 #define FALSE   0
 
-#define MODE_STATS
+//#define MODE_STATS
 
 /*#define DCPRED 1*/
 #define DCPREDSIMTHRESH 0
diff --git a/vp8/common/entropymode.c b/vp8/common/entropymode.c
index da8a548..589d39f 100644
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -15,7 +15,7 @@
 #if CONFIG_I8X8
 
 #if CONFIG_QIMODE
-static const unsigned int kf_y_mode_cts[8][VP8_YMODES] =
+const unsigned int kf_y_mode_cts[8][VP8_YMODES] =
 {
     {17,  6,  5,  2, 22, 203},
     {27, 13, 13,  6, 27, 170},
diff --git a/vp8/common/onyxc_int.h b/vp8/common/onyxc_int.h
index de1c312..1542127 100644
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -185,6 +185,8 @@
     vp8_prob kf_bmode_prob [VP8_BINTRAMODES] [VP8_BINTRAMODES] [VP8_BINTRAMODES-1];
 #if CONFIG_QIMODE
     vp8_prob kf_ymode_prob[8][VP8_YMODES-1];  /* keyframe "" */
+    int kf_ymode_probs_index;
+    int kf_ymode_probs_update;
 #else
     vp8_prob kf_ymode_prob [VP8_YMODES-1];  /* keyframe "" */
 #endif
diff --git a/vp8/decoder/decodemv.c b/vp8/decoder/decodemv.c
index 36feb28..a4ea8f1 100644
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -92,7 +92,7 @@
                 m->mbmi.mb_skip_coeff = 0;
 #if CONFIG_QIMODE
             y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc,
-                pbi->common.kf_ymode_prob[pbi->common.base_qindex>>4]);
+                pbi->common.kf_ymode_prob[pbi->common.kf_ymode_probs_index]);
 #else
             y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc, pbi->common.kf_ymode_prob);
 #endif
@@ -127,7 +127,6 @@
                  }
                 //printf("%2d%2d%2d%2d\n", m->bmi[0].as_mode,m->bmi[2].as_mode,
                 //                       m->bmi[8].as_mode,m->bmi[10].as_mode);
-                                         */
            }
             else
 #endif
@@ -557,6 +556,13 @@
 
     mb_mode_mv_init(pbi);
 
+#if CONFIG_QIMODE
+    if(pbi->common.frame_type==KEY_FRAME && !pbi->common.kf_ymode_probs_update)
+    {
+        pbi->common.kf_ymode_probs_index = vp8_read_literal(&pbi->bc, 3);
+    }
+#endif
+
     while (++mb_row < pbi->common.mb_rows)
     {
         int mb_col = -1;
diff --git a/vp8/encoder/bitstream.c b/vp8/encoder/bitstream.c
index 90a50c2..df7aee9 100644
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -1160,6 +1160,13 @@
         vp8_write_literal(bc, prob_skip_false, 8);
     }
 
+#if CONFIG_QIMODE
+    if(!c->kf_ymode_probs_update)
+    {
+        vp8_write_literal(bc, c->kf_ymode_probs_index, 3);
+    }
+#endif
+
     while (++mb_row < c->mb_rows)
     {
         int mb_col = -1;
@@ -1193,7 +1200,7 @@
             if (c->mb_no_coeff_skip)
                 vp8_encode_bool(bc, m->mbmi.mb_skip_coeff, prob_skip_false);
 #if CONFIG_QIMODE
-            kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->base_qindex>>4]);
+            kfwrite_ymode(bc, ym, c->kf_ymode_prob[c->kf_ymode_probs_index]);
 #else
             kfwrite_ymode(bc, ym, c->kf_ymode_prob);
 #endif
@@ -1785,6 +1792,35 @@
     else
         vp8_write_bit(bc, 0);
 }
+#if CONFIG_QIMODE
+extern const unsigned int kf_y_mode_cts[8][VP8_YMODES];
+static void decide_kf_ymode_entropy(VP8_COMP *cpi)
+{
+
+    int mode_cost[MB_MODE_COUNT];
+    int cost;
+    int bestcost = INT_MAX;
+    int bestindex = 0;
+    int i, j;
+
+    for(i=0; i<8; i++)
+    {
+        vp8_cost_tokens(mode_cost, cpi->common.kf_ymode_prob[i], vp8_kf_ymode_tree);
+        cost = 0;
+        for(j=0;j<VP8_YMODES;j++)
+        {
+            cost += mode_cost[j] * cpi->ymode_count[j];
+        }
+        if(cost < bestcost)
+        {
+            bestindex = i;
+            bestcost = cost;
+        }
+    }
+    cpi->common.kf_ymode_probs_index = bestindex;
+
+}
+#endif
 
 void vp8_pack_bitstream(VP8_COMP *cpi, unsigned char *dest, unsigned long *size)
 {
@@ -2083,6 +2119,9 @@
 
     if (pc->frame_type == KEY_FRAME)
     {
+#if CONFIG_QIMODE
+        decide_kf_ymode_entropy(cpi);
+#endif
         write_kfmodes(cpi);
 
 #ifdef ENTROPY_STATS
diff --git a/vp8/encoder/modecosts.c b/vp8/encoder/modecosts.c
index 846401c..841579a 100644
--- a/vp8/encoder/modecosts.c
+++ b/vp8/encoder/modecosts.c
@@ -41,7 +41,8 @@
 
     vp8_cost_tokens(c->mb.mbmode_cost[1], x->fc.ymode_prob, vp8_ymode_tree);
 #if CONFIG_QIMODE
-    vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob[c->common.base_qindex>>4], vp8_kf_ymode_tree);
+    vp8_cost_tokens(c->mb.mbmode_cost[0],
+        x->kf_ymode_prob[c->common.kf_ymode_probs_index], vp8_kf_ymode_tree);
 #else
     vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree);
 #endif
diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c
index c899cf8..c24bf60 100644
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -349,6 +349,10 @@
         (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs
     );
 
+#if CONFIG_QIMODE
+    //rough estimate for costing
+    cpi->common.kf_ymode_probs_index = cpi->common.base_qindex>>4;
+#endif
     vp8_init_mode_costs(cpi);
 
 }