diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index d6882d5859f16c015d4767fefafbe686fb7bc44f..4b49b17a29661cd1b1f7f7fd477a945d8a242499 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -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]; diff --git a/vp9/encoder/vp9_encodemv.c b/vp9/encoder/vp9_encodemv.c index 500f57442e68e9496574efb053786c716c96b133..7c6f292d5ff6abe239e515b4b00373266062d3a2 100644 --- a/vp9/encoder/vp9_encodemv.c +++ b/vp9/encoder/vp9_encodemv.c @@ -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); } } diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index 2afcd27b1a43e1f4d0729331f85d8730944f14b9..548f70baa31a4d88e20d60e5eec8a170955ad0ae 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -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) { diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 19b1e3af5484f65000bd2098694c73e6bde191df..113e0343dd1384acc5bb954c23dfe891b21974b7 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -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; diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index a0c64beb515249645c7d6f5caac1be94bcfa05b1..a2ecafacc40d973831bf9a52db8a4b9a1d76606a 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -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;