sf->adjust_partitioning_from_last_frame = 0;
sf->last_partitioning_redo_frequency = 4;
sf->disable_splitmv = 0;
- sf->conditional_oblique_intramodes = 0;
+ sf->mode_search_skip_flags = 0;
// Skip any mode not chosen at size < X for all sizes > X
// Hence BLOCK_SIZE_SB64X64 (skip is off)
cpi->common.show_frame == 0) ?
USE_FULL_RD :
USE_LARGESTALL);
- sf->conditional_oblique_intramodes = 1;
- sf->disable_splitmv =
- (MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
sf->use_square_partition_only = !(cpi->common.frame_type == KEY_FRAME ||
cpi->common.intra_only ||
cpi->common.show_frame == 0);
+ sf->disable_splitmv =
+ (MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
sf->unused_mode_skip_lvl = BLOCK_SIZE_SB32X32;
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
+ FLAG_SKIP_INTRA_BESTINTER |
+ FLAG_SKIP_COMP_BESTINTRA;
}
if (speed == 2) {
sf->adjust_thresholds_by_speed = 1;
sf->use_lastframe_partitioning = 1;
sf->adjust_partitioning_from_last_frame = 1;
sf->last_partitioning_redo_frequency = 3;
- sf->tx_size_search_method = USE_LARGESTALL;
- sf->conditional_oblique_intramodes = 1;
sf->unused_mode_skip_lvl = BLOCK_SIZE_SB32X32;
sf->reduce_first_step_size = 1;
sf->optimize_coefficients = 0;
// sf->reference_masking = 1;
+ sf->tx_size_search_method = ((cpi->common.frame_type == KEY_FRAME ||
+ cpi->common.intra_only ||
+ cpi->common.show_frame == 0) ?
+ USE_FULL_RD :
+ USE_LARGESTALL);
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
+ FLAG_SKIP_INTRA_BESTINTER |
+ FLAG_SKIP_COMP_BESTINTRA |
+ FLAG_SKIP_COMP_REFMISMATCH;
}
if (speed == 3) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
USE_FULL_RD :
USE_LARGESTALL);
sf->reduce_first_step_size = 1;
- sf->conditional_oblique_intramodes = 1;
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
+ FLAG_SKIP_INTRA_BESTINTER |
+ FLAG_SKIP_COMP_BESTINTRA |
+ FLAG_SKIP_COMP_REFMISMATCH;
}
if (speed == 4) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
cpi->common.show_frame == 0) ?
USE_FULL_RD :
USE_LARGESTALL);
- sf->conditional_oblique_intramodes = 1;
+ sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
+ FLAG_SKIP_INTRA_BESTINTER |
+ FLAG_SKIP_COMP_BESTINTRA |
+ FLAG_SKIP_COMP_REFMISMATCH;
}
/*
if (speed == 2) {
USE_LARGESTALL
} TX_SIZE_SEARCH_METHOD;
+typedef enum {
+ // Values should be powers of 2 so that they can be selected as bits of
+ // an integer flags field
+
+ // terminate search early based on distortion so far compared to
+ // qp step, distortion in the neighborhood of the frame, etc.
+ FLAG_EARLY_TERMINATE = 1,
+
+ // skips comp inter modes if the best so far is an intra mode
+ FLAG_SKIP_COMP_BESTINTRA = 2,
+
+ // skips comp inter modes if the best single intermode so far does
+ // not have the same reference as one of the two references being
+ // tested
+ FLAG_SKIP_COMP_REFMISMATCH = 4,
+
+ // skips oblique intra modes if the best so far is an inter mode
+ FLAG_SKIP_INTRA_BESTINTER = 8,
+
+ // skips oblique intra modes at angles 27, 63, 117, 153 if the best
+ // intra so far is not one of the neighboring directions
+ FLAG_SKIP_INTRA_DIRMISMATCH = 16,
+} MODE_SEARCH_SKIP_LOGIC;
+
typedef struct {
int RD;
SEARCH_METHODS search_method;
int adjust_partitioning_from_last_frame;
int last_partitioning_redo_frequency;
int disable_splitmv;
- // Search the D27, D63, D117 and D153 modes
- // only if the best intra mode so far is one
- // of the two directional modes nearest to each.
- int conditional_oblique_intramodes;
+
+ // Implements various heuristics to skip searching modes
+ // The heuristics selected are based on flags
+ // defined in the MODE_SEARCH_SKIP_HEURISTICS enum
+ unsigned int mode_search_skip_flags;
} SPEED_FEATURES;
enum BlockSize {
*psse = sse[mbmi->txfm_size];
}
-static int conditional_skip(MB_PREDICTION_MODE mode,
- MB_PREDICTION_MODE best_intra_mode) {
+static int conditional_skipintra(MB_PREDICTION_MODE mode,
+ MB_PREDICTION_MODE best_intra_mode) {
if (mode == D117_PRED &&
best_intra_mode != V_PRED &&
best_intra_mode != D135_PRED)
int ratey = 0;
// Only do the oblique modes if the best so far is
// one of the neighboring directional modes
- if (cpi->sf.conditional_oblique_intramodes) {
- if (conditional_skip(mode, *best_mode))
+ if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
+ if (conditional_skipintra(mode, *best_mode))
continue;
}
vp9_prob comp_mode_p;
int64_t best_overall_rd = INT64_MAX;
int64_t best_intra_rd = INT64_MAX;
+ int64_t best_inter_rd = INT64_MAX;
MB_PREDICTION_MODE best_intra_mode = DC_PRED;
+ // MB_PREDICTION_MODE best_inter_mode = ZEROMV;
+ MV_REFERENCE_FRAME best_inter_ref_frame = LAST_FRAME;
INTERPOLATIONFILTERTYPE best_filter = SWITCHABLE;
INTERPOLATIONFILTERTYPE tmp_best_filter = SWITCHABLE;
int rate_uv_intra[TX_SIZE_MAX_SB], rate_uv_tokenonly[TX_SIZE_MAX_SB];
int i;
int this_skip2 = 0;
int64_t total_sse = INT_MAX;
+ int early_term = 0;
for (i = 0; i < NB_TXFM_MODES; ++i)
txfm_cache[i] = INT64_MAX;
continue;
}
+ comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
+ if (comp_pred) {
+ if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
+ if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME)
+ continue;
+ if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
+ if (vp9_mode_order[mode_index].ref_frame != best_inter_ref_frame &&
+ vp9_mode_order[mode_index].second_ref_frame != best_inter_ref_frame)
+ continue;
+ }
// TODO(jingning, jkoleszar): scaling reference frame not supported for
// SPLITMV.
if (mbmi->ref_frame[0] > 0 &&
set_scale_factors(xd, mbmi->ref_frame[0], mbmi->ref_frame[1],
scale_factor);
- comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
mbmi->mode = this_mode;
mbmi->uv_mode = DC_PRED;
if (this_mode == I4X4_PRED) {
int rate;
+ /*
+ if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
+ (vp9_mode_order[best_mode_index].ref_frame > INTRA_FRAME))
+ continue;
+ */
+
mbmi->txfm_size = TX_4X4;
rd_pick_intra4x4mby_modes(cpi, x, &rate, &rate_y,
&distortion_y, INT64_MAX);
TX_SIZE uv_tx;
// Only search the oblique modes if the best so far is
// one of the neighboring directional modes
- if (cpi->sf.conditional_oblique_intramodes) {
- if (conditional_skip(mbmi->mode, best_intra_mode))
+ if ((cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
+ (this_mode >= D45_PRED && this_mode <= TM_PRED)) {
+ if (vp9_mode_order[best_mode_index].ref_frame > INTRA_FRAME)
+ continue;
+ }
+ if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
+ if (conditional_skipintra(mbmi->mode, best_intra_mode))
continue;
}
super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable, NULL,
PARTITION_INFO tmp_best_partition;
int pred_exists = 0;
int uv_skippable;
+ if (is_comp_pred) {
+ if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA)
+ if (vp9_mode_order[best_mode_index].ref_frame == INTRA_FRAME)
+ continue;
+ if (cpi->sf.mode_search_skip_flags & FLAG_SKIP_COMP_REFMISMATCH)
+ if (vp9_mode_order[mode_index].ref_frame != best_inter_ref_frame &&
+ vp9_mode_order[mode_index].second_ref_frame !=
+ best_inter_ref_frame)
+ continue;
+ }
this_rd_thresh = (mbmi->ref_frame[0] == LAST_FRAME) ?
cpi->rd_threshes[bsize][THR_NEWMV] :
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
}
- // Keep record of best intra distortion
+ // Keep record of best intra rd
if (xd->mode_info_context->mbmi.ref_frame[0] == INTRA_FRAME &&
xd->mode_info_context->mbmi.mode <= TM_PRED &&
this_rd < best_intra_rd) {
best_intra_rd = this_rd;
best_intra_mode = xd->mode_info_context->mbmi.mode;
}
+ // Keep record of best inter rd with single reference
+ if (xd->mode_info_context->mbmi.ref_frame[0] > INTRA_FRAME &&
+ xd->mode_info_context->mbmi.ref_frame[1] == NONE &&
+ !mode_excluded &&
+ this_rd < best_inter_rd) {
+ best_inter_rd = this_rd;
+ best_inter_ref_frame = ref_frame;
+ // best_inter_mode = xd->mode_info_context->mbmi.mode;
+ }
if (!disable_skip && mbmi->ref_frame[0] == INTRA_FRAME)
for (i = 0; i < NB_PREDICTION_TYPES; ++i)
if (this_rd < best_rd || x->skip) {
if (!mode_excluded) {
// Note index of best mode so far
+ const int qstep = xd->plane[0].dequant[1];
+
best_mode_index = mode_index;
if (ref_frame == INTRA_FRAME) {
if (this_mode == I4X4_PRED || this_mode == SPLITMV)
for (i = 0; i < 4; i++)
best_bmodes[i] = xd->mode_info_context->bmi[i];
+
+ // TODO(debargha): enhance this test with a better distortion prediction
+ // based on qp, activity mask and history
+ if (cpi->sf.mode_search_skip_flags & FLAG_EARLY_TERMINATE)
+ if (ref_frame > INTRA_FRAME && distortion2 * 4 < qstep * qstep)
+ early_term = 1;
}
#if 0
// Testing this mode gave rise to an improvement in best error score.
}
}
+ if (early_term)
+ break;
+
if (x->skip && !mode_excluded)
break;
}