ref: a4ce53f14d25ffea989fc83ee7f039762a142c83
parent: 87440aeb820ac547e2bf6ff1fc3d483b57461d78
author: Jingning Han <[email protected]>
date: Fri Dec 20 10:24:22 EST 2013
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
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -118,7 +118,8 @@
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];
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -417,6 +417,8 @@
// 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 @@
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 @@
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 @@
// 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 @@
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 @@
&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 @@
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 @@
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 @@
&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 @@
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 @@
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 @@
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 @@
}
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,