Reworked the auto_mv_step_size speed feature

This patch modifies the auto_mv_step_size speed feature to
use a combination of the maximum magnitude mv from the last
inter frame, and the maximum magnitude mv for the two reference
mvs with the same reference. For arf frames, the max mav step
for the resolution is used.
The bounds therefore are slightly tighter. The feature is made
a speed 1 feature.

Rebased.

Results (when this feature is turned on over speed 0):
derfraw300: -0.046% psnr, about 5+% speedup
(tested on football: goes from 4m30.760s to 4m17.410s).

Change-Id: If492797a61b0b4b3e58c0b8f86afb880165fc9f6
This commit is contained in:
Deb Mukherjee 2013-07-12 09:52:24 -07:00
parent 97dbee00dd
commit 302698fb12
5 changed files with 56 additions and 17 deletions

View File

@ -96,6 +96,7 @@ struct macroblock {
signed int act_zbin_adj;
int mv_best_ref_index[MAX_REF_FRAMES];
unsigned int max_mv_context[MAX_REF_FRAMES];
int nmvjointcost[MV_JOINTS];
int nmvcosts[2][MV_VALS];

View File

@ -486,11 +486,11 @@ void vp9_encode_mv(VP9_COMP* cpi, vp9_writer* w,
if (mv_joint_horizontal(j))
encode_mv_component(w, diff.col, &mvctx->comps[1], usehp);
// If auto_mv_step_size is enabled and it is an arf/non shown frame
// then keep track of the largest motion vector component used.
if (cpi->sf.auto_mv_step_size && !cpi->common.show_frame) {
cpi->max_mv_magnitude = MAX((MAX(abs(mv->row), abs(mv->col)) >> 3),
cpi->max_mv_magnitude);
// If auto_mv_step_size is enabled then keep track of the largest
// motion vector component used.
if (!cpi->dummy_packing && cpi->sf.auto_mv_step_size) {
unsigned int maxv = MAX(abs(mv->row), abs(mv->col)) >> 3;
cpi->max_mv_magnitude = MAX(maxv, cpi->max_mv_magnitude);
}
}

View File

@ -680,12 +680,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
cpi->mode_chosen_counts[i] = 0;
}
// Initialize cpi->max_mv_magnitude if appropriate.
if ((cpi->common.frame_type == KEY_FRAME) || cpi->common.intra_only ||
(cpi->common.show_frame == 0)) {
cpi->max_mv_magnitude = 0;
}
// best quality defaults
sf->RD = 1;
sf->search_method = NSTEP;
@ -747,7 +741,6 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
#else
sf->static_segmentation = 0;
#endif
sf->auto_mv_step_size = 1;
sf->use_avoid_tested_higherror = 1;
sf->adaptive_rd_thresh = 1;
sf->last_chroma_intra_mode = TM_PRED;
@ -772,6 +765,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->last_chroma_intra_mode = H_PRED;
sf->use_rd_breakout = 1;
sf->skip_encode_sb = 1;
sf->auto_mv_step_size = 1;
}
if (speed == 2) {
sf->adjust_thresholds_by_speed = 1;
@ -798,6 +792,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->using_small_partition_info = 1;
sf->disable_splitmv =
(MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
sf->auto_mv_step_size = 1;
}
if (speed == 3) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
@ -814,6 +809,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_rd_breakout = 1;
sf->skip_encode_sb = 1;
sf->disable_splitmv = 1;
sf->auto_mv_step_size = 1;
}
if (speed == 4) {
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_TYPES;
@ -830,6 +826,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
FLAG_SKIP_COMP_REFMISMATCH;
sf->use_rd_breakout = 1;
sf->optimize_coefficients = 0;
sf->auto_mv_step_size = 1;
// sf->reduce_first_step_size = 1;
// sf->reference_masking = 1;
@ -2489,6 +2486,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
int undershoot_seen = 0;
SPEED_FEATURES *sf = &cpi->sf;
unsigned int max_mv_def = MIN(cpi->common.width, cpi->common.height);
#if RESET_FOREACH_FILTER
int q_low0;
int q_high0;
@ -2561,6 +2559,24 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Set default state for segment based loop filter update flags
xd->mode_ref_lf_delta_update = 0;
// Initialize cpi->mv_step_param to default based on max resolution
cpi->mv_step_param = vp9_init_search_range(cpi, max_mv_def);
// Initialize cpi->max_mv_magnitude and cpi->mv_step_param if appropriate.
if (sf->auto_mv_step_size) {
if ((cpi->common.frame_type == KEY_FRAME) || cpi->common.intra_only) {
// initialize max_mv_magnitude for use in the first INTER frame
// after a key/intra-only frame
cpi->max_mv_magnitude = max_mv_def;
} else {
if (cm->show_frame)
// allow mv_steps to correspond to twice the max mv magnitude found
// in the previous frame, capped by the default max_mv_magnitude based
// on resolution
cpi->mv_step_param = vp9_init_search_range(
cpi, MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
cpi->max_mv_magnitude = 0;
}
}
// Set various flags etc to special state if it is a key frame
if (cm->frame_type == KEY_FRAME) {

View File

@ -505,6 +505,7 @@ typedef struct VP9_COMP {
int error_bins[1024];
unsigned int max_mv_magnitude;
int mv_step_param;
// Data used for real time conferencing mode to help determine if it would be good to update the gf
int inter_zz_count;

View File

@ -1940,9 +1940,24 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
if (i == 2)
bsi->mvp.as_int =
x->e_mbd.mode_info_context->bmi[i - 2].as_mv[0].as_int;
step_param = 2;
}
}
if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
// Take wtd average of the step_params based on the last frame's
// max mv magnitude and the best ref mvs of the current block for
// the given reference.
if (i == 0)
step_param = (vp9_init_search_range(
cpi, x->max_mv_context[mbmi->ref_frame[0]]) +
cpi->mv_step_param) >> 1;
else
step_param = (vp9_init_search_range(
cpi, MAX(abs(bsi->mvp.as_mv.row),
abs(bsi->mvp.as_mv.col)) >> 3) +
cpi->mv_step_param) >> 1;
} else {
step_param = cpi->mv_step_param;
}
further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
@ -2163,6 +2178,7 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
int best_index = 0;
int best_sad = INT_MAX;
int this_sad = INT_MAX;
unsigned int max_mv = 0;
uint8_t *src_y_ptr = x->plane[0].src.buf;
uint8_t *ref_y_ptr;
@ -2172,6 +2188,8 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x,
for (i = 0; i < MAX_MV_REF_CANDIDATES; i++) {
this_mv.as_int = mbmi->ref_mvs[ref_frame][i].as_int;
max_mv = MAX(max_mv,
MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3);
// The list is at an end if we see 0 for a second time.
if (!this_mv.as_int && zero_seen)
break;
@ -2195,6 +2213,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;
}
static void estimate_ref_frame_costs(VP9_COMP *cpi, int segment_id,
@ -2441,12 +2460,14 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
// Work out the size of the first step in the mv step search.
// 0 here is maximum length first step. 1 is MAX >> 1 etc.
if (cpi->sf.auto_mv_step_size && cpi->common.show_frame) {
step_param = vp9_init_search_range(cpi, cpi->max_mv_magnitude);
// Take wtd average of the step_params based on the last frame's
// max mv magnitude and that based on the best ref mvs of the current
// block for the given reference.
step_param = (vp9_init_search_range(cpi, x->max_mv_context[ref]) +
cpi->mv_step_param) >> 1;
} else {
step_param = vp9_init_search_range(
cpi, MIN(cpi->common.width, cpi->common.height));
step_param = cpi->mv_step_param;
}
// mvp_full.as_int = ref_mv[0].as_int;
mvp_full.as_int =
mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_int;