Allow inter mode rd est to use static models Enhances the 2-pass inter_mode_rd_model_estimation feature to use static rd models as well as online dynamic models, using inter_mode_rd_model_estimation feature values: inter_mode_rd_model_estimation = 0, not used inter_mode_rd_model_estimation = 1, use online model inter_mode_rd_model_estimation = 2, use static model The new static model option currnetly uses a variance based selection method, but that may change soon. The patch also includes some refactoring and streamlining of the code, but the inter_mode_rd_model_estimation = 1 behavior is left unchanged. The inter_mode_rd_model_estimation feature is still left as 0 and so the feature is not turned on yet until further tweaks and testing are conducted. Change-Id: I6dc6543dab7124e4bbbe2fa8c65e5841b03d0a03
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 60409cb..2f92da9 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -5641,7 +5641,7 @@ } #if CONFIG_COLLECT_INTER_MODE_RD_STATS // TODO(angiebird): Let inter_mode_rd_model_estimation support multi-tile. - if (cpi->sf.inter_mode_rd_model_estimation && cm->tile_cols == 1 && + if (cpi->sf.inter_mode_rd_model_estimation == 1 && cm->tile_cols == 1 && cm->tile_rows == 1) { av1_inter_mode_data_fit(tile_data, x->rdmult); }
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index f91a360..9923e45 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -786,16 +786,6 @@ return 0; } -static int64_t get_est_rd(TileDataEnc *tile_data, BLOCK_SIZE bsize, int rdmult, - int64_t sse, int curr_cost) { - int est_residue_cost; - int64_t est_dist; - if (get_est_rate_dist(tile_data, bsize, sse, &est_residue_cost, &est_dist)) { - return RDCOST(rdmult, est_residue_cost + curr_cost, est_dist); - } - return 0; -} - void av1_inter_mode_data_fit(TileDataEnc *tile_data, int rdmult) { aom_clear_system_state(); for (int bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) { @@ -2533,7 +2523,9 @@ if (rd_stats->rate == INT_MAX || rd_stats->dist == INT64_MAX) return; #if CONFIG_COLLECT_INTER_MODE_RD_STATS - if (!tile_data->inter_mode_rd_models[plane_bsize].ready) return; + if (cpi->sf.inter_mode_rd_model_estimation == 1 && + !tile_data->inter_mode_rd_models[plane_bsize].ready) + return; #endif (void)tile_data; // Generate small sample to restrict output size. @@ -2611,19 +2603,21 @@ model_rdcost_norm); #if CONFIG_COLLECT_INTER_MODE_RD_STATS - // TODO(angiebird): make sure the prediction for YUV planes are ready - const int64_t overall_sse = get_sse(cpi, x); - assert(tile_data->inter_mode_rd_models[plane_bsize].ready); - int est_residue_cost = 0; - int64_t est_dist = 0; - get_est_rate_dist(tile_data, plane_bsize, overall_sse, &est_residue_cost, - &est_dist); - const double est_residue_cost_norm = (double)est_residue_cost / num_samples; - const double est_dist_norm = (double)est_dist / num_samples; - const double est_rdcost_norm = - (double)RDCOST(x->rdmult, est_residue_cost, est_dist) / num_samples; - fprintf(fout, " %g %g %g", est_residue_cost_norm, est_dist_norm, - est_rdcost_norm); + if (cpi->sf.inter_mode_rd_model_estimation == 1) { + assert(tile_data->inter_mode_rd_models[plane_bsize].ready); + const int64_t overall_sse = get_sse(cpi, x); + assert(tile_data->inter_mode_rd_models[plane_bsize].ready); + int est_residue_cost = 0; + int64_t est_dist = 0; + get_est_rate_dist(tile_data, plane_bsize, overall_sse, &est_residue_cost, + &est_dist); + const double est_residue_cost_norm = (double)est_residue_cost / num_samples; + const double est_dist_norm = (double)est_dist / num_samples; + const double est_rdcost_norm = + (double)RDCOST(x->rdmult, est_residue_cost, est_dist) / num_samples; + fprintf(fout, " %g %g %g", est_residue_cost_norm, est_dist_norm, + est_rdcost_norm); + } #endif double mean = get_mean(src_diff, diff_stride, bw, bh); @@ -9251,7 +9245,11 @@ } } - if (cpi->sf.model_based_motion_mode_rd_breakout) { + if (cpi->sf.model_based_motion_mode_rd_breakout +#if CONFIG_COLLECT_INTER_MODE_RD_STATS + && do_tx_search +#endif // CONFIG_COLLECT_INTER_MODE_RD_STATS + ) { int model_rate; int64_t model_dist; model_rd_sb_fn[MODELRD_TYPE_MOTION_MODE_RD]( @@ -9266,38 +9264,37 @@ } #if CONFIG_COLLECT_INTER_MODE_RD_STATS - if (cpi->sf.inter_mode_rd_model_estimation && cm->tile_cols == 1 && - cm->tile_rows == 1) { - const InterModeRdModel *md = - &tile_data->inter_mode_rd_models[mbmi->sb_type]; - if (md->ready) { - const int64_t curr_sse = get_sse(cpi, x); - const int64_t est_rd = get_est_rd(tile_data, mbmi->sb_type, x->rdmult, - curr_sse, rd_stats->rate); - const int est_skip = est_rd * 0.8 > *best_est_rd; - if (est_skip) { - mbmi->ref_frame[1] = ref_frame_1; - continue; - } else { - if (est_rd < *best_est_rd) { - *best_est_rd = est_rd; - } - } - } - } - if (!do_tx_search) { - const int64_t curr_sse = get_sse(cpi, x); + int64_t curr_sse; int est_residue_cost = 0; int64_t est_dist = 0; - const int has_est_rd = get_est_rate_dist(tile_data, bsize, curr_sse, - &est_residue_cost, &est_dist); - (void)has_est_rd; - assert(has_est_rd); + int64_t est_rd = 0; + if (cpi->sf.inter_mode_rd_model_estimation == 1) { + curr_sse = get_sse(cpi, x); + const int has_est_rd = get_est_rate_dist(tile_data, bsize, curr_sse, + &est_residue_cost, &est_dist); + (void)has_est_rd; + assert(has_est_rd); + est_rd = RDCOST(x->rdmult, rd_stats->rate + est_residue_cost, est_dist); + if (est_rd * 0.8 > *best_est_rd) { + mbmi->ref_frame[1] = ref_frame_1; + continue; + } + } else if (cpi->sf.inter_mode_rd_model_estimation == 2) { + model_rd_sb_fn[MODELRD_TYPE_MOTION_MODE_RD]( + cpi, bsize, x, xd, 0, num_planes - 1, mi_row, mi_col, + &est_residue_cost, &est_dist, NULL, &curr_sse, NULL, NULL, NULL); + est_rd = RDCOST(x->rdmult, rd_stats->rate + est_residue_cost, est_dist); + if (est_rd * 0.75 > AOMMIN(ref_best_rd, *best_est_rd)) { + mbmi->ref_frame[1] = ref_frame_1; + continue; + } + } const int mode_rate = rd_stats->rate; rd_stats->rate += est_residue_cost; rd_stats->dist = est_dist; - rd_stats->rdcost = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist); + rd_stats->rdcost = est_rd; + *best_est_rd = AOMMIN(*best_est_rd, rd_stats->rdcost); if (cm->current_frame.reference_mode == SINGLE_REFERENCE) { if (!is_comp_pred) { inter_modes_info_push(inter_modes_info, mode_rate, curr_sse, @@ -11974,12 +11971,11 @@ #if CONFIG_COLLECT_INTER_MODE_RD_STATS int64_t best_est_rd = INT64_MAX; // TODO(angiebird): Turn this on when this speed feature is well tested -#if 1 const InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize]; - const int do_tx_search = !md->ready; -#else - const int do_tx_search = 1; -#endif + const int do_tx_search = + !((cpi->sf.inter_mode_rd_model_estimation == 1 && md->ready) || + (cpi->sf.inter_mode_rd_model_estimation == 2 && + x->source_variance < 512)); InterModesInfo *inter_modes_info = x->inter_modes_info; inter_modes_info->num = 0; #endif @@ -12285,8 +12281,14 @@ const int data_idx = inter_modes_info->rd_idx_pair_arr[j].idx; *mbmi = inter_modes_info->mbmi_arr[data_idx]; int64_t curr_est_rd = inter_modes_info->est_rd_arr[data_idx]; - if (curr_est_rd * 0.85 > top_est_rd) { - continue; + if (cpi->sf.inter_mode_rd_model_estimation == 1) { + if (curr_est_rd * 0.85 > top_est_rd) break; + } else if (cpi->sf.inter_mode_rd_model_estimation == 2) { + if (x->source_variance < 256) { + if (curr_est_rd * 0.80 > top_est_rd) break; + } else { + if (curr_est_rd * 0.75 > top_est_rd) break; + } } const int mode_rate = inter_modes_info->mode_rate_arr[data_idx];
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c index b5b4fd0..727924e 100644 --- a/av1/encoder/speed_features.c +++ b/av1/encoder/speed_features.c
@@ -204,6 +204,10 @@ sf->model_based_prune_tx_search_level = 1; sf->model_based_post_interp_filter_breakout = 1; sf->model_based_motion_mode_rd_breakout = 1; + + // TODO(debargha): Test, tweak and turn on either 1 or 2 + sf->inter_mode_rd_model_estimation = 0; + sf->prune_ref_frame_for_rect_partitions = !(boosted || cpi->refresh_bwd_ref_frame || cpi->refresh_alt2_ref_frame); sf->prune_ref_mode_for_partitions = sf->prune_ref_frame_for_rect_partitions; @@ -543,6 +547,7 @@ // inter_mode_rd_model_estimation in conjunction with // model_based_motion_mode_rd_breakout sf->inter_mode_rd_model_estimation = 0; + sf->obmc_full_pixel_search_level = 0; sf->skip_sharp_interp_filter_search = 0; sf->prune_comp_type_by_comp_avg = 0; @@ -635,6 +640,7 @@ #endif // CONFIG_DIST_8X8 if (cpi->oxcf.row_mt == 1 && (cpi->oxcf.max_threads > 1)) { sf->adaptive_rd_thresh = 0; - sf->inter_mode_rd_model_estimation = 0; + if (sf->inter_mode_rd_model_estimation == 1) + sf->inter_mode_rd_model_estimation = 0; } }
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h index 5687f68..bccf245 100644 --- a/av1/encoder/speed_features.h +++ b/av1/encoder/speed_features.h
@@ -565,7 +565,12 @@ // adding a penalty of 1% int dual_sgr_penalty_level; - // Dynamically estimate final rd from prediction error and mode cost + // 2-pass inter mode model estimation where the preliminary pass skips + // transform search and uses a model to estimate rd, while the final pass + // computes the full transform search. two types of models are supported: + // 0: not used + // 1: used with online dynamic rd model + // 2: used with static rd model int inter_mode_rd_model_estimation; // Skip some ref frames in compound motion search by single motion search