Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 46 additions & 17 deletions av2/encoder/mcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4719,13 +4719,25 @@ static const warp_search_config warp_search_info[WARP_SEARCH_METHODS] = {
},
};

// Checks if the warped motion vector refinement search can be terminated early.
static AVM_INLINE bool early_terminate_refine_warped_mv(
uint64_t best_rd, uint64_t best_rd_prev, bool center_best_so_far,
bool do_early_terminate) {
if (center_best_so_far) return true;

if (do_early_terminate && (best_rd > 0.95 * best_rd_prev)) return true;

return false;
}

Comment thread
urvangjoshi marked this conversation as resolved.
// Refines MV in a small range
unsigned int av2_refine_warped_mv(MACROBLOCKD *xd, const AV2_COMMON *const cm,
const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
BLOCK_SIZE bsize, const int *pts0,
const int *pts_inref0, int total_samples,
int8_t ref, WARP_SEARCH_METHOD search_method,
int num_iterations) {
int num_iterations,
bool warp_mv_refine_early_term) {
MB_MODE_INFO *mbmi = xd->mi[0];

const MV *neighbors = warp_search_info[search_method].neighbors;
Expand All @@ -4752,6 +4764,7 @@ unsigned int av2_refine_warped_mv(MACROBLOCKD *xd, const AV2_COMMON *const cm,

// First iteration always scans all neighbors
uint8_t valid_neighbors = UINT8_MAX;
unsigned int bestmse_prev = bestmse;

for (int ite = 0; ite < num_iterations; ++ite) {
int best_idx = -1;
Expand Down Expand Up @@ -4792,13 +4805,17 @@ unsigned int av2_refine_warped_mv(MACROBLOCKD *xd, const AV2_COMMON *const cm,
}
}

if (best_idx == -1) break;

if (best_idx >= 0) {
best_mv->row += neighbors[best_idx].row * (1 << mv_shift);
best_mv->col += neighbors[best_idx].col * (1 << mv_shift);
valid_neighbors = neighbor_mask[best_idx];
}

if (early_terminate_refine_warped_mv(
bestmse, bestmse_prev, (best_idx == -1), warp_mv_refine_early_term))
break;

bestmse_prev = bestmse;
}

mbmi->wm_params[ref] = best_wm_params;
Expand Down Expand Up @@ -5356,7 +5373,7 @@ int av2_pick_warp_delta(
if (!fast_decoupled_search) {
uint64_t best_rd_prev = best_rd;
for (int iter = 0; iter < number_of_iterations; iter++) {
int center_best_so_far = 1;
bool center_best_so_far = true;

if (can_refine_mv && !skip_mv_search) {
*params = best_wm_params;
Expand Down Expand Up @@ -5440,29 +5457,27 @@ int av2_pick_warp_delta(
// Decreasing is best
best_wm_params = dec_params;
best_rd = dec_rd;
center_best_so_far = 0;
center_best_so_far = false;
} else {
// Increasing is best
best_wm_params = inc_params;
best_rd = inc_rd;
center_best_so_far = 0;
center_best_so_far = false;
}
} else if (dec_rd < best_rd) {
// Decreasing is best
best_wm_params = dec_params;
best_rd = dec_rd;
center_best_so_far = 0;
center_best_so_far = false;
} else {
// Current is best
// No need to change anything
}
}

const int early_terminate_refine =
center_best_so_far ||
(early_term_warp_delta_refine && best_rd > 0.95 * best_rd_prev);

if (early_terminate_refine) {
if (early_terminate_refine_warped_mv(best_rd, best_rd_prev,
center_best_so_far,
early_term_warp_delta_refine)) {
break;
}

Expand Down Expand Up @@ -5517,7 +5532,8 @@ int av2_refine_mv_for_base_param_warp_model(
const AV2_COMMON *const cm, MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
const MB_MODE_INFO_EXT *mbmi_ext,
const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
WARP_SEARCH_METHOD search_method, int num_iterations) {
WARP_SEARCH_METHOD search_method, int num_iterations,
bool warp_mv_refine_early_term) {
WarpedMotionParams *params = &mbmi->wm_params[0];
const BLOCK_SIZE bsize = mbmi->sb_type[PLANE_TYPE_Y];
int mi_row = xd->mi_row;
Expand Down Expand Up @@ -5566,6 +5582,7 @@ int av2_refine_mv_for_base_param_warp_model(

// First iteration always scans all neighbors
uint8_t valid_neighbors = UINT8_MAX;
uint64_t best_rd_prev = best_rd;

for (int ite = 0; ite < num_iterations; ++ite) {
int best_idx = -1;
Expand Down Expand Up @@ -5603,14 +5620,20 @@ int av2_refine_mv_for_base_param_warp_model(
}
}
}
if (best_idx == -1) break;

if (best_idx >= 0) {
// Commit to this motion vector
best_mv->row += neighbors[best_idx].row * (1 << mv_shift);
best_mv->col += neighbors[best_idx].col * (1 << mv_shift);
center_mv.as_mv = *best_mv;
valid_neighbors = neighbor_mask[best_idx];
}

if (early_terminate_refine_warped_mv(
best_rd, best_rd_prev, (best_idx == -1), warp_mv_refine_early_term))
break;

best_rd_prev = best_rd;
}

mbmi->wm_params[0] = best_wm_params;
Expand All @@ -5627,7 +5650,8 @@ void av2_refine_mv_for_warp_extend(const AV2_COMMON *cm, MACROBLOCKD *xd,
bool neighbor_is_above, BLOCK_SIZE bsize,
const WarpedMotionParams *neighbor_params,
WARP_SEARCH_METHOD search_method,
int num_iterations) {
int num_iterations,
bool warp_mv_refine_early_term) {
MB_MODE_INFO *mbmi = xd->mi[0];

const MV *neighbors = warp_search_info[search_method].neighbors;
Expand All @@ -5654,6 +5678,7 @@ void av2_refine_mv_for_warp_extend(const AV2_COMMON *cm, MACROBLOCKD *xd,

// First iteration always scans all neighbors
uint8_t valid_neighbors = UINT8_MAX;
unsigned int bestmse_prev = bestmse;

for (int ite = 0; ite < num_iterations; ++ite) {
int best_idx = -1;
Expand Down Expand Up @@ -5690,13 +5715,17 @@ void av2_refine_mv_for_warp_extend(const AV2_COMMON *cm, MACROBLOCKD *xd,
}
}

if (best_idx == -1) break;

if (best_idx >= 0) {
best_mv->row += neighbors[best_idx].row * (1 << mv_shift);
best_mv->col += neighbors[best_idx].col * (1 << mv_shift);
valid_neighbors = neighbor_mask[best_idx];
}

if (early_terminate_refine_warped_mv(
bestmse, bestmse_prev, (best_idx == -1), warp_mv_refine_early_term))
break;

bestmse_prev = bestmse;
}

mbmi->wm_params[0] = best_wm_params;
Expand Down
9 changes: 6 additions & 3 deletions av2/encoder/mcomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,8 @@ unsigned int av2_refine_warped_mv(MACROBLOCKD *xd, const AV2_COMMON *const cm,
BLOCK_SIZE bsize, const int *pts0,
const int *pts_inref0, int total_samples,
int8_t ref, WARP_SEARCH_METHOD search_method,
int num_iterations);
int num_iterations,
bool warp_mv_refine_early_term);
uint8_t need_mv_adjustment(MACROBLOCKD *xd, const AV2_COMMON *const cm,
MACROBLOCK *const x, MB_MODE_INFO *mbmi,
BLOCK_SIZE bsize, MV *mv_diffs, MV *ref_mvs,
Expand All @@ -581,14 +582,16 @@ int av2_refine_mv_for_base_param_warp_model(
const AV2_COMMON *const cm, MACROBLOCKD *xd, MB_MODE_INFO *mbmi,
const MB_MODE_INFO_EXT *mbmi_ext,
const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
WARP_SEARCH_METHOD search_method, int num_iterations);
WARP_SEARCH_METHOD search_method, int num_iterations,
bool warp_mv_refine_early_term);

void av2_refine_mv_for_warp_extend(const AV2_COMMON *cm, MACROBLOCKD *xd,
const SUBPEL_MOTION_SEARCH_PARAMS *ms_params,
bool neighbor_is_above, BLOCK_SIZE bsize,
const WarpedMotionParams *neighbor_params,
WARP_SEARCH_METHOD search_method,
int num_iterations);
int num_iterations,
bool warp_mv_refine_early_term);

static INLINE void av2_set_fractional_mv(int_mv *fractional_best_mv) {
for (int z = 0; z < 3; z++) {
Expand Down
11 changes: 7 additions & 4 deletions av2/encoder/rdopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2512,7 +2512,8 @@ static AVM_INLINE int handle_warp_causal_mode(
av2_refine_warped_mv(
xd, cm, &ms_params, bsize, pts0, pts_inref0, total_samples0, 0,
get_warp_search_method(cpi, eval_motion_mode, mbmi->ref_frame[0]),
cpi->sf.mv_sf.warp_search_iters);
cpi->sf.mv_sf.warp_search_iters,
cpi->sf.mv_sf.warp_mv_refine_early_term);
if (mv0.as_int != mbmi->mv[0].as_int) {
if (mbmi->mode == NEW_NEWMV) {
int tmp_rate_mv0 = av2_mv_bit_cost(
Expand Down Expand Up @@ -2543,7 +2544,8 @@ static AVM_INLINE int handle_warp_causal_mode(
av2_refine_warped_mv(
xd, cm, &ms_params, bsize, pts1, pts_inref1, total_samples1, 1,
get_warp_search_method(cpi, eval_motion_mode, mbmi->ref_frame[1]),
cpi->sf.mv_sf.warp_search_iters);
cpi->sf.mv_sf.warp_search_iters,
cpi->sf.mv_sf.warp_mv_refine_early_term);

if (mv1.as_int != mbmi->mv[1].as_int) {
int tmp_rate_mv1 = av2_mv_bit_cost(
Expand Down Expand Up @@ -2641,7 +2643,8 @@ static AVM_INLINE int handle_warp_delta_mode(
valid = av2_refine_mv_for_base_param_warp_model(
cm, xd, mbmi, mbmi_ext, &ms_params,
get_warp_search_method(cpi, eval_motion_mode, mbmi->ref_frame[0]),
cpi->sf.mv_sf.warp_search_iters);
cpi->sf.mv_sf.warp_search_iters,
cpi->sf.mv_sf.warp_mv_refine_early_term);
} else {
mbmi->six_param_warp_model_flag = get_default_six_param_flag(cm, mbmi);
const int six_param_enabled_by_tid =
Expand Down Expand Up @@ -2759,7 +2762,7 @@ static AVM_INLINE int handle_warp_extend_mode(
av2_refine_mv_for_warp_extend(
cm, xd, &ms_params, neighbor_is_above, bsize, &neighbor_params,
get_warp_search_method(cpi, eval_motion_mode, mbmi->ref_frame[0]),
cpi->sf.mv_sf.warp_search_iters);
cpi->sf.mv_sf.warp_search_iters, cpi->sf.mv_sf.warp_mv_refine_early_term);

// If we changed the MV, update costs
if (mv0.as_int != mbmi->mv[0].as_int) {
Expand Down
2 changes: 2 additions & 0 deletions av2/encoder/speed_features.c
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ static void set_good_speed_features_framesize_independent(
sf->mv_sf.full_pixel_search_level = 1;
sf->mv_sf.simple_motion_subpel_force_stop = QUARTER_PEL;
sf->mv_sf.subpel_search_method = SUBPEL_TREE_PRUNED;
sf->mv_sf.warp_mv_refine_early_term = true;

sf->gm_sf.num_refinement_steps = 0;

Expand Down Expand Up @@ -866,6 +867,7 @@ static AVM_INLINE void init_mv_sf(MV_SPEED_FEATURES *mv_sf) {
mv_sf->warp_search_method = WARP_SEARCH_SQUARE;
mv_sf->warp_search_method_sec_ref = WARP_SEARCH_SQUARE;
mv_sf->warp_search_iters = 8;
mv_sf->warp_mv_refine_early_term = false;
mv_sf->fast_motion_estimation_on_block_256 = 0;
}

Expand Down
4 changes: 4 additions & 0 deletions av2/encoder/speed_features.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,10 @@ typedef struct MV_SPEED_FEATURES {
// Maximum number of iterations in WARP_CAUSAL refinement search
int warp_search_iters;

// Early-terminate warp MV refinement when the RD improvement over the
// previous iteration is less than ~5%. Enabled for speed >= 3.
bool warp_mv_refine_early_term;

// Use faster motion search settings for partition blocks with at least one
// dimension that's >= 256
int fast_motion_estimation_on_block_256;
Expand Down