]> granicus.if.org Git - libvpx/commitdiff
Reworked the auto_mv_step_size speed feature
authorDeb Mukherjee <debargha@google.com>
Fri, 12 Jul 2013 16:52:24 +0000 (09:52 -0700)
committerDeb Mukherjee <debargha@google.com>
Fri, 19 Jul 2013 22:12:56 +0000 (15:12 -0700)
This patch modifies the auto_mv_step_size speed feature to
use a combination of the maximum magnitude mv from the last
inter frame, and the maximum magnitude mv for the two reference
mvs with the same reference. For arf frames, the max mav step
for the resolution is used.
The bounds therefore are slightly tighter. The feature is made
a speed 1 feature.

Rebased.

Results (when this feature is turned on over speed 0):
derfraw300: -0.046% psnr, about 5+% speedup
(tested on football: goes from 4m30.760s to 4m17.410s).

Change-Id: If492797a61b0b4b3e58c0b8f86afb880165fc9f6

vp9/encoder/vp9_block.h
vp9/encoder/vp9_encodemv.c
vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_rdopt.c

index d6882d5859f16c015d4767fefafbe686fb7bc44f..4b49b17a29661cd1b1f7f7fd477a945d8a242499 100644 (file)
@@ -96,6 +96,7 @@ struct macroblock {
   signed int act_zbin_adj;
 
   int mv_best_ref_index[MAX_REF_FRAMES];
+  unsigned int max_mv_context[MAX_REF_FRAMES];
 
   int nmvjointcost[MV_JOINTS];
   int nmvcosts[2][MV_VALS];
index 500f57442e68e9496574efb053786c716c96b133..7c6f292d5ff6abe239e515b4b00373266062d3a2 100644 (file)
@@ -486,11 +486,11 @@ void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w,
   if (mv_joint_horizontal(j))
     encode_mv_component(w, diff.col, &mvctx->comps[1], usehp);
 
-  // If auto_mv_step_size is enabled and it is an arf/non shown frame
-  // then keep track of the largest motion vector component used.
-  if (cpi->sf.auto_mv_step_size && !cpi->common.show_frame) {
-    cpi->max_mv_magnitude = MAX((MAX(abs(mv->row), abs(mv->col)) >> 3),
-                                cpi->max_mv_magnitude);
+  // If auto_mv_step_size is enabled then keep track of the largest
+  // motion vector component used.
+  if (!cpi->dummy_packing && cpi->sf.auto_mv_step_size) {
+    unsigned int maxv = MAX(abs(mv->row), abs(mv->col)) >> 3;
+    cpi->max_mv_magnitude = MAX(maxv, cpi->max_mv_magnitude);
   }
 }
 
index 2afcd27b1a43e1f4d0729331f85d8730944f14b9..548f70baa31a4d88e20d60e5eec8a170955ad0ae 100644 (file)
@@ -680,12 +680,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
     cpi->mode_chosen_counts[i] = 0;
   }
 
-  // Initialize cpi->max_mv_magnitude if appropriate.
-  if ((cpi->common.frame_type == KEY_FRAME) || cpi->common.intra_only ||
-    (cpi->common.show_frame == 0)) {
-    cpi->max_mv_magnitude = 0;
-  }
-
   // best quality defaults
   sf->RD = 1;
   sf->search_method = NSTEP;
@@ -747,7 +741,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
 #else
       sf->static_segmentation = 0;
 #endif
-      sf->auto_mv_step_size = 1;
       sf->use_avoid_tested_higherror = 1;
       sf->adaptive_rd_thresh = 1;
       sf->last_chroma_intra_mode = TM_PRED;
@@ -772,6 +765,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
         sf->last_chroma_intra_mode = H_PRED;
         sf->use_rd_breakout = 1;
         sf->skip_encode_sb = 1;
+        sf->auto_mv_step_size = 1;
       }
       if (speed == 2) {
         sf->adjust_thresholds_by_speed = 1;
@@ -798,6 +792,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
         sf->using_small_partition_info = 1;
         sf->disable_splitmv =
             (MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
+        sf->auto_mv_step_size = 1;
       }
       if (speed == 3) {
         sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
@@ -814,6 +809,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
         sf->use_rd_breakout = 1;
         sf->skip_encode_sb = 1;
         sf->disable_splitmv = 1;
+        sf->auto_mv_step_size = 1;
       }
       if (speed == 4) {
         sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
@@ -830,6 +826,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
                                      FLAG_SKIP_COMP_REFMISMATCH;
         sf->use_rd_breakout = 1;
         sf->optimize_coefficients = 0;
+        sf->auto_mv_step_size = 1;
         // sf->reduce_first_step_size = 1;
         // sf->reference_masking = 1;
 
@@ -2489,6 +2486,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
   int undershoot_seen = 0;
 
   SPEED_FEATURES *sf = &cpi->sf;
+  unsigned int max_mv_def = MIN(cpi->common.width, cpi->common.height);
 #if RESET_FOREACH_FILTER
   int q_low0;
   int q_high0;
@@ -2561,6 +2559,24 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
   // Set default state for segment based loop filter update flags
   xd->mode_ref_lf_delta_update = 0;
 
+  // Initialize cpi->mv_step_param to default based on max resolution
+  cpi->mv_step_param = vp9_init_search_range(cpi, max_mv_def);
+  // Initialize cpi->max_mv_magnitude and cpi->mv_step_param if appropriate.
+  if (sf->auto_mv_step_size) {
+    if ((cpi->common.frame_type == KEY_FRAME) || cpi->common.intra_only) {
+      // initialize max_mv_magnitude for use in the first INTER frame
+      // after a key/intra-only frame
+      cpi->max_mv_magnitude = max_mv_def;
+    } else {
+      if (cm->show_frame)
+        // allow mv_steps to correspond to twice the max mv magnitude found
+        // in the previous frame, capped by the default max_mv_magnitude based
+        // on resolution
+        cpi->mv_step_param = vp9_init_search_range(
+            cpi, MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
+      cpi->max_mv_magnitude = 0;
+    }
+  }
 
   // Set various flags etc to special state if it is a key frame
   if (cm->frame_type == KEY_FRAME) {
index 19b1e3af5484f65000bd2098694c73e6bde191df..113e0343dd1384acc5bb954c23dfe891b21974b7 100644 (file)
@@ -505,6 +505,7 @@ typedef struct VP9_COMP {
   int error_bins[1024];
 
   unsigned int max_mv_magnitude;
+  int mv_step_param;
 
   // Data used for real time conferencing mode to help determine if it would be good to update the gf
   int inter_zz_count;
index a0c64beb515249645c7d6f5caac1be94bcfa05b1..a2ecafacc40d973831bf9a52db8a4b9a1d76606a 100644 (file)
@@ -1940,9 +1940,24 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
               if (i == 2)
                 bsi->mvp.as_int =
                 x->e_mbd.mode_info_context->bmi[i - 2].as_mv[0].as_int;
-              step_param = 2;
             }
           }
+          if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
+            // Take wtd average of the step_params based on the last frame's
+            // max mv magnitude and the best ref mvs of the current block for
+            // the given reference.
+            if (i == 0)
+              step_param = (vp9_init_search_range(
+                  cpi, x->max_mv_context[mbmi->ref_frame[0]]) +
+                  cpi->mv_step_param) >> 1;
+            else
+              step_param = (vp9_init_search_range(
+                  cpi, MAX(abs(bsi->mvp.as_mv.row),
+                           abs(bsi->mvp.as_mv.col)) >> 3) +
+                  cpi->mv_step_param) >> 1;
+          } else {
+            step_param = cpi->mv_step_param;
+          }
 
           further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
 
@@ -2163,6 +2178,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
   int best_index = 0;
   int best_sad = INT_MAX;
   int this_sad = INT_MAX;
+  unsigned int max_mv = 0;
 
   uint8_t *src_y_ptr = x->plane[0].src.buf;
   uint8_t *ref_y_ptr;
@@ -2172,6 +2188,8 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
   for (i = 0; i < MAX_MV_REF_CANDIDATES; i++) {
     this_mv.as_int = mbmi->ref_mvs[ref_frame][i].as_int;
 
+    max_mv = MAX(max_mv,
+                 MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
     // The list is at an end if we see 0 for a second time.
     if (!this_mv.as_int && zero_seen)
       break;
@@ -2195,6 +2213,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
 
   // Note the index of the mv that worked best in the reference list.
   x->mv_best_ref_index[ref_frame] = best_index;
+  x->max_mv_context[ref_frame] = max_mv;
 }
 
 static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
@@ -2441,12 +2460,14 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
     // Work out the size of the first step in the mv step search.
     // 0 here is maximum length first step. 1 is MAX >> 1 etc.
     if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
-      step_param = vp9_init_search_range(cpi, cpi->max_mv_magnitude);
+      // Take wtd average of the step_params based on the last frame's
+      // max mv magnitude and that based on the best ref mvs of the current
+      // block for the given reference.
+      step_param = (vp9_init_search_range(cpi, x->max_mv_context[ref]) +
+                    cpi->mv_step_param) >> 1;
     } else {
-      step_param = vp9_init_search_range(
-                     cpi, MIN(cpi->common.width, cpi->common.height));
+      step_param = cpi->mv_step_param;
     }
-
     // mvp_full.as_int = ref_mv[0].as_int;
     mvp_full.as_int =
         mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int;