Commit a4ce53f1 authored by Jingning Han's avatar Jingning Han
Browse files

Adaptive motion control on ref and search range

This commit takes a preliminary attempt to refine the motion search
control. It detects the SAD associated with mv predictor per reference
frame, and based on which to determine whether the encoder wants to
reduce the motion search range (if the predicted mv provides fairly
small SAD), or to skip the current reference frame (if there exists
another ref frame that gives much smaller SAD cost).

This feature is turned on in the settings of speed 1 and above.

In speed 1, compression performance changed
derf  -0.018%
yt    -0.043%
hd    -0.045%
stdhd -0.281%

speed-up
pedestrian_area_1080p at 4000 kbps 100 frames
199651ms -> 188846ms (5.5% speed-up)
blue_sky_1080p at 6000 kbps
443531ms -> 415239ms (6.3% speed-up)

In speed 2, compression performance changed
derf  -0.026%
yt    -0.090%
hd    -0.055%
stdhd -0.210%

speed-up
pedstrian 113949ms -> 108855ms (4.5% speed-up)
blue_sky  271057ms -> 257322ms (5% speed-up)

Change-Id: I1b74ea28278c94fea329d971d706d573983d810d
parent 87440aeb
......@@ -118,7 +118,8 @@ struct macroblock {
int mv_best_ref_index[MAX_REF_FRAMES];
unsigned int max_mv_context[MAX_REF_FRAMES];
unsigned int source_variance;
unsigned int pred_sse;
unsigned int pred_sse[MAX_REF_FRAMES];
int pred_mv_sad[MAX_REF_FRAMES];
int nmvjointcost[MV_JOINTS];
int nmvcosts[2][MV_VALS];
......
......@@ -417,6 +417,8 @@ static void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize,
// Hence quantizer step is also 8 times. To get effective quantizer
// we need to divide by 8 before sending to modeling function.
int i, rate_sum = 0, dist_sum = 0;
int ref = xd->mi_8x8[0]->mbmi.ref_frame[0];
unsigned int sse;
for (i = 0; i < MAX_MB_PLANE; ++i) {
struct macroblock_plane *const p = &x->plane[i];
......@@ -425,9 +427,11 @@ static void model_rd_for_sb(VP9_COMP *cpi, BLOCK_SIZE bsize,
int rate;
int64_t dist;
(void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
pd->dst.buf, pd->dst.stride, &x->pred_sse);
pd->dst.buf, pd->dst.stride, &sse);
if (i == 0)
x->pred_sse[ref] = sse;
// sse works better than var, since there is no dc prediction used
model_rd_from_var_lapndz(x->pred_sse, 1 << num_pels_log2_lookup[bs],
model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
pd->dequant[1] >> 3, &rate, &dist);
rate_sum += rate;
......@@ -1839,7 +1843,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
x->errorperbit, v_fn_ptr,
0, cpi->sf.subpel_iters_per_step,
x->nmvjointcost, x->mvcost,
&distortion, &x->pred_sse);
&distortion,
&x->pred_sse[mbmi->ref_frame[0]]);
// save motion search result for use in compound prediction
seg_mvs[i][mbmi->ref_frame[0]].as_int = mode_mv[NEWMV].as_int;
......@@ -2134,6 +2139,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
// Note the index of the mv that worked best in the reference list.
x->mv_best_ref_index[ref_frame] = best_index;
x->max_mv_context[ref_frame] = max_mv;
x->pred_mv_sad[ref_frame] = best_sad;
}
static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
......@@ -2381,6 +2387,30 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
step_param = MAX(step_param, boffset);
}
if (cpi->sf.adaptive_motion_search) {
int bwl = b_width_log2_lookup[bsize];
int bhl = b_height_log2_lookup[bsize];
int i;
int tlevel = x->pred_mv_sad[ref] >> (bwl + bhl + 4);
if (tlevel < 5)
step_param += 2;
for (i = LAST_FRAME; i <= ALTREF_FRAME && cpi->common.show_frame; ++i) {
if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
x->pred_mv[ref].as_int = 0;
tmp_mv->as_int = INVALID_MV;
if (scaled_ref_frame) {
int i;
for (i = 0; i < MAX_MB_PLANE; i++)
xd->plane[i].pre[0] = backup_yv12[i];
}
return;
}
}
}
mvp_full.as_int = x->mv_best_ref_index[ref] < MAX_MV_REF_CANDIDATES ?
mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int :
x->pred_mv[ref].as_int;
......@@ -2429,7 +2459,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
&cpi->fn_ptr[bsize],
0, cpi->sf.subpel_iters_per_step,
x->nmvjointcost, x->mvcost,
&dis, &x->pred_sse);
&dis, &x->pred_sse[ref]);
}
*rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv,
x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
......@@ -2491,7 +2521,6 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
for (ite = 0; ite < 4; ite++) {
struct buf_2d ref_yv12[2];
int bestsme = INT_MAX;
unsigned int bestsse = INT_MAX;
int sadpb = x->sadperbit16;
int_mv tmp_mv;
int search_range = 3;
......@@ -2542,6 +2571,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
if (bestsme < INT_MAX) {
int dis; /* TODO: use dis in distortion calculation later. */
unsigned int sse;
bestsme = cpi->find_fractional_mv_step_comp(
x, &tmp_mv.as_mv,
&ref_mv[id].as_mv,
......@@ -2550,7 +2580,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
&cpi->fn_ptr[bsize],
0, cpi->sf.subpel_iters_per_step,
x->nmvjointcost, x->mvcost,
&dis, &bestsse, second_pred,
&dis, &sse, second_pred,
pw, ph);
}
......@@ -2560,7 +2590,6 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
if (bestsme < last_besterr[id]) {
frame_mv[refs[id]].as_int = tmp_mv.as_int;
last_besterr[id] = bestsme;
x->pred_sse = bestsse;
} else {
break;
}
......@@ -2852,7 +2881,6 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
}
if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
int tmp_rate;
int64_t tmp_dist;
......@@ -3147,6 +3175,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
best_filter_rd[i] = INT64_MAX;
for (i = 0; i < TX_SIZES; i++)
rate_uv_intra[i] = INT_MAX;
for (i = 0; i < MAX_REF_FRAMES; ++i)
x->pred_sse[i] = INT_MAX;
*returnrate = INT_MAX;
......@@ -3184,6 +3214,7 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
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, idx_list[ref_frame], ref_frame,
block_size, mi_row, mi_col,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment