From b928893dabb984adfdca582bc4dcba3bd5c26d0e Mon Sep 17 00:00:00 2001 From: Yeqing Wu Date: Sat, 11 Jul 2026 13:36:57 -0700 Subject: [PATCH] Add pruning for refinemv, INTERINTRA, and WARP_DELTA Enables three ref-index based pruning speed features at speed >= 1: - prune_refinemv_by_ref_idx: skip refinemv_loop == 1 for ref-pairs other than (0, 1). - prune_interintra_by_ref_idx: skip INTERINTRA motion mode when ref_frame[0] > 1. - prune_warp_delta_by_ref_idx: skip WARP_DELTA motion mode when ref_frame[0] > 2. STATS_CHANGED Anchor: commit 165345b Speed 1 (cpu-used=1): FG16 CTC (33 frames, class A1 and A2, RA) Speed 4 (cpu-used=4): FG16 CTC (33 frames, class A1 and A2, RA) ``` 1) Speed 1 a) Overall performance (all three features combined) +------------+------+-------+-------+------+------+------+ | Class | Y | Cb | Cr | wAvg | Enc% | Dec% | +------------+------+-------+-------+------+------+------+ | A1 | 0.02 | -0.15 | 0.05 | 0.01 | 93 | 101 | | A2 | 0.12 | 0.36 | -0.03 | 0.12 | 93 | 100 | | Avg w/o B2 | 0.09 | 0.21 | -0.00 | 0.09 | 93 | 100 | +------------+------+-------+-------+------+------+------+ b) Performance of prune_refinemv_by_ref_idx only +------------+-------+-------+-------+-------+------+------+ | Class | Y | Cb | Cr | wAvg | Enc% | Dec% | +------------+-------+-------+-------+-------+------+------+ | A1 | -0.01 | -0.14 | -0.34 | -0.04 | 99 | 101 | | A2 | 0.04 | 0.06 | -0.25 | 0.02 | 99 | 100 | | Avg w/o B2 | 0.02 | 0.00 | -0.28 | 0.00 | 99 | 100 | +------------+-------+-------+-------+-------+------+------+ c) Performance of prune_interintra_by_ref_idx only +------------+------+-------+------+------+------+------+ | Class | Y | Cb | Cr | wAvg | Enc% | Dec% | +------------+------+-------+------+------+------+------+ | A1 | 0.04 | -0.02 | 0.04 | 0.04 | 98 | 100 | | A2 | 0.02 | 0.27 | 0.08 | 0.03 | 98 | 100 | | Avg w/o B2 | 0.03 | 0.18 | 0.07 | 0.03 | 98 | 100 | +------------+------+-------+------+------+------+------+ d) Performance of prune_warp_delta_by_ref_idx only +------------+------+------+-------+------+------+------+ | Class | Y | Cb | Cr | wAvg | Enc% | Dec% | +------------+------+------+-------+------+------+------+ | A1 | 0.03 | 0.00 | 0.12 | 0.03 | 95 | 101 | | A2 | 0.07 | 0.11 | -0.07 | 0.07 | 96 | 100 | | Avg w/o B2 | 0.06 | 0.08 | -0.01 | 0.06 | 96 | 100 | +------------+------+------+-------+------+------+------+ 2) Speed 4 Overall performance (all three features combined) +------------+-------+-------+-------+-------+------+------+ | Class | Y | Cb | Cr | wAvg | Enc% | Dec% | +------------+-------+-------+-------+-------+------+------+ | A1 | -0.01 | -0.09 | -0.01 | -0.02 | 90 | 101 | | A2 | 0.14 | 0.33 | 0.18 | 0.14 | 89 | 101 | | Avg w/o B2 | 0.09 | 0.20 | 0.12 | 0.09 | 89 | 101 | +------------+------+-------+-------+-------+------+------+ ``` --- av2/encoder/rdopt.c | 15 +++++++++++++++ av2/encoder/speed_features.c | 6 ++++++ av2/encoder/speed_features.h | 12 ++++++++++++ 3 files changed, 33 insertions(+) diff --git a/av2/encoder/rdopt.c b/av2/encoder/rdopt.c index e0289f3209..14be35d6df 100644 --- a/av2/encoder/rdopt.c +++ b/av2/encoder/rdopt.c @@ -2960,11 +2960,15 @@ static AVM_INLINE int evaluate_motion_mode_trial( &tmp_rate2) < 0) return -1; } else if (mbmi->motion_mode == INTERINTRA) { + if (cpi->sf.inter_sf.prune_interintra_by_ref_idx && mbmi->ref_frame[0] > 1) + return -1; if (av2_handle_inter_intra_mode(cpi, x, bsize, mbmi, args, *ref_best_rd, &tmp_rate_mv, &tmp_rate2, orig_dst) < 0) return -1; assert(mbmi->motion_mode == INTERINTRA); } else if (mbmi->motion_mode == WARP_DELTA) { + if (cpi->sf.inter_sf.prune_warp_delta_by_ref_idx && mbmi->ref_frame[0] > 2) + return -1; if (handle_warp_delta_mode( cpi, x, bsize, mbmi, mbmi_ext, args, *ref_best_rd, orig_dst, ctx->previous_mvs, ctx->prev_best_models, org_warp_inter_intra, @@ -5021,6 +5025,12 @@ static void evaluate_inter_predictor(AV2_COMP *const cpi, } } restore_dst_buf(xd, *env->orig_dst, num_planes); + // motion_mode_rd() may leave mbmi->motion_mode set to a non-SIMPLE + // winner. The winning value has already been captured into + // search_state->best_mbmi and winner_mode_stats above. Restore here so + // the outer caller (handle_inter_mode) sees SIMPLE_TRANSLATION at the + // top of its next per-precision iteration. + mbmi->motion_mode = SIMPLE_TRANSLATION; } /*!\brief AV2 inter mode RD computation @@ -5630,6 +5640,11 @@ static int64_t handle_inter_mode( &base_mbmi, 0, num_planes, args->skip_motion_mode); for (int refinemv_loop = 0; refinemv_loop < REFINEMV_NUM_MODES; refinemv_loop++) { + if (refinemv_loop == 1 && + cpi->sf.inter_sf.prune_refinemv_by_ref_idx && + !(base_mbmi.ref_frame[0] == 0 && + base_mbmi.ref_frame[1] == 1)) + continue; it_ctx.refinemv_loop = refinemv_loop; evaluate_inter_predictor( cpi, tile_data, x, &env, &it_ctx, &search_state, diff --git a/av2/encoder/speed_features.c b/av2/encoder/speed_features.c index 0bc28123cc..e1707ac45e 100644 --- a/av2/encoder/speed_features.c +++ b/av2/encoder/speed_features.c @@ -339,6 +339,9 @@ static void set_good_speed_features_framesize_independent( // TODO (Yeqing Wu): need to be tuned for speed > 1. sf->inter_sf.skip_compound_prune_top_refs_num_ref0 = 1; sf->inter_sf.skip_compound_prune_top_refs_num_ref1 = 2; + sf->inter_sf.prune_refinemv_by_ref_idx = 1; + sf->inter_sf.prune_interintra_by_ref_idx = 1; + sf->inter_sf.prune_warp_delta_by_ref_idx = 1; sf->tx_sf.adaptive_tx_type_search_idx = 4; sf->tx_sf.adaptive_tx_partition_type_search_idx = 4; @@ -721,6 +724,9 @@ static AVM_INLINE void init_inter_sf(INTER_MODE_SPEED_FEATURES *inter_sf) { inter_sf->prune_compound_using_single_ref = 0; inter_sf->skip_compound_prune_top_refs_num_ref0 = 0; inter_sf->skip_compound_prune_top_refs_num_ref1 = 0; + inter_sf->prune_refinemv_by_ref_idx = 0; + inter_sf->prune_interintra_by_ref_idx = 0; + inter_sf->prune_warp_delta_by_ref_idx = 0; inter_sf->prune_comp_using_best_single_mode_ref = 0; inter_sf->prune_mode_search_simple_translation = 0; inter_sf->prune_comp_type_by_comp_avg = 0; diff --git a/av2/encoder/speed_features.h b/av2/encoder/speed_features.h index 1bcbbaf9d2..208a59dd1a 100644 --- a/av2/encoder/speed_features.h +++ b/av2/encoder/speed_features.h @@ -634,6 +634,18 @@ typedef struct INTER_MODE_SPEED_FEATURES { int skip_compound_prune_top_refs_num_ref0; int skip_compound_prune_top_refs_num_ref1; + // Skip refinemv_loop == 1 for ref-pairs other than (0, 1). Enabled at + // speed >= 1. + int prune_refinemv_by_ref_idx; + + // Skip INTERINTRA motion mode when ref_frame[0] > 1. Enabled at + // speed >= 1. + int prune_interintra_by_ref_idx; + + // Skip WARP_DELTA motion mode when ref_frame[0] > 2. Enabled at + // speed >= 1. + int prune_warp_delta_by_ref_idx; + // Skip extended compound mode when ref frame corresponding to NEWMV does not // have NEWMV as single mode winner. // 0 : no pruning