shithub: libvpx

Download patch

ref: be360d47f412424e1bf1d645860ccabdad2f3343
parent: 43a059de71e73e4eefd620d684f50c8a4c7a5e1d
author: Yaowu Xu <yaowu@google.com>
date: Thu Dec 8 06:43:09 EST 2011

Enabled adaptive UV intra coding for inter frames

Previously, Y-adaptive UV intra coding only enabled on key frames in
UVINTRA experiment. This commit enabled the same coding for inter
frames, so the encoding of UV intra modes are consistent cross all
frame types. Tests on derf set showed a very small overall gain around
.04%:

http://www.corp.google.com/~yaowu/no_crawl/interUVintra.html

The gain looks to be reasonable given inta coded MBs is only a
small portion of MBs in inter frames.

Change-Id: Ic6fc261923f2c253f4a0c9f8bccf4797557b9e16

--- a/vp8/common/entropymode.c
+++ b/vp8/common/entropymode.c
@@ -28,31 +28,28 @@
     {99, 42, 43, 21, 12,  39},
 };
 #else
-static const unsigned int kf_y_mode_cts[VP8_YMODES] = { 49, 22, 23, 11, 23, 128};
+static const unsigned int kf_y_mode_cts[VP8_YMODES] = {
+    49, 22, 23, 11, 23, 128};
 #endif
-/* TODO: calibrate the baseline distribution */
-static const unsigned int y_mode_cts  [VP8_YMODES] = { 8080, 1908, 1582, 1007, 2000, 5874};
 
+static const unsigned int y_mode_cts  [VP8_YMODES] = {
+    106,  25, 21, 13, 16, 74};
+
 #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},
+    { 210, 20, 20,  6},
+    { 180, 60, 10,  6},
+    { 150, 20, 80,  6},
+    { 170, 35, 35, 16},
+    { 142, 51, 45, 18}, /* never used */
+    { 160, 40, 46, 10},
 };
-*/
 #else
 static const unsigned int uv_mode_cts  [VP8_UV_MODES] = { 59483, 13605, 16492, 4230};
 #endif
 
-
 static const unsigned int i8x8_mode_cts  [VP8_UV_MODES] = {93, 69, 81, 13};
 
-
 #if CONFIG_UVINTRA
 static const unsigned int kf_uv_mode_cts [VP8_YMODES] [VP8_UV_MODES] ={
     { 180, 34, 34,  8},
@@ -59,8 +56,8 @@
     { 132, 74, 40, 10},
     { 132, 40, 74, 10},
     { 152, 46, 40, 18},
+    { 142, 51, 45, 18}, /* never used */
     { 142, 51, 45, 18},
-    { 142, 51, 45, 18},
 };
 #else
 static const unsigned int kf_uv_mode_cts[VP8_UV_MODES] = { 5319, 1904, 1703, 674};
@@ -268,26 +265,31 @@
         256, 1
     );
 #endif
-    vp8_tree_probs_from_distribution(
-        VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
-        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);
+            vp8_tree_probs_from_distribution(
+                VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
+                x->fc.uv_mode_prob[i], bct, uv_mode_cts[i],
+                256, 1);
+        }
     }
 #else
     vp8_tree_probs_from_distribution(
         VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
+        x->fc.uv_mode_prob, bct, uv_mode_cts,
+        256, 1);
+
+    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
-    );
+        256, 1);
 #endif
     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
@@ -43,7 +43,11 @@
 {
     vp8_prob bmode_prob [VP8_BINTRAMODES-1];
     vp8_prob ymode_prob [VP8_YMODES-1];   /* interframe intra mode probs */
+#if CONFIG_UVINTRA
+    vp8_prob uv_mode_prob [VP8_YMODES][VP8_UV_MODES-1];
+#else
     vp8_prob uv_mode_prob [VP8_UV_MODES-1];
+#endif
     vp8_prob sub_mv_ref_prob [VP8_SUBMVREFS-1];
     vp8_prob coef_probs [BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [ENTROPY_NODES];
 #if CONFIG_T8X8
--- a/vp8/decoder/decodemv.c
+++ b/vp8/decoder/decodemv.c
@@ -410,7 +410,9 @@
             }
             while (++i < 4);
         }
-
+#if CONFIG_UVINTRA
+        //vp8_read_bit(bc);
+#else
         if (vp8_read_bit(bc))
         {
             int i = 0;
@@ -421,7 +423,7 @@
             }
             while (++i < 3);
         }
-
+#endif /* CONFIG_UVINTRA */
         read_mvcontexts(bc, mvc);
     }
 }
@@ -798,7 +800,13 @@
             }
         }
         else
-            mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc, pbi->common.fc.uv_mode_prob);
+#if CONFIG_UVINTRA
+            mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc,
+                                    pbi->common.fc.uv_mode_prob[mbmi->mode]);
+#else
+            mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc,
+                                    pbi->common.fc.uv_mode_prob);
+#endif /*CONFIG_UVINTRA*/
     }
 
 }
--- a/vp8/encoder/bitstream.c
+++ b/vp8/encoder/bitstream.c
@@ -128,13 +128,16 @@
         );
     }
     {
+#if CONFIG_UVINTRA
+        //vp8_write_bit(w, 0);
+#else
         vp8_prob Pnew   [VP8_UV_MODES-1];
         unsigned int bct [VP8_UV_MODES-1] [2];
-
         update_mode(
             w, VP8_UV_MODES, vp8_uv_mode_encodings, vp8_uv_mode_tree,
             Pnew, x->fc.uv_mode_prob, bct, (unsigned int *)cpi->uv_mode_count
         );
+#endif
     }
 }
 
@@ -1147,7 +1150,19 @@
                     write_i8x8_mode(w, m->bmi[10].as_mode, pc->i8x8_mode_prob);
                 }
                 else
+                {
+#if CONFIG_UVINTRA
+                    write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob[mode]);
+#ifdef MODE_STATS
+                    if(mode!=B_PRED)
+                        ++cpi->y_uv_mode_count[mode][mi->uv_mode];
+#endif
+
+#else
                     write_uv_mode(w, mi->uv_mode, pc->fc.uv_mode_prob);
+#endif /*CONFIG_UVINTRA*/
+
+                }
             }
             else
             {
--- a/vp8/encoder/modecosts.c
+++ b/vp8/encoder/modecosts.c
@@ -37,20 +37,28 @@
 
         vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.bmode_prob, T);
     }
-    vp8_cost_tokens((int *)c->mb.inter_bmode_costs, x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_tree);
+    vp8_cost_tokens((int *)c->mb.inter_bmode_costs,
+        x->fc.sub_mv_ref_prob, vp8_sub_mv_ref_tree);
 
     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.kf_ymode_probs_index], vp8_kf_ymode_tree);
+                    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);
+    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);
+    vp8_cost_tokens(c->mb.intra_uv_mode_cost[1],
+                    x->fc.uv_mode_prob[VP8_YMODES-1], vp8_uv_mode_tree);
+    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);
+    vp8_cost_tokens(c->mb.intra_uv_mode_cost[1],
+                    x->fc.uv_mode_prob, vp8_uv_mode_tree);
+    vp8_cost_tokens(c->mb.intra_uv_mode_cost[0],
+                    x->kf_uv_mode_prob, vp8_uv_mode_tree);
 #endif
     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
@@ -2591,6 +2591,12 @@
     vp8_loop_filter_init(cm);
 
     cpi->common.error.setjmp = 0;
+
+#if CONFIG_UVINTRA
+    vp8_zero(cpi->y_uv_mode_count)
+#endif
+
+
     return (VP8_PTR) cpi;
 
 }
@@ -2698,7 +2704,7 @@
             fprintf(f, "Y: %8d, %8d, %8d, %8d, %8d, %8d\n", y_modes[0], y_modes[1], y_modes[2], y_modes[3], y_modes[4], y_modes[5]);
             fprintf(f, "I8:%8d, %8d, %8d, %8d\n", i8x8_modes[0], i8x8_modes[1], i8x8_modes[2], i8x8_modes[3]);
             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");
+            fprintf(f, "KeyFrame Y-UV:\n");
             {
                 int i;
                 for(i=0;i<VP8_YMODES;i++)
@@ -2707,6 +2713,17 @@
                         uv_modes_y[i][1], uv_modes_y[i][2], uv_modes_y[i][3]);
                 }
             }
+#if CONFIG_UVINTRA
+            fprintf(f, "Inter Y-UV:\n");
+            {
+                int i;
+                for(i=0;i<VP8_YMODES;i++)
+                {
+                    fprintf(f, "%2d:%8d, %8d, %8d, %8d\n",i,cpi->y_uv_mode_count[i][0],
+                        cpi->y_uv_mode_count[i][1], cpi->y_uv_mode_count[i][2], cpi->y_uv_mode_count[i][3]);
+                }
+            }
+#endif
             fprintf(f, "B: ");
             {
                 int i;
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -83,7 +83,7 @@
     int inter_b_modes[B_MODE_COUNT];
 #endif
     /* interframe intra mode probs */
-    vp8_prob ymode_prob[VP8_YMODES-1], uv_mode_prob[VP8_UV_MODES-1];
+    vp8_prob ymode_prob[VP8_YMODES-1];
     /* keyframe intra mode probs */
 #if CONFIG_QIMODE
     vp8_prob kf_ymode_prob[8][VP8_YMODES-1];
@@ -93,8 +93,10 @@
 
 #if CONFIG_UVINTRA
     vp8_prob kf_uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
+    vp8_prob uv_mode_prob[VP8_YMODES][VP8_UV_MODES-1];
 #else
     vp8_prob kf_uv_mode_prob[VP8_UV_MODES-1];
+    vp8_prob 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];
@@ -538,6 +540,12 @@
     int t4x4_count;
     int t8x8_count;
 #endif
+
+#if CONFIG_UVINTRA
+    int y_uv_mode_count[VP8_YMODES][VP8_UV_MODES];
+#endif
+
+
 
     unsigned char *segmentation_map;
     unsigned char *last_segmentation_map;
--