shithub: libvpx

Download patch

ref: 8be7e572a70ebe98693762868e2a72673e74feb9
parent: 1c07abca18d2e7f1868f085288b8ed7d98fdd2ed
author: JackyChen <jackychen@google.com>
date: Fri Aug 5 07:10:29 EDT 2016

vp9 svc: SVC encoder speed up.

Bias towards base_mv and skip 1/4 pixel motion search when using base mv.
2~3% speed up for 2 spatial layers, 3~5% speed up for 3 spatial layers.
PSNR loss:
(2 layers) 0.07dB for gips_stationary, 0.04dB for gips_motion;
(3 layers) 0.07dB for gips_stationary, 0.06dB for gips_motion.

Change-Id: I773acbda080c301cabe8cd259f842bcc5b8bc999

--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -203,9 +203,12 @@
       !(RDCOST(x->rdmult, x->rddiv, (*rate_mv + rate_mode), 0) > best_rd_sofar);
 
   if (rv) {
+    const int subpel_force_stop = use_base_mv && cpi->sf.base_mv_aggressive
+                                      ? 2
+                                      : cpi->sf.mv.subpel_force_stop;
     cpi->find_fractional_mv_step(
         x, &tmp_mv->as_mv, &ref_mv, cpi->common.allow_high_precision_mv,
-        x->errorperbit, &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
+        x->errorperbit, &cpi->fn_ptr[bsize], subpel_force_stop,
         cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
         x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0);
     *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
@@ -1602,10 +1605,10 @@
             x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref_frame], NULL, 0,
             0);
       } else if (svc->use_base_mv && svc->spatial_layer_id) {
-        if (frame_mv[NEWMV][ref_frame].as_int != INVALID_MV &&
-            frame_mv[NEWMV][ref_frame].as_int != 0) {
+        if (frame_mv[NEWMV][ref_frame].as_int != INVALID_MV) {
           const int pre_stride = xd->plane[0].pre[0].stride;
           int base_mv_sad = INT_MAX;
+          const float base_mv_bias = sf->base_mv_aggressive ? 1.5 : 1.0;
           const uint8_t *const pre_buf =
               xd->plane[0].pre[0].buf +
               (frame_mv[NEWMV][ref_frame].as_mv.row >> 3) * pre_stride +
@@ -1613,9 +1616,7 @@
           base_mv_sad = cpi->fn_ptr[bsize].sdf(
               x->plane[0].src.buf, x->plane[0].src.stride, pre_buf, pre_stride);
 
-          // TODO(wonkap): make the decision to use base layer mv on RD;
-          // not just SAD.
-          if (base_mv_sad < x->pred_mv_sad[ref_frame]) {
+          if (base_mv_sad < base_mv_bias * x->pred_mv_sad[ref_frame]) {
             // Base layer mv is good.
             if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col,
                                         &frame_mv[NEWMV][ref_frame], &rate_mv,
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -445,6 +445,7 @@
       // Enable short circuit for low temporal variance.
       sf->short_circuit_low_temp_var = 1;
     }
+    if (cpi->use_svc) sf->base_mv_aggressive = 1;
   }
 
   if (speed >= 7) {
@@ -457,6 +458,7 @@
       sf->mv.fullpel_search_step_param = 6;
     }
   }
+
   if (speed >= 8) {
     sf->adaptive_rd_thresh = 4;
     sf->mv.subpel_force_stop = (content == VP9E_CONTENT_SCREEN) ? 3 : 2;
@@ -587,6 +589,7 @@
   sf->short_circuit_low_temp_var = 0;
   sf->limit_newmv_early_exit = 0;
   sf->bias_golden = 0;
+  sf->base_mv_aggressive = 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,11 +453,17 @@
   // 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;
+
+  // Bias to use base mv and skip 1/4 subpel search when use base mv in
+  // enhancement layer.
+  int base_mv_aggressive;
 } SPEED_FEATURES;
 
 struct VP9_COMP;