shithub: libvpx

Download patch

ref: 81d16e3f530705a8bfc5712734af3b289bf72150
parent: aebb16bfa81e57b6db35c2b709f863f1ae105f85
author: Yaowu Xu <yaowu@google.com>
date: Thu Jan 26 09:36:20 EST 2012

fixed an issue with 8x8 token cost in trellisquant

changed the token cost for 8x8 transformed macroblock used in trellisquant
from those derived from 4x4 transform coefficient distribution to those
derived from 8x8 transform coefficient distribution. Test results show
this fix help 8x8 transform based compression consistently on cif and hd
sets:

http://www.corp.google.com/~yaowu/no_crawl/t8x8/cif_cost8x8only.html
(avg psnr:.14% glb psnr: .17% ssim: .20%)
http://www.corp.google.com/~yaowu/no_crawl/t8x8/hd_cost8x8only.html
(avg psnr:.17% glb psnr: .18% ssim: .58%)

Note: To test the effect of this change, 8x8 transform was forced to be used
only on 16x16 predicted macroblocks on inter frames, the effect would be
bigger had all macroblocks been forcd to use 8x8 transform.

Change-Id: If9b7868b75357c66541f511e5ee78e4d2d4929a4

--- a/vp8/encoder/block.h
+++ b/vp8/encoder/block.h
@@ -118,7 +118,14 @@
     unsigned char *active_ptr;
     MV_CONTEXT *mvc;
 
-    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS] [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
+    unsigned int token_costs[BLOCK_TYPES] [COEF_BANDS]
+                            [PREV_COEF_CONTEXTS][MAX_ENTROPY_TOKENS];
+
+#if CONFIG_T8X8
+    unsigned int token_costs_8x8[BLOCK_TYPES] [COEF_BANDS]
+                            [PREV_COEF_CONTEXTS] [MAX_ENTROPY_TOKENS];
+#endif
+
     int optimize;
     int q_index;
 
--- a/vp8/encoder/encodemb.c
+++ b/vp8/encoder/encodemb.c
@@ -907,9 +907,9 @@
                 band = vp8_coef_bands_8x8[i + 1];
                 pt = vp8_prev_token_class[t0];
                 rate0 +=
-                    mb->token_costs[type][band][pt][tokens[next][0].token];
+                    mb->token_costs_8x8[type][band][pt][tokens[next][0].token];
                 rate1 +=
-                    mb->token_costs[type][band][pt][tokens[next][1].token];
+                    mb->token_costs_8x8[type][band][pt][tokens[next][1].token];
             }
             rd_cost0 = RDCOST_8x8(rdmult, rddiv, rate0, error0);
             rd_cost1 = RDCOST_8x8(rdmult, rddiv, rate1, error1);
@@ -966,13 +966,13 @@
                 if(t0!=DCT_EOB_TOKEN)
                 {
                     pt = vp8_prev_token_class[t0];
-                    rate0 += mb->token_costs[type][band][pt][
+                    rate0 += mb->token_costs_8x8[type][band][pt][
                         tokens[next][0].token];
                 }
                 if(t1!=DCT_EOB_TOKEN)
                 {
                     pt = vp8_prev_token_class[t1];
-                    rate1 += mb->token_costs[type][band][pt][
+                    rate1 += mb->token_costs_8x8[type][band][pt][
                         tokens[next][1].token];
                 }
             }
@@ -1013,12 +1013,12 @@
             /* Update the cost of each path if we're past the EOB token. */
             if (t0 != DCT_EOB_TOKEN)
             {
-                tokens[next][0].rate += mb->token_costs[type][band][0][t0];
+                tokens[next][0].rate += mb->token_costs_8x8[type][band][0][t0];
                 tokens[next][0].token = ZERO_TOKEN;
             }
             if (t1 != DCT_EOB_TOKEN)
             {
-                tokens[next][1].rate += mb->token_costs[type][band][0][t1];
+                tokens[next][1].rate += mb->token_costs_8x8[type][band][0][t1];
                 tokens[next][1].token = ZERO_TOKEN;
             }
             /* Don't update next, because we didn't add a new node. */
@@ -1034,8 +1034,8 @@
     error1 = tokens[next][1].error;
     t0 = tokens[next][0].token;
     t1 = tokens[next][1].token;
-    rate0 += mb->token_costs[type][band][pt][t0];
-    rate1 += mb->token_costs[type][band][pt][t1];
+    rate0 += mb->token_costs_8x8[type][band][pt][t0];
+    rate1 += mb->token_costs_8x8[type][band][pt][t1];
     rd_cost0 = RDCOST_8x8(rdmult, rddiv, rate0, error0);
     rd_cost1 = RDCOST_8x8(rdmult, rddiv, rate1, error1);
     if (rd_cost0 == rd_cost1)
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -215,7 +215,6 @@
     for (i = 0; i < BLOCK_TYPES; i++)
         for (j = 0; j < COEF_BANDS; j++)
             for (k = 0; k < PREV_COEF_CONTEXTS; k++)
-
                 vp8_cost_tokens((int *)(c [i][j][k]), p [i][j][k], vp8_coef_tree);
 
 }
@@ -363,6 +362,12 @@
         (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs
     );
 
+#if CONFIG_T8X8
+    fill_token_costs(
+        cpi->mb.token_costs_8x8,
+        (const vp8_prob( *)[8][3][11]) cpi->common.fc.coef_probs_8x8
+    );
+#endif
 #if CONFIG_QIMODE
     //rough estimate for costing
     cpi->common.kf_ymode_probs_index = cpi->common.base_qindex>>4;
@@ -665,6 +670,7 @@
     // rate
     *Rate = vp8_rdcost_mby(mb);
 }
+
 
 static void copy_predictor(unsigned char *dst, const unsigned char *predictor)
 {
--