From a142d6fc935cba1dc6ceb4d798b3aac68b34684b Mon Sep 17 00:00:00 2001
From: Jingning Han <jingning@google.com>
Date: Tue, 16 Jul 2013 12:04:07 -0700
Subject: [PATCH] Skip redundant motion search in 4x4 level rd loop

This commit makes the encoder to perform motion search only once
per reference frame type for each 4x4/4x8/8x4 block. For bus_cif
at 2000 kbps, the runtime goes from 253812ms -> 217817ms
(14% speed-up) for speed 0.

Change-Id: I5f17599ccc8cfaf93ccb4f98fcb6008af6d79e92
---
 vp9/encoder/vp9_rdopt.c | 50 ++++++++++++++++++++++-------------------
 1 file changed, 27 insertions(+), 23 deletions(-)

diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 91f606a1c4..58eeed2152 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1842,7 +1842,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
         vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
 
         // motion search for newmv (single predictor case only)
-        if (mbmi->ref_frame[1] <= 0 && this_mode == NEWMV) {
+        if (mbmi->ref_frame[1] <= 0 && this_mode == NEWMV &&
+            seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
           int step_param = 0;
           int further_steps;
           int thissme, bestsme = INT_MAX;
@@ -1914,7 +1915,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
 
           // restore src pointers
           mi_buf_restore(x, orig_src, orig_pre);
-        } else if (mbmi->ref_frame[1] > 0 && this_mode == NEWMV) {
+        }
+
+        if (mbmi->ref_frame[1] > 0 && this_mode == NEWMV &&
+            mbmi->interp_filter == vp9_switchable_interp[0]) {
           if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
               seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
             continue;
@@ -3415,28 +3419,28 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
         if ((newbest && cm->mcomp_filter_type == SWITCHABLE) ||
             (mbmi->interp_filter == cm->mcomp_filter_type &&
              cm->mcomp_filter_type != SWITCHABLE)) {
-              tmp_best_rdu = tmp_rd;
-              tmp_best_rate = rate;
-              tmp_best_ratey = rate_y;
-              tmp_best_distortion = distortion;
-              tmp_best_skippable = skippable;
-              tmp_best_mbmode = *mbmi;
-              tmp_best_partition = *x->partition_info;
-              for (i = 0; i < 4; i++)
-                tmp_best_bmodes[i] = xd->mode_info_context->bmi[i];
-              pred_exists = 1;
-              if (switchable_filter_index == 0 &&
-                  cpi->sf.use_rd_breakout &&
-                  best_rd < INT64_MAX) {
-                if (tmp_best_rdu / 2 > best_rd) {
-                  // skip searching the other filters if the first is
-                  // already substantially larger than the best so far
-                  tmp_best_filter = mbmi->interp_filter;
-                  tmp_best_rdu = INT64_MAX;
-                  break;
-                }
-              }
+          tmp_best_rdu = tmp_rd;
+          tmp_best_rate = rate;
+          tmp_best_ratey = rate_y;
+          tmp_best_distortion = distortion;
+          tmp_best_skippable = skippable;
+          tmp_best_mbmode = *mbmi;
+          tmp_best_partition = *x->partition_info;
+          for (i = 0; i < 4; i++)
+            tmp_best_bmodes[i] = xd->mode_info_context->bmi[i];
+          pred_exists = 1;
+          if (switchable_filter_index == 0 &&
+              cpi->sf.use_rd_breakout &&
+              best_rd < INT64_MAX) {
+            if (tmp_best_rdu / 2 > best_rd) {
+              // skip searching the other filters if the first is
+              // already substantially larger than the best so far
+              tmp_best_filter = mbmi->interp_filter;
+              tmp_best_rdu = INT64_MAX;
+              break;
             }
+          }
+        }
       }  // switchable_filter_index loop
       if (tmp_best_rdu == INT64_MAX)
         continue;
-- 
GitLab