From f9f0879756c6c6a5af3cd43986ffde39b3b5deae Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Tue, 9 Sep 2014 18:43:27 -0700 Subject: Refactor to remove speed feature dependency on mode search order This commit refactor the rate-distortion optimization search for regular block sizes to remove the speed feature dependency on mode search order. Change-Id: Ied033ee484c2957e17baa7b6450b720fe7dd0e7d --- vp9/encoder/vp9_rdopt.c | 69 +++++++++++++++++++++++----------------- vp9/encoder/vp9_speed_features.c | 37 --------------------- vp9/encoder/vp9_speed_features.h | 38 ++++++++++++++++++++++ 3 files changed, 78 insertions(+), 66 deletions(-) (limited to 'vp9') diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 9096677fb..7c3e87d77 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -41,9 +41,14 @@ #define RD_THRESH_MAX_FACT 64 #define RD_THRESH_INC 1 -#define LAST_FRAME_MODE_MASK 0xFFEDCD60 -#define GOLDEN_FRAME_MODE_MASK 0xFFDA3BB0 -#define ALT_REF_MODE_MASK 0xFFC648D0 +#define LAST_FRAME_MODE_MASK ((1 << GOLDEN_FRAME) | (1 << ALTREF_FRAME) | \ + (1 << INTRA_FRAME)) +#define GOLDEN_FRAME_MODE_MASK ((1 << LAST_FRAME) | (1 << ALTREF_FRAME) | \ + (1 << INTRA_FRAME)) +#define ALT_REF_MODE_MASK ((1 << LAST_FRAME) | (1 << GOLDEN_FRAME) | \ + (1 << INTRA_FRAME)) + +#define SECOND_REF_FRAME_MASK ((1 << ALTREF_FRAME) | 0x01) #define MIN_EARLY_TERM_INDEX 3 @@ -2584,7 +2589,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, PREDICTION_MODE mode_uv[TX_SIZES]; int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q); int best_skip2 = 0; - int mode_skip_mask = 0; + uint8_t ref_frame_skip_mask[2] = { 0 }; + uint16_t mode_skip_mask[MAX_REF_FRAMES] = { 0 }; int mode_skip_start = cpi->sf.mode_skip_start + 1; const int *const rd_threshes = rd_opt->threshes[segment_id][bsize]; const int *const rd_thresh_freq_fact = rd_opt->thresh_freq_fact[bsize]; @@ -2628,23 +2634,17 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { - // All modes from vp9_mode_order that use this frame as any ref - static const int ref_frame_mask_all[] = { - 0x0, 0x123291, 0x25c444, 0x39b722 - }; - // Fixed mv modes (NEARESTMV, NEARMV, ZEROMV) from vp9_mode_order that use - // this frame as their primary ref - static const int ref_frame_mask_fixedmv[] = { - 0x0, 0x121281, 0x24c404, 0x080102 - }; if (!(cpi->ref_frame_flags & flag_list[ref_frame])) { - // Skip modes for missing references - mode_skip_mask |= ref_frame_mask_all[ref_frame]; + // Skip checking missing references in both single and compound reference + // modes. Note that a mode will be skipped iff both reference frames + // are masked out. + ref_frame_skip_mask[0] |= (1 << ref_frame); + ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; } else if (cpi->sf.reference_masking) { for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) { // Skip fixed mv modes for poor references if ((x->pred_mv_sad[ref_frame] >> 2) > x->pred_mv_sad[i]) { - mode_skip_mask |= ref_frame_mask_fixedmv[ref_frame]; + mode_skip_mask[ref_frame] |= INTER_NEAREST_NEAR_ZERO; break; } } @@ -2653,7 +2653,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // then do nothing if the current ref frame is not allowed.. if (vp9_segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) && vp9_get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) { - mode_skip_mask |= ref_frame_mask_all[ref_frame]; + ref_frame_skip_mask[0] |= (1 << ref_frame); + ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; } } @@ -2666,12 +2667,13 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // an unfiltered alternative. We allow near/nearest as well // because they may result in zero-zero MVs but be cheaper. if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) { - mode_skip_mask = - ~((1 << THR_NEARESTA) | (1 << THR_NEARA) | (1 << THR_ZEROA)); + ref_frame_skip_mask[0] = (1 << LAST_FRAME) | (1 << GOLDEN_FRAME); + ref_frame_skip_mask[1] = SECOND_REF_FRAME_MASK; + mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO; if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0) - mode_skip_mask |= (1 << THR_NEARA); + mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV); if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0) - mode_skip_mask |= (1 << THR_NEARESTA); + mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV); } } @@ -2702,13 +2704,15 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, case INTRA_FRAME: break; case LAST_FRAME: - mode_skip_mask |= LAST_FRAME_MODE_MASK; + ref_frame_skip_mask[0] |= LAST_FRAME_MODE_MASK; + ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; break; case GOLDEN_FRAME: - mode_skip_mask |= GOLDEN_FRAME_MODE_MASK; + ref_frame_skip_mask[0] |= GOLDEN_FRAME_MODE_MASK; + ref_frame_skip_mask[1] |= SECOND_REF_FRAME_MASK; break; case ALTREF_FRAME: - mode_skip_mask |= ALT_REF_MODE_MASK; + ref_frame_skip_mask[0] |= ALT_REF_MODE_MASK; break; case NONE: case MAX_REF_FRAMES: @@ -2717,17 +2721,24 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, } } - if (cpi->sf.alt_ref_search_fp && cpi->rc.is_src_frame_alt_ref) { - mode_skip_mask = 0; - if (!(ref_frame == ALTREF_FRAME && second_ref_frame == NONE)) - continue; + if (cpi->rc.is_src_frame_alt_ref) { + if (cpi->sf.alt_ref_search_fp) { + mode_skip_mask[ALTREF_FRAME] = 0; + + if (!(ref_frame == ALTREF_FRAME && second_ref_frame == NONE)) + continue; + } } if (bsize > cpi->sf.max_intra_bsize) if (ref_frame == INTRA_FRAME) continue; - if (mode_skip_mask & (1 << mode_index)) + if (ref_frame_skip_mask[0] & (1 << ref_frame) && + ref_frame_skip_mask[1] & (1 << MAX(0, second_ref_frame))) + continue; + + if (mode_skip_mask[ref_frame] & (1 << this_mode)) continue; // Test best rd so far against threshold for trying this mode. diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index df0e0a153..d9ac12262 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -13,43 +13,6 @@ #include "vp9/encoder/vp9_encoder.h" #include "vp9/encoder/vp9_speed_features.h" -enum { - INTRA_ALL = (1 << DC_PRED) | - (1 << V_PRED) | (1 << H_PRED) | - (1 << D45_PRED) | (1 << D135_PRED) | - (1 << D117_PRED) | (1 << D153_PRED) | - (1 << D207_PRED) | (1 << D63_PRED) | - (1 << TM_PRED), - INTRA_DC = (1 << DC_PRED), - INTRA_DC_TM = (1 << DC_PRED) | (1 << TM_PRED), - INTRA_DC_H_V = (1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED), - INTRA_DC_TM_H_V = (1 << DC_PRED) | (1 << TM_PRED) | (1 << V_PRED) | - (1 << H_PRED) -}; - -enum { - INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) | (1 << NEWMV), - INTER_NEAREST = (1 << NEARESTMV), - INTER_NEAREST_NEAR_NEW = (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV) -}; - -enum { - DISABLE_ALL_INTER_SPLIT = (1 << THR_COMP_GA) | - (1 << THR_COMP_LA) | - (1 << THR_ALTR) | - (1 << THR_GOLD) | - (1 << THR_LAST), - - DISABLE_ALL_SPLIT = (1 << THR_INTRA) | DISABLE_ALL_INTER_SPLIT, - - DISABLE_COMPOUND_SPLIT = (1 << THR_COMP_GA) | (1 << THR_COMP_LA), - - LAST_AND_INTRA_SPLIT_ONLY = (1 << THR_COMP_GA) | - (1 << THR_COMP_LA) | - (1 << THR_ALTR) | - (1 << THR_GOLD) -}; - // Intra only frames, golden frames (except alt ref overlays) and // alt ref frames tend to be coded at a higher than ambient quality static int frame_is_boosted(const VP9_COMP *cpi) { diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h index 33c441f62..0f49154ff 100644 --- a/vp9/encoder/vp9_speed_features.h +++ b/vp9/encoder/vp9_speed_features.h @@ -17,6 +17,44 @@ extern "C" { #endif +enum { + INTRA_ALL = (1 << DC_PRED) | + (1 << V_PRED) | (1 << H_PRED) | + (1 << D45_PRED) | (1 << D135_PRED) | + (1 << D117_PRED) | (1 << D153_PRED) | + (1 << D207_PRED) | (1 << D63_PRED) | + (1 << TM_PRED), + INTRA_DC = (1 << DC_PRED), + INTRA_DC_TM = (1 << DC_PRED) | (1 << TM_PRED), + INTRA_DC_H_V = (1 << DC_PRED) | (1 << V_PRED) | (1 << H_PRED), + INTRA_DC_TM_H_V = (1 << DC_PRED) | (1 << TM_PRED) | (1 << V_PRED) | + (1 << H_PRED) +}; + +enum { + INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) | (1 << NEWMV), + INTER_NEAREST = (1 << NEARESTMV), + INTER_NEAREST_NEAR_NEW = (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV), + INTER_NEAREST_NEAR_ZERO = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV), +}; + +enum { + DISABLE_ALL_INTER_SPLIT = (1 << THR_COMP_GA) | + (1 << THR_COMP_LA) | + (1 << THR_ALTR) | + (1 << THR_GOLD) | + (1 << THR_LAST), + + DISABLE_ALL_SPLIT = (1 << THR_INTRA) | DISABLE_ALL_INTER_SPLIT, + + DISABLE_COMPOUND_SPLIT = (1 << THR_COMP_GA) | (1 << THR_COMP_LA), + + LAST_AND_INTRA_SPLIT_ONLY = (1 << THR_COMP_GA) | + (1 << THR_COMP_LA) | + (1 << THR_ALTR) | + (1 << THR_GOLD) +}; + typedef enum { DIAMOND = 0, NSTEP = 1, -- cgit v1.2.3