From d66c7486351530662c2c906b55c1c0e89ec6299d Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Thu, 9 Jan 2014 18:01:30 -0800 Subject: [PATCH] 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 --- vp9/encoder/vp9_encodeframe.c | 3 --- vp9/encoder/vp9_onyx_if.c | 3 +++ vp9/encoder/vp9_rdopt.c | 44 +++++++++++++++++++++-------------- 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index a4d5fbe84..43f803842 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1925,9 +1925,6 @@ static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile, 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; diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 2cdf45d3f..cab3ef100 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -878,6 +878,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { 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 @@ void vp9_set_speed_features(VP9_COMP *cpi) { 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 @@ void vp9_set_speed_features(VP9_COMP *cpi) { 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; diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 97dc1e0ff..d940db945 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -3174,7 +3174,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, *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 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, 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 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } // 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 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } - // 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 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, 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 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, 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] * @@ -4366,11 +4379,6 @@ int64_t vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, } } - // 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; *returndistortion = INT_MAX; -- 2.40.0