diff --git a/av2/common/filter.h b/av2/common/filter.h index 33885685a7..3c433c5d4f 100644 --- a/av2/common/filter.h +++ b/av2/common/filter.h @@ -51,7 +51,8 @@ enum { enum { INTERP_EVAL_LUMA_EVAL_CHROMA = 0, INTERP_SKIP_LUMA_EVAL_CHROMA, - INTERP_EVAL_INVALID, + INTERP_EVAL_LUMA_SKIP_CHROMA, // Valid only when skip_model_rd_uv speed + // feature is enabled INTERP_SKIP_LUMA_SKIP_CHROMA, } UENUM1BYTE(INTERP_EVAL_PLANE); diff --git a/av2/encoder/interp_search.c b/av2/encoder/interp_search.c index 75973f2e90..cd34a4803f 100644 --- a/av2/encoder/interp_search.c +++ b/av2/encoder/interp_search.c @@ -193,7 +193,6 @@ static INLINE int64_t interpolation_filter_rd( (void)tile_data; - assert(skip_pred != 2); assert((rd_stats_luma->rate >= 0) && (rd_stats->rate >= 0)); assert((rd_stats_luma->dist >= 0) && (rd_stats->dist >= 0)); assert((rd_stats_luma->sse >= 0) && (rd_stats->sse >= 0)); @@ -213,11 +212,16 @@ static INLINE int64_t interpolation_filter_rd( (skip_pred == interp_search_flags->default_interp_skip_flags) ? INTERP_SKIP_LUMA_SKIP_CHROMA : skip_pred; - - switch (tmp_skip_pred) { - case INTERP_EVAL_LUMA_EVAL_CHROMA: - // skip_pred = 0: Evaluate both luma and chroma. - // Luma MC + assert(IMPLIES(tmp_skip_pred == INTERP_EVAL_LUMA_SKIP_CHROMA, + cpi->sf.interp_sf.skip_model_rd_uv)); + + if (tmp_skip_pred == INTERP_SKIP_LUMA_SKIP_CHROMA) { + // Both luma and chroma evaluations are skipped. + this_rd_stats = *rd_stats; + } else { + // Evaluate Luma + if (tmp_skip_pred == INTERP_EVAL_LUMA_EVAL_CHROMA || + tmp_skip_pred == INTERP_EVAL_LUMA_SKIP_CHROMA) { interp_model_rd_eval(x, cpi, bsize, orig_dst, AVM_PLANE_Y, AVM_PLANE_Y, &this_rd_stats_luma, 0); this_rd_stats = this_rd_stats_luma; @@ -227,10 +231,10 @@ static INLINE int64_t interpolation_filter_rd( INT64_MAX); PrintPredictionUnitStats(cpi, tile_data, x, &rd_stats_y, bsize); #endif // CONFIG_COLLECT_RD_STATS == 3 - AVM_FALLTHROUGH_INTENDED; - case INTERP_SKIP_LUMA_EVAL_CHROMA: - // skip_pred = 1: skip luma evaluation (retain previous best luma stats) - // and do chroma evaluation. + } + // Evaluate Chroma + if (tmp_skip_pred == INTERP_EVAL_LUMA_EVAL_CHROMA || + tmp_skip_pred == INTERP_SKIP_LUMA_EVAL_CHROMA) { for (int plane = 1; plane < num_planes; ++plane) { int64_t tmp_rd = RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist); @@ -241,13 +245,7 @@ static INLINE int64_t interpolation_filter_rd( interp_model_rd_eval(x, cpi, bsize, orig_dst, plane, plane, &this_rd_stats, 0); } - break; - case INTERP_SKIP_LUMA_SKIP_CHROMA: - // both luma and chroma evaluation is skipped - this_rd_stats = *rd_stats; - break; - case INTERP_EVAL_INVALID: - default: assert(0); return 0; + } } int64_t tmp_rd = RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist); @@ -344,6 +342,13 @@ static INLINE void calc_interp_skip_pred_flag(MACROBLOCK *const x, assert(mbmi->comp_group_idx == 1); if (*skip_hor == 0 && *skip_ver == 1) *skip_ver = 0; } + + // Configure flags to skip chroma RD evaluation when skip_model_rd_uv is + // enabled + if (cpi->sf.interp_sf.skip_model_rd_uv && num_planes > 1) { + *skip_hor |= INTERP_EVAL_LUMA_SKIP_CHROMA; + *skip_ver |= INTERP_EVAL_LUMA_SKIP_CHROMA; + } } /*!\brief AV2 interpolation filter search @@ -368,7 +373,7 @@ static INLINE void calc_interp_skip_pred_flag(MACROBLOCK *const x, * \param[in,out] switchable_rate The rate associated with using a SWITCHABLE * filter mode. * \param[in,out] skip_build_pred Indicates whether or not to build the inter - * predictor. If this is 0, the inter predictor + * predictor. If this is 3, the inter predictor * has already been built and thus we can avoid * repeating computation. * \param[in] args HandleInterModeArgs struct holding @@ -396,6 +401,7 @@ int64_t av2_interpolation_filter_search( MB_MODE_INFO *const mbmi = xd->mi[0]; const int need_search = av2_is_interp_needed(cm, xd); const int ref_frame = COMPACT_INDEX0_NRS(xd->mi[0]->ref_frame[0]); + const int skip_model_rd_uv = cpi->sf.interp_sf.skip_model_rd_uv; RD_STATS rd_stats_luma, rd_stats; if (mbmi->mode == WARPMV) return 0; @@ -415,6 +421,7 @@ int64_t av2_interpolation_filter_search( *rd = args->interp_filter_stats[match_found_idx].rd; x->pred_sse[ref_frame] = args->interp_filter_stats[match_found_idx].pred_sse; + *skip_build_pred = INTERP_EVAL_LUMA_EVAL_CHROMA; return 0; } @@ -436,11 +443,13 @@ int64_t av2_interpolation_filter_search( PrintPredictionUnitStats(cpi, tile_data, x, &rd_stats_y, bsize); #endif // CONFIG_COLLECT_RD_STATS == 3 // Chroma MC - if (num_planes > 1) { + if (num_planes > 1 && !skip_model_rd_uv) { interp_model_rd_eval(x, cpi, bsize, orig_dst, AVM_PLANE_U, AVM_PLANE_V, &rd_stats, *skip_build_pred); } - *skip_build_pred = 1; + *skip_build_pred = num_planes > 1 && skip_model_rd_uv + ? INTERP_SKIP_LUMA_EVAL_CHROMA + : INTERP_SKIP_LUMA_SKIP_CHROMA; av2_merge_rd_stats(&rd_stats, &rd_stats_luma); @@ -489,8 +498,8 @@ int64_t av2_interpolation_filter_search( // Setting 0th flag corresonds to skipping luma MC and setting 1st bt // corresponds to skipping chroma MC skip_flag=0 corresponds to "Don't skip // luma and chroma MC" Skip flag=1 corresponds to "Skip Luma MC only" - // Skip_flag=2 is not a valid case - // skip_flag=3 corresponds to "Skip both luma and chroma MC" + // Skip_flag=2 corresponds to "Skip chroma MC only". This is valid only when + // skip_model_rd_uv speed feature is enabled int skip_hor = interp_search_flags->default_interp_skip_flags; int skip_ver = interp_search_flags->default_interp_skip_flags; calc_interp_skip_pred_flag(x, cpi, &skip_hor, &skip_ver); diff --git a/av2/encoder/rdopt.c b/av2/encoder/rdopt.c index 69ceaa9d0f..0c82e1fcf8 100644 --- a/av2/encoder/rdopt.c +++ b/av2/encoder/rdopt.c @@ -4490,26 +4490,18 @@ static INLINE bool prune_comp_eval_using_est_rd( * done in the motion mode search. * \param[in,out] rd_stats Struct to keep track of the overall RD * information. - * \param[in,out] skip_rd An array of length 2 where skip_rd[0] is - the + * \param[in,out] skip_rd An array of length 2 where skip_rd[0] is the * best total RD for a skip mode so far, and - * skip_rd[1] is the best RD for a skip mode - so - * far in luma. This is used as a speed - feature - * to skip the transform search if the - computed + * skip_rd[1] is the best RD for a skip mode so + * far in luma. This is used as a speed feature + * to skip the transform search if the computed * skip RD for the current mode is not better * than the best skip_rd so far. - * \param[in,out] skip_build_pred Indicates whether or not to build the - inter - * predictor. If this is 0, the inter - predictor - * has already been built and thus we can - avoid - * repeating computation. - * \return Returns 1 if this mode is worse than one already seen and 0 if it - is + * \param[out] skip_build_pred Indicates whether or not to build the inter + * predictor during/after interpolation + * filter search. + + * \return Returns 1 if this mode is worse than one already seen and 0 if it is * a viable candidate. */ static int process_compound_inter_mode( @@ -4587,7 +4579,7 @@ static int process_compound_inter_mode( av2_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize, AVM_PLANE_U, num_planes - 1); } - *skip_build_pred = 1; + *skip_build_pred = INTERP_SKIP_LUMA_SKIP_CHROMA; } return 0; } @@ -5023,7 +5015,9 @@ static void evaluate_inter_predictor(AV2_COMP *const cpi, mbmi, cpi->sf.inter_sf.prune_ref_mv_idx_search)) return; - int skip_build_pred = 0; + // Flag to indicate whether to skip av1_enc_build_inter_predictor() after + // interpolation filter search + int skip_build_pred = INTERP_EVAL_LUMA_EVAL_CHROMA; const int mi_row = xd->mi_row; const int mi_col = xd->mi_col; @@ -5104,15 +5098,24 @@ static void evaluate_inter_predictor(AV2_COMP *const cpi, } } rd_stats->rate += compmode_interinter_cost; - if ((skip_build_pred != 1 && (mbmi->mode != WARPMV)) || is_comp_pred) { - // Build this inter predictor if it has not been - // previously built + if ((skip_build_pred != INTERP_SKIP_LUMA_SKIP_CHROMA && + (mbmi->mode != WARPMV)) || + is_comp_pred) { + // Chroma plane of COMPOUND_DIFFWTD mode shares the segment mask of luma + // which is stored in xd->seg_mask. Hence, the predictor is populated for + // all planes. This should avoid usage of incorrect segment mask when the + // call is made only for chroma. + const int skip_luma_plane = + skip_build_pred == INTERP_SKIP_LUMA_EVAL_CHROMA && + mbmi->interinter_comp.type != COMPOUND_DIFFWTD; + const int start_plane = skip_luma_plane ? AVM_PLANE_U : AVM_PLANE_Y; av2_enc_build_inter_predictor(cm, xd, mi_row, mi_col, env->orig_dst, bsize, - 0, av2_num_planes(cm) - 1); + start_plane, av2_num_planes(cm) - 1); } // So far we did not make prediction for WARPMV mode - assert(IMPLIES(mbmi->mode == WARPMV, skip_build_pred != 1)); + assert(IMPLIES(mbmi->mode == WARPMV, + skip_build_pred == INTERP_EVAL_LUMA_EVAL_CHROMA)); int rate2_nocoeff = rd_stats->rate; assert(IMPLIES(mbmi->mode == WARPMV, diff --git a/av2/encoder/speed_features.c b/av2/encoder/speed_features.c index 301f73447b..d29e192891 100644 --- a/av2/encoder/speed_features.c +++ b/av2/encoder/speed_features.c @@ -439,6 +439,8 @@ static void set_good_speed_features_framesize_independent( sf->inter_sf.skip_temporary_pred_for_opfl = 1; sf->inter_sf.enable_warp_inter_intra_in_winner = 1; + sf->interp_sf.skip_model_rd_uv = 1; + // Enable the optimized inter-SDP fast method (requires >=1 intra coded // block, prunes when inter-mode ratio exceeds 50%, and early skips when // the current best partitioning is PARTITION_NONE). @@ -974,6 +976,7 @@ static AVM_INLINE void init_inter_sf(INTER_MODE_SPEED_FEATURES *inter_sf) { static AVM_INLINE void init_interp_sf(INTERP_FILTER_SPEED_FEATURES *interp_sf) { interp_sf->use_interp_filter = 0; + interp_sf->skip_model_rd_uv = 0; } static AVM_INLINE void init_intra_sf(INTRA_MODE_SPEED_FEATURES *intra_sf) { diff --git a/av2/encoder/speed_features.h b/av2/encoder/speed_features.h index 8c3dc19658..0fb792a5ee 100644 --- a/av2/encoder/speed_features.h +++ b/av2/encoder/speed_features.h @@ -871,6 +871,10 @@ typedef struct INTERP_FILTER_SPEED_FEATURES { // Check mv and ref_frames before search, if they are very close with previous // saved results, filter search can be skipped. int use_interp_filter; + + // Skip model RD evaluation of chroma planes during interpolation filter + // search. Enabled for speed >= 1. + int skip_model_rd_uv; } INTERP_FILTER_SPEED_FEATURES; typedef struct INTRA_MODE_SPEED_FEATURES {