shithub: libvpx

Download patch

ref: 2bbde25003f5f67e2d60449712521890cadf7774
parent: a10a268e58ffd4366f6dbddd5f26600d688714c9
author: Yaowu Xu <yaowu@google.com>
date: Thu Aug 4 12:30:27 EDT 2011

make uv intra mode coding adaptive to Y mode

This commit tries to do UV intra mode coding adaptive to Y intra mode.
Entropy context is defined as conditional PDF of uv intra mode given
the Y mode. All constants are normalized with 256 to be fit in 8 bits.

This provides further coding efficiency beyond the quantizer adaptive
y intra mode coding. Consistent gains were observed on all clips and
all bit rates for HD all key encoding tests.

To test, configure with
--enable-experimental --enable-uvintra

Change-Id: I2d78d73f143127f063e19bd0bac3b68c418d756a

--- a/configure
+++ b/configure
@@ -224,6 +224,7 @@
     csm
     i8x8
     qimode
+    uvintra
 "
 CONFIG_LIST="
     external_build
--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -34,11 +34,41 @@
 static const unsigned int kf_y_mode_cts[VP8_YMODES] = { 1607, 915, 812, 811, 5455};
 static const unsigned int y_mode_cts  [VP8_YMODES] = { 8080, 1908, 1582, 1007, 5874};
 #endif
+
+#if CONFIG_UVINTRA
+static const unsigned int uv_mode_cts  [VP8_UV_MODES] ={ 162, 41, 41, 12};
+/*
+static const unsigned int uv_mode_cts [VP8_YMODES] [VP8_UV_MODES] ={
+    { 180, 35, 35,  6},
+    { 152, 76, 20,  8},
+    { 152, 20, 76,  8},
+    { 172, 36, 36, 12},
+    { 162, 41, 41, 12},
+    { 162, 41, 41, 12},
+};
+*/
+#else
 static const unsigned int uv_mode_cts  [VP8_UV_MODES] = { 59483, 13605, 16492, 4230};
+#endif
+
+
 #if CONFIG_I8X8
 static const unsigned int i8x8_mode_cts  [VP8_UV_MODES] = {93, 69, 81, 13};
 #endif
+
+
+#if CONFIG_UVINTRA
+static const unsigned int kf_uv_mode_cts [VP8_YMODES] [VP8_UV_MODES] ={
+    { 180, 34, 34,  8},
+    { 132, 74, 40, 10},
+    { 132, 40, 74, 10},
+    { 152, 46, 40, 18},
+    { 142, 51, 45, 18},
+    { 142, 51, 45, 18},
+};
+#else
 static const unsigned int kf_uv_mode_cts[VP8_UV_MODES] = { 5319, 1904, 1703, 674};
+#endif
 
 static const unsigned int bmode_cts[VP8_BINTRAMODES] =
 {
@@ -259,11 +289,22 @@
         x->fc.uv_mode_prob, bct, uv_mode_cts,
         256, 1
     );
+#if CONFIG_UVINTRA
+    {
+        int i;
+        for (i=0;i<VP8_YMODES;i++)
+            vp8_tree_probs_from_distribution(
+                VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
+                x->kf_uv_mode_prob[i], bct, kf_uv_mode_cts[i],
+                256, 1);
+    }
+#else
     vp8_tree_probs_from_distribution(
         VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
         x->kf_uv_mode_prob, bct, kf_uv_mode_cts,
         256, 1
     );
+#endif
 #if CONFIG_I8X8
     vp8_tree_probs_from_distribution(
         VP8_UV_MODES, vp8_i8x8_mode_encodings, vp8_i8x8_mode_tree,
--- a/vp8/common/onyxc_int.h
+++ b/vp8/common/onyxc_int.h
@@ -190,7 +190,11 @@
 #else
     vp8_prob kf_ymode_prob [VP8_YMODES-1];  /* keyframe "" */
 #endif
+#if CONFIG_UVINTRA
+    vp8_prob kf_uv_mode_prob[VP8_YMODES] [VP8_UV_MODES-1];
+#else
     vp8_prob kf_uv_mode_prob [VP8_UV_MODES-1];
+#endif
 #if CONFIG_I8X8
     vp8_prob i8x8_mode_prob [VP8_UV_MODES-1];
 #endif
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -155,7 +155,13 @@
            }
             else
 #endif
-            m->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.kf_uv_mode_prob);
+#if CONFIG_UVINTRA
+            m->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc,
+                pbi->common.kf_uv_mode_prob[m->mbmi.mode]);
+#else
+            m->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc,
+                pbi->common.kf_uv_mode_prob);
+#endif
         }
 }
 
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -1359,7 +1359,11 @@
             }
             else
 #endif
+#if CONFIG_UVINTRA
+            write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
+#else
             write_uv_mode(bc, (m++)->mbmi.uv_mode, c->kf_uv_mode_prob);
+#endif
         }
         //printf("\n");
         m++;    // skip L prediction border
--- a/vp8/encoder/encodeframe.c
+++ b/vp8/encoder/encodeframe.c
@@ -75,8 +75,17 @@
 unsigned int inter_uv_modes[VP8_UV_MODES] = {0, 0, 0, 0};
 unsigned int inter_b_modes[15] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 unsigned int y_modes[VP8_YMODES] = {0, 0, 0, 0, 0};
-unsigned int i8x8_modes[VP8_I8X8_MODES]={0};
+unsigned int i8x8_modes[VP8_I8X8_MODES]={0  };
 unsigned int uv_modes[VP8_UV_MODES] = {0, 0, 0, 0};
+unsigned int uv_modes_y[VP8_YMODES][VP8_UV_MODES]=
+{
+{0, 0, 0, 0},
+{0, 0, 0, 0},
+{0, 0, 0, 0},
+{0, 0, 0, 0},
+{0, 0, 0, 0},
+{0, 0, 0, 0}
+};
 unsigned int b_modes[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 #endif
 
@@ -1462,6 +1471,7 @@
     const int is_key = cpi->common.frame_type == KEY_FRAME;
 
     ++ (is_key ? uv_modes : inter_uv_modes)[uvm];
+    ++ uv_modes_y[m][uvm];
 
     if (m == B_PRED)
     {
--- a/vp8/encoder/modecosts.c
+++ b/vp8/encoder/modecosts.c
@@ -47,7 +47,11 @@
     vp8_cost_tokens(c->mb.mbmode_cost[0], x->kf_ymode_prob, vp8_kf_ymode_tree);
 #endif
     vp8_cost_tokens(c->mb.intra_uv_mode_cost[1], x->fc.uv_mode_prob, vp8_uv_mode_tree);
+#if CONFIG_UVINTRA
+    vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob[VP8_YMODES-1], vp8_uv_mode_tree);
+#else
     vp8_cost_tokens(c->mb.intra_uv_mode_cost[0], x->kf_uv_mode_prob, vp8_uv_mode_tree);
+#endif
 #if CONFIG_I8X8
     vp8_cost_tokens(c->mb.i8x8_mode_costs,
                     x->i8x8_mode_prob,vp8_i8x8_mode_tree);
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -147,6 +147,7 @@
 extern int y_modes[VP8_YMODES]  ;
 extern int i8x8_modes[VP8_I8X8_MODES];
 extern int uv_modes[VP8_UV_MODES] ;
+extern int uv_modes_y[VP8_YMODES][VP8_UV_MODES];
 extern int b_modes[10]  ;
 extern int inter_y_modes[10] ;
 extern int inter_uv_modes[4] ;
@@ -2476,6 +2477,15 @@
             fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4]);
 #endif
             fprintf(f, "UV:%8d, %8d, %8d, %8d\n", uv_modes[0], uv_modes[1], uv_modes[2], uv_modes[3]);
+            fprintf(f, "Y-UV:\n");
+            {
+                int i;
+                for(i=0;i<VP8_YMODES;i++)
+                {
+                    fprintf(f, "%2d:%8d, %8d, %8d, %8d\n",i,uv_modes_y[i][0],
+                        uv_modes_y[i][1], uv_modes_y[i][2], uv_modes_y[i][3]);
+                }
+            }
             fprintf(f, "B: ");
             {
                 int i;
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -82,9 +82,15 @@
     vp8_prob ymode_prob[VP8_YMODES-1], uv_mode_prob[VP8_UV_MODES-1];
     /* keyframe intra mode probs */
 #if CONFIG_QIMODE
-    vp8_prob kf_ymode_prob[8][VP8_YMODES-1], kf_uv_mode_prob[VP8_UV_MODES-1];
+    vp8_prob kf_ymode_prob[8][VP8_YMODES-1];
 #else
-    vp8_prob kf_ymode_prob[VP8_YMODES-1], kf_uv_mode_prob[VP8_UV_MODES-1];
+    vp8_prob kf_ymode_prob[VP8_YMODES-1];
+#endif
+
+#if CONFIG_UVINTRA
+    vp8_prob kf_uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
+#else
+    vp8_prob kf_uv_mode_prob[VP8_UV_MODES-1];
 #endif
     /* intra MB type cts this frame */
     int ymode_count[VP8_YMODES], uv_mode_count[VP8_UV_MODES];