Merge "vp9_pick_inter_mode(): Use single loop to evaluate inter modes"

This commit is contained in:
Yaowu Xu 2015-03-12 18:43:23 -07:00 committed by Gerrit Code Review
commit 1aa75c65cc

View File

@ -602,13 +602,27 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
*rd_cost = best_rdc; *rd_cost = best_rdc;
} }
static const PREDICTION_MODE inter_mode_set[INTER_MODES] = {
ZEROMV, NEARESTMV, NEARMV, NEWMV,
};
static const int ref_frame_cost[MAX_REF_FRAMES] = { static const int ref_frame_cost[MAX_REF_FRAMES] = {
1235, 229, 530, 615, 1235, 229, 530, 615,
}; };
typedef struct {
MV_REFERENCE_FRAME ref_frame;
PREDICTION_MODE pred_mode;
} REF_MODE;
#define RT_INTER_MODES 8
static const REF_MODE ref_mode_set[RT_INTER_MODES] = {
{LAST_FRAME, ZEROMV},
{LAST_FRAME, NEARESTMV},
{LAST_FRAME, NEARMV},
{LAST_FRAME, NEWMV},
{GOLDEN_FRAME, ZEROMV},
{GOLDEN_FRAME, NEARESTMV},
{GOLDEN_FRAME, NEARMV},
{GOLDEN_FRAME, NEWMV}
};
// TODO(jingning) placeholder for inter-frame non-RD mode decision. // TODO(jingning) placeholder for inter-frame non-RD mode decision.
// this needs various further optimizations. to be continued.. // this needs various further optimizations. to be continued..
void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
@ -665,6 +679,7 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
const int pixels_in_block = bh * bw; const int pixels_in_block = bh * bw;
int reuse_inter_pred = cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready; int reuse_inter_pred = cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready;
int ref_frame_skip_mask = 0; int ref_frame_skip_mask = 0;
int idx;
if (reuse_inter_pred) { if (reuse_inter_pred) {
int i; int i;
@ -748,9 +763,17 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
if (cpi->rc.frames_since_golden == 0) if (cpi->rc.frames_since_golden == 0)
ref_frame_skip_mask |= (1 << GOLDEN_FRAME); ref_frame_skip_mask |= (1 << GOLDEN_FRAME);
for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) { for (idx = 0; idx < RT_INTER_MODES; ++idx) {
PREDICTION_MODE this_mode; int rate_mv = 0;
int i = (ref_frame == LAST_FRAME) ? GOLDEN_FRAME : LAST_FRAME; int mode_rd_thresh;
int mode_index;
int i;
PREDICTION_MODE this_mode = ref_mode_set[idx].pred_mode;
ref_frame = ref_mode_set[idx].ref_frame;
mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
i = (ref_frame == LAST_FRAME) ? GOLDEN_FRAME : LAST_FRAME;
if (!(cpi->ref_frame_flags & flag_list[ref_frame])) if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
continue; continue;
@ -772,30 +795,22 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
mbmi->ref_frame[0] = ref_frame; mbmi->ref_frame[0] = ref_frame;
set_ref_ptrs(cm, xd, ref_frame, NONE); set_ref_ptrs(cm, xd, ref_frame, NONE);
for (i = 0; i < INTER_MODES; ++i) {
int rate_mv = 0;
int mode_rd_thresh;
int mode_index;
this_mode = inter_mode_set[i];
mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
if (const_motion[ref_frame] && this_mode == NEARMV) if (const_motion[ref_frame] && this_mode == NEARMV)
continue; continue;
if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode))) if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode)))
continue; continue;
mode_rd_thresh = best_mode_skip_txfm ? rd_threshes[mode_index] << 1 : mode_rd_thresh = best_mode_skip_txfm ?
rd_threshes[mode_index]; rd_threshes[mode_index] << 1 : rd_threshes[mode_index];
if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh, if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
rd_thresh_freq_fact[mode_index])) rd_thresh_freq_fact[mode_index]))
continue; continue;
if (this_mode == NEWMV) { if (this_mode == NEWMV) {
if (cpi->sf.partition_search_type != VAR_BASED_PARTITION && if (cpi->sf.partition_search_type != VAR_BASED_PARTITION
best_rdc.rdcost < (int64_t)(1 << num_pels_log2_lookup[bsize])) && best_rdc.rdcost < (int64_t) (1 << num_pels_log2_lookup[bsize]))
continue; continue;
if (ref_frame > LAST_FRAME) { if (ref_frame > LAST_FRAME) {
int tmp_sad; int tmp_sad;
int dis, cost_list[5]; int dis, cost_list[5];
@ -825,14 +840,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
x->nmvjointcost, x->mvcost, &dis, x->nmvjointcost, x->mvcost, &dis,
&x->pred_sse[ref_frame], NULL, 0, 0); &x->pred_sse[ref_frame], NULL, 0, 0);
} else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col, } else if (!combined_motion_search(cpi, x, bsize, mi_row, mi_col,
&frame_mv[NEWMV][ref_frame], &frame_mv[NEWMV][ref_frame], &rate_mv, best_rdc.rdcost)) {
&rate_mv, best_rdc.rdcost)) {
continue; continue;
} }
} }
if (this_mode != NEARESTMV && if (this_mode != NEARESTMV && frame_mv[this_mode][ref_frame].as_int ==
frame_mv[this_mode][ref_frame].as_int ==
frame_mv[NEARESTMV][ref_frame].as_int) frame_mv[NEARESTMV][ref_frame].as_int)
continue; continue;
@ -852,10 +865,9 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
} }
} }
if ((this_mode == NEWMV || filter_ref == SWITCHABLE) && if ((this_mode == NEWMV || filter_ref == SWITCHABLE) && pred_filter_search
pred_filter_search && (ref_frame == LAST_FRAME) && && (ref_frame == LAST_FRAME)
((mbmi->mv[0].as_mv.row & 0x07) != 0 || && (((mbmi->mv[0].as_mv.row | mbmi->mv[0].as_mv.col) & 0x07) != 0)) {
(mbmi->mv[0].as_mv.col & 0x07) != 0)) {
int pf_rate[3]; int pf_rate[3];
int64_t pf_dist[3]; int64_t pf_dist[3];
unsigned int pf_var[3]; unsigned int pf_var[3];
@ -869,8 +881,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
int64_t cost; int64_t cost;
mbmi->interp_filter = filter; mbmi->interp_filter = filter;
vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter], model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter], &pf_dist[filter],
&pf_dist[filter], &pf_var[filter], &pf_sse[filter]); &pf_var[filter], &pf_sse[filter]);
pf_rate[filter] += vp9_get_switchable_rate(cpi, xd); pf_rate[filter] += vp9_get_switchable_rate(cpi, xd);
cost = RDCOST(x->rdmult, x->rddiv, pf_rate[filter], pf_dist[filter]); cost = RDCOST(x->rdmult, x->rddiv, pf_rate[filter], pf_dist[filter]);
pf_tx_size[filter] = mbmi->tx_size; pf_tx_size[filter] = mbmi->tx_size;
@ -905,11 +917,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
sse_y = pf_sse[mbmi->interp_filter]; sse_y = pf_sse[mbmi->interp_filter];
x->skip_txfm[0] = skip_txfm; x->skip_txfm[0] = skip_txfm;
} else { } else {
mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP: filter_ref; mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP : filter_ref;
vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize); vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist, model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
&var_y, &sse_y); &var_y, &sse_y);
this_rdc.rate += cm->interp_filter == SWITCHABLE ? this_rdc.rate +=
cm->interp_filter == SWITCHABLE ?
vp9_get_switchable_rate(cpi, xd) : 0; vp9_get_switchable_rate(cpi, xd) : 0;
} }
@ -921,29 +934,28 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 1); vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 1);
if (x->color_sensitivity[1]) if (x->color_sensitivity[1])
vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 2); vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 2);
model_rd_for_sb_uv(cpi, bsize, x, xd, &uv_rate, &uv_dist, model_rd_for_sb_uv(cpi, bsize, x, xd, &uv_rate, &uv_dist, &var_y, &sse_y);
&var_y, &sse_y);
this_rdc.rate += uv_rate; this_rdc.rate += uv_rate;
this_rdc.dist += uv_dist; this_rdc.dist += uv_dist;
} }
this_rdc.rate += rate_mv; this_rdc.rate += rate_mv;
this_rdc.rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]] this_rdc.rate +=
[INTER_OFFSET(this_mode)]; cpi->inter_mode_cost[mbmi->mode_context[ref_frame]][INTER_OFFSET(
this_mode)];
this_rdc.rate += ref_frame_cost[ref_frame]; this_rdc.rate += ref_frame_cost[ref_frame];
this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
this_rdc.rate, this_rdc.dist);
// Skipping checking: test to see if this block can be reconstructed by // Skipping checking: test to see if this block can be reconstructed by
// prediction only. // prediction only.
if (cpi->allow_encode_breakout) { if (cpi->allow_encode_breakout) {
encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame, encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame, this_mode,
this_mode, var_y, sse_y, yv12_mb, var_y, sse_y, yv12_mb, &this_rdc.rate,
&this_rdc.rate, &this_rdc.dist); &this_rdc.dist);
if (x->skip) { if (x->skip) {
this_rdc.rate += rate_mv; this_rdc.rate += rate_mv;
this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate,
this_rdc.rate, this_rdc.dist); this_rdc.dist);
} }
} }
@ -975,13 +987,6 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
break; break;
} }
// Check that a prediction mode has been selected.
assert(best_rdc.rdcost < INT64_MAX);
if (x->skip)
break;
}
mbmi->mode = best_mode; mbmi->mode = best_mode;
mbmi->interp_filter = best_pred_filter; mbmi->interp_filter = best_pred_filter;
mbmi->tx_size = best_tx_size; mbmi->tx_size = best_tx_size;