shithub: libvpx

Download patch

ref: 7eb7d6b22742ed0436f52c7e9dae4ce7d90b0ccd
parent: af3b0de732e2c90dd7216894559f3b1a5b5f21e5
author: Marco <marpan@google.com>
date: Mon Aug 15 06:22:40 EDT 2016

vp9 non-rd pickmode: Add limit on newmv-last and golden bias.

Add option, for newmv-last, to limit the rd-threshold update for early exit,
under a source varianace condition.
This can improve visual quality in low texture moving areas,
like forehead/faces.

Also add bias against golden to improve the speed/fps,
will little/negligible loss in quality.

Only affects CBR mode, non-svc, non-screen-content.

Change-Id: I3a5229eee860c71499a6fd464c450b167b07534d

--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -978,19 +978,21 @@
   }
 }
 
-static INLINE void update_thresh_freq_fact(VP9_COMP *cpi,
-                                           TileDataEnc *tile_data,
-                                           BLOCK_SIZE bsize,
-                                           MV_REFERENCE_FRAME ref_frame,
-                                           THR_MODES best_mode_idx,
-                                           PREDICTION_MODE mode) {
+static INLINE void update_thresh_freq_fact(
+    VP9_COMP *cpi, TileDataEnc *tile_data, int source_variance,
+    BLOCK_SIZE bsize, MV_REFERENCE_FRAME ref_frame, THR_MODES best_mode_idx,
+    PREDICTION_MODE mode) {
   THR_MODES thr_mode_idx = mode_idx[ref_frame][mode_offset(mode)];
   int *freq_fact = &tile_data->thresh_freq_fact[bsize][thr_mode_idx];
   if (thr_mode_idx == best_mode_idx)
     *freq_fact -= (*freq_fact >> 4);
-  else
+  else if (cpi->sf.limit_newmv_early_exit && mode == NEWMV &&
+           ref_frame == LAST_FRAME && source_variance < 5) {
+    *freq_fact = VPXMIN(*freq_fact + RD_THRESH_INC, 32);
+  } else {
     *freq_fact = VPXMIN(*freq_fact + RD_THRESH_INC,
                         cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
+  }
 }
 
 void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
@@ -1438,7 +1440,7 @@
   mi->tx_size =
       VPXMIN(max_txsize_lookup[bsize], tx_mode_to_biggest_tx_size[cm->tx_mode]);
 
-  if (sf->short_circuit_flat_blocks) {
+  if (sf->short_circuit_flat_blocks || sf->limit_newmv_early_exit) {
 #if CONFIG_VP9_HIGHBITDEPTH
     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
       x->source_variance = vp9_high_get_sby_perpixel_variance(
@@ -1558,6 +1560,13 @@
     mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
     mode_rd_thresh = best_mode_skip_txfm ? rd_threshes[mode_index] << 1
                                          : rd_threshes[mode_index];
+
+    // Increase mode_rd_thresh value for GOLDEN_FRAME for improved encoding
+    // speed with little/no subjective quality loss.
+    if (cpi->sf.bias_golden && ref_frame == GOLDEN_FRAME &&
+        cpi->rc.frames_since_golden > 4)
+      mode_rd_thresh = mode_rd_thresh << 3;
+
     if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
                             rd_thresh_freq_fact[mode_index]))
       continue;
@@ -2032,8 +2041,8 @@
       // TODO(yunqingwang): Check intra mode mask and only update freq_fact
       // for those valid modes.
       for (i = 0; i < intra_modes; i++) {
-        update_thresh_freq_fact(cpi, tile_data, bsize, INTRA_FRAME,
-                                best_mode_idx, intra_mode_list[i]);
+        update_thresh_freq_fact(cpi, tile_data, x->source_variance, bsize,
+                                INTRA_FRAME, best_mode_idx, intra_mode_list[i]);
       }
     } else {
       for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) {
@@ -2040,8 +2049,8 @@
         PREDICTION_MODE this_mode;
         if (best_ref_frame != ref_frame) continue;
         for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
-          update_thresh_freq_fact(cpi, tile_data, bsize, ref_frame,
-                                  best_mode_idx, this_mode);
+          update_thresh_freq_fact(cpi, tile_data, x->source_variance, bsize,
+                                  ref_frame, best_mode_idx, this_mode);
         }
       }
     }
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -426,6 +426,11 @@
     if (content == VP9E_CONTENT_SCREEN) {
       sf->short_circuit_flat_blocks = 1;
     }
+    if (cpi->oxcf.rc_mode == VPX_CBR &&
+        cpi->oxcf.content != VP9E_CONTENT_SCREEN && !cpi->use_svc) {
+      sf->limit_newmv_early_exit = 1;
+      sf->bias_golden = 1;
+    }
   }
 
   if (speed >= 6) {
@@ -467,6 +472,8 @@
       // More aggressive short circuit for speed 8.
       sf->short_circuit_low_temp_var = 2;
     }
+    sf->limit_newmv_early_exit = 0;
+    sf->bias_golden = 0;
   }
 }
 
@@ -578,6 +585,8 @@
   sf->simple_model_rd_from_var = 0;
   sf->short_circuit_flat_blocks = 0;
   sf->short_circuit_low_temp_var = 0;
+  sf->limit_newmv_early_exit = 0;
+  sf->bias_golden = 0;
 
   // Some speed-up features even for best quality as minimal impact on quality.
   sf->adaptive_rd_thresh = 1;
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -453,6 +453,11 @@
   // INTRA for bsize >= 32x32 and vert/horz INTRA for bsize 16x16, 16x32 and
   // 32x16.
   int short_circuit_low_temp_var;
+  // Limits the rd-threshold update for early exit for the newmv-last mode,
+  // for non-rd mode.
+  int limit_newmv_early_exit;
+  // Adds a bias against golden reference, for non-rd mode.
+  int bias_golden;
 } SPEED_FEATURES;
 
 struct VP9_COMP;