]> granicus.if.org Git - libvpx/commitdiff
fixed an issue with 8x8 token cost in trellisquant
authorYaowu Xu <yaowu@google.com>
Thu, 26 Jan 2012 22:36:20 +0000 (14:36 -0800)
committerYaowu Xu <yaowu@google.com>
Thu, 26 Jan 2012 22:50:11 +0000 (14:50 -0800)
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

vp8/encoder/block.h
vp8/encoder/encodemb.c
vp8/encoder/rdopt.c

index f992630a3dc4b2c19d7e2c4bc0230600407ed78a..68de571c5468a87f4d69b442ba0ac5fe8df5a0e4 100644 (file)
@@ -118,7 +118,14 @@ typedef struct
     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;
 
index 82ac021fd2305f823c0e42dfe46f6b2598f95e1e..7916066eb01c1d3ab3bf53d6cb1d0c8f3c5034d2 100644 (file)
@@ -907,9 +907,9 @@ void optimize_b_8x8(MACROBLOCK *mb, int i, int type,
                 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 @@ void optimize_b_8x8(MACROBLOCK *mb, int i, int type,
                 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 @@ void optimize_b_8x8(MACROBLOCK *mb, int i, int type,
             /* 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 @@ void optimize_b_8x8(MACROBLOCK *mb, int i, int type,
     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)
index 99bad881d3718abb5672dd12c3506e45889f4f0d..45db403f60a2b2686d3eead0c231fe7099a9f063 100644 (file)
@@ -215,7 +215,6 @@ static void fill_token_costs(
     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 @@ void vp8_initialize_rd_consts(VP8_COMP *cpi, int QIndex)
         (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;
@@ -666,6 +671,7 @@ static void macro_block_yrd( MACROBLOCK *mb,
     *Rate = vp8_rdcost_mby(mb);
 }
 
+
 static void copy_predictor(unsigned char *dst, const unsigned char *predictor)
 {
     const unsigned int *p = (const unsigned int *)predictor;