shithub: libvpx

Download patch

ref: d66c7486351530662c2c906b55c1c0e89ec6299d
parent: af31b27aae70d18bf5d52307bde1ab356b7c42b5
author: Jingning Han <jingning@google.com>
date: Thu Jan 9 13:01:30 EST 2014

Enable skipping reference frame check in rd loop

This commit allows encoder to compare the SAD cost associated with
the best motion vector predictor, per frame. If one reference frame
has this cost more than 4 times of the best SAD cost given by other
reference frames, skip NEARESTMV, NEARMV, ZEROMV mode check of this
reference frame.

This setting is turned on in speed 2 and above. Compression quality
change in speed 2:
derf  -0.014%
yt    -0.097%
hd    -0.023%
stdhd  0.046%

It reduces the speed 2 runtime of test sequences:
pedestrian_area_1080p 4000 kbps 310763 ms -> 303595 ms
bluesky_1080p 6000 kbps         259852 ms -> 251920 ms

Change-Id: I7f59cf79503d51836d61d56d50dc5bdf0e502e22

--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1925,9 +1925,6 @@
 
     vp9_zero(cpi->mb.pred_mv);
 
-    if (cpi->sf.reference_masking)
-      rd_pick_reference_frame(cpi, tile, mi_row, mi_col);
-
     if (cpi->sf.use_lastframe_partitioning ||
         cpi->sf.use_one_partition_size_always ) {
       const int idx_str = cm->mode_info_stride * mi_row + mi_col;
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -878,6 +878,7 @@
         sf->use_rd_breakout = 1;
         sf->adaptive_motion_search = 1;
         sf->adaptive_pred_filter_type = 2;
+        sf->reference_masking = 1;
         sf->auto_mv_step_size = 1;
 
         sf->disable_filter_search_var_thresh = 50;
@@ -914,6 +915,7 @@
         sf->use_rd_breakout = 1;
         sf->adaptive_motion_search = 1;
         sf->adaptive_pred_filter_type = 2;
+        sf->reference_masking = 1;
         sf->auto_mv_step_size = 1;
 
         sf->disable_filter_search_var_thresh = 100;
@@ -948,6 +950,7 @@
         sf->use_rd_breakout = 1;
         sf->adaptive_motion_search = 1;
         sf->adaptive_pred_filter_type = 2;
+        sf->reference_masking = 1;
         sf->auto_mv_step_size = 1;
 
         sf->disable_filter_search_var_thresh = 200;
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3174,7 +3174,7 @@
 
   *returnrate = INT_MAX;
 
-  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
+  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
     x->pred_mv_sad[ref_frame] = INT_MAX;
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
       setup_buffer_inter(cpi, x, tile, get_ref_frame_idx(cpi, ref_frame),
@@ -3185,6 +3185,18 @@
     frame_mv[ZEROMV][ref_frame].as_int = 0;
   }
 
+  cpi->ref_frame_mask = 0;
+  for (ref_frame = LAST_FRAME;
+       ref_frame <= ALTREF_FRAME && cpi->sf.reference_masking; ++ref_frame) {
+    int i;
+    for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
+      if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) {
+        cpi->ref_frame_mask |= (1 << ref_frame);
+        break;
+      }
+    }
+  }
+
   for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
     int mode_excluded = 0;
     int64_t this_rd = INT64_MAX;
@@ -3234,8 +3246,7 @@
     }
 
     // Skip if the current reference frame has been masked off
-    if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask &&
-        (cpi->ref_frame_mask & (1 << ref_frame)))
+    if (cpi->ref_frame_mask & (1 << ref_frame) && this_mode != NEWMV)
       continue;
 
     // Test best rd so far against threshold for trying this mode.
@@ -3640,11 +3651,6 @@
     }
   }
 
-  // If we are using reference masking and the set mask flag is set then
-  // create the reference frame mask.
-  if (cpi->sf.reference_masking && cpi->set_ref_frame_mask)
-    cpi->ref_frame_mask = ~(1 << vp9_mode_order[best_mode_index].ref_frame[0]);
-
   // Flag all modes that have a distortion thats > 2x the best we found at
   // this level.
   for (mode_index = 0; mode_index < MB_MODE_COUNT; ++mode_index) {
@@ -3805,6 +3811,18 @@
     frame_mv[ZEROMV][ref_frame].as_int = 0;
   }
 
+  cpi->ref_frame_mask = 0;
+  for (ref_frame = LAST_FRAME;
+       ref_frame <= ALTREF_FRAME && cpi->sf.reference_masking; ++ref_frame) {
+    int i;
+    for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
+      if ((x->pred_mv_sad[ref_frame] >> 1) > x->pred_mv_sad[i]) {
+        cpi->ref_frame_mask |= (1 << ref_frame);
+        break;
+      }
+    }
+  }
+
   for (mode_index = 0; mode_index < MAX_REFS; ++mode_index) {
     int mode_excluded = 0;
     int64_t this_rd = INT64_MAX;
@@ -3852,11 +3870,6 @@
         continue;
     }
 
-    // Skip if the current reference frame has been masked off
-    if (cpi->sf.reference_masking && !cpi->set_ref_frame_mask &&
-        (cpi->ref_frame_mask & (1 << ref_frame)))
-      continue;
-
     // Test best rd so far against threshold for trying this mode.
     if ((best_rd <
          ((int64_t)cpi->rd_thresh_sub8x8[segment_id][bsize][mode_index] *
@@ -4365,11 +4378,6 @@
                               BLOCK_8X8, uv_tx_size);
     }
   }
-
-  // If we are using reference masking and the set mask flag is set then
-  // create the reference frame mask.
-  if (cpi->sf.reference_masking && cpi->set_ref_frame_mask)
-    cpi->ref_frame_mask = ~(1 << vp9_ref_order[best_mode_index].ref_frame[0]);
 
   if (best_rd == INT64_MAX && bsize < BLOCK_8X8) {
     *returnrate = INT_MAX;