shithub: libvpx

Download patch

ref: 1d44e7ce1ff748bd07a66bd146d956b2c38caf1c
parent: aac2c12663dc3b7aec16436612c4d3cd3d589001
author: Yaowu Xu <yaowu@google.com>
date: Wed Aug 31 08:01:58 EDT 2011

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

--- 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)
--- 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
--- 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},
--- 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
--- 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
@@ -556,6 +555,13 @@
     int mb_row = -1;
 
     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)
     {
--- 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,7 +1792,36 @@
     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)
 {
     int i, j;
@@ -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
--- 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
--- 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);
 
 }