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