shithub: libvpx

Download patch

ref: 62aa642d71bbbdc72dc01da4fb0416be550cd2e2
parent: 541eb7899409914dd0c530bebb2307102f7694a8
author: Jingning Han <jingning@google.com>
date: Wed Jul 6 06:05:51 EDT 2016

Enable uniform quantization with trellis optimization in speed 0

This commit allows the inter prediction residual to use uniform
quantization followed by trellis coefficient optimization in
speed 0. It improves the coding performance by

lowres 0.79%
midres 1.07%
hdres  1.44%

Change-Id: I46ef8cfe042a4ccc7a0055515012cd6cbf5c9619

--- a/vp9/encoder/vp9_encodemb.c
+++ b/vp9/encoder/vp9_encodemb.c
@@ -62,7 +62,7 @@
   tran_low_t    dqc;
 } vp9_token_state;
 
-static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] ={ {10, 6}, {8, 7}, };
+static const int plane_rd_mult[REF_TYPES][PLANE_TYPES] ={ {10, 6}, {8, 5}, };
 
 #define UPDATE_RD_COST()\
 {\
@@ -125,8 +125,8 @@
   return pt;
 }
 
-static int optimize_b(MACROBLOCK *mb, int plane, int block,
-                      TX_SIZE tx_size, int ctx) {
+int vp9_optimize_b(MACROBLOCK *mb, int plane, int block,
+                   TX_SIZE tx_size, int ctx) {
   MACROBLOCKD *const xd = &mb->e_mbd;
   struct macroblock_plane *const p = &mb->plane[plane];
   struct macroblockd_plane *const pd = &xd->plane[plane];
@@ -694,7 +694,7 @@
 
   if (x->optimize && (!x->skip_recode || !x->skip_optimize)) {
     const int ctx = combine_entropy_contexts(*a, *l);
-    *a = *l = optimize_b(x, plane, block, tx_size, ctx) > 0;
+    *a = *l = vp9_optimize_b(x, plane, block, tx_size, ctx) > 0;
   } else {
     *a = *l = p->eobs[block] > 0;
   }
@@ -970,7 +970,7 @@
         }
       }
       if (args->ctx != NULL && !x->skip_recode) {
-       *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
+       *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
       }
       if (!x->skip_encode && *eob)
         vp9_idct32x32_add(dqcoeff, dst, dst_stride, *eob);
@@ -990,7 +990,7 @@
         }
       }
       if (args->ctx != NULL && !x->skip_recode) {
-        *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
+        *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
       }
       if (!x->skip_encode && *eob)
         vp9_iht16x16_add(tx_type, dqcoeff, dst, dst_stride, *eob);
@@ -1010,7 +1010,7 @@
         }
       }
       if (args->ctx != NULL && !x->skip_recode) {
-        *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
+        *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
       }
       if (!x->skip_encode && *eob)
         vp9_iht8x8_add(tx_type, dqcoeff, dst, dst_stride, *eob);
@@ -1033,7 +1033,7 @@
         }
       }
       if (args->ctx != NULL && !x->skip_recode) {
-        *a = *l = optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
+        *a = *l = vp9_optimize_b(x, plane, block, tx_size, entropy_ctx) > 0;
       }
       if (!x->skip_encode && *eob) {
         if (tx_type == DCT_DCT)
--- a/vp9/encoder/vp9_encodemb.h
+++ b/vp9/encoder/vp9_encodemb.h
@@ -23,6 +23,8 @@
   struct optimize_ctx *ctx;
   int8_t *skip;
 };
+int vp9_optimize_b(MACROBLOCK *mb, int plane, int block,
+                   TX_SIZE tx_size, int ctx);
 void vp9_encode_sb(MACROBLOCK *x, BLOCK_SIZE bsize);
 void vp9_encode_sby_pass1(MACROBLOCK *x, BLOCK_SIZE bsize);
 void vp9_xform_quant_fp(MACROBLOCK *x, int plane, int block, int row, int col,
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -602,9 +602,9 @@
     return;
 
   if (!is_inter_block(mi)) {
-    struct encode_b_args arg = {x, NULL, &mi->skip};
+    struct encode_b_args intra_arg = {x, NULL, &mi->skip};
     vp9_encode_block_intra(plane, block, blk_row, blk_col, plane_bsize, tx_size,
-                           &arg);
+                           &intra_arg);
     if (args->cpi->sf.txfm_domain_distortion) {
       dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
                  &sse);
@@ -635,6 +635,8 @@
         SKIP_TXFM_NONE) {
       // full forward transform and quantization
       vp9_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size);
+      if (args->cpi->sf.quant_coeff_opt)
+        vp9_optimize_b(x, plane, block, tx_size, coeff_ctx);
       dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
                  &sse);
     } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] ==
@@ -668,6 +670,8 @@
   } else {
     // full forward transform and quantization
     vp9_xform_quant(x, plane, block, blk_row, blk_col, plane_bsize, tx_size);
+    if (args->cpi->sf.quant_coeff_opt)
+      vp9_optimize_b(x, plane, block, tx_size, coeff_ctx);
     dist_block(args->cpi, x, plane, block, blk_row, blk_col, tx_size, &dist,
                &sse);
   }
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -163,6 +163,7 @@
     sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
     sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
     sf->txfm_domain_distortion = 1;
+    sf->quant_coeff_opt = 0;
   }
 
   if (speed >= 2) {
@@ -281,6 +282,7 @@
 
   if (speed >= 1) {
     sf->txfm_domain_distortion = 1;
+    sf->quant_coeff_opt = 0;
     sf->use_square_partition_only = !frame_is_intra_only(cm);
     sf->less_rectangular_check = 1;
     sf->tx_size_search_method = frame_is_intra_only(cm) ? USE_FULL_RD
@@ -544,6 +546,7 @@
   sf->adaptive_interp_filter_search = 0;
   sf->allow_partition_search_skip = 0;
   sf->txfm_domain_distortion = 0;
+  sf->quant_coeff_opt = 1;
 
   for (i = 0; i < TX_SIZES; i++) {
     sf->intra_y_mode_mask[i] = INTRA_ALL;
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -246,9 +246,11 @@
   // Coefficient probability model approximation step size
   int coeff_prob_appx_step;
 
-  // Use transform domain distortion. Use pixel domain distortion when
-  // this flag is set to be zero. The pixel domain distortion computation
-  // improves the distortion metric precision.
+  // Enable uniform quantizer followed by trellis coefficient optimization
+  int quant_coeff_opt;
+
+  // Use transform domain distortion. Use pixel domain distortion in speed 0
+  // and certain situations in higher speed to improve the RD model precision.
   int txfm_domain_distortion;
 
   // The threshold is to determine how slow the motino is, it is used when