Allintra: Delay top-right sync for row-mt When row-mt is enabled, a thread waits for the encoding of the top-right superblock to be complete before encoding the current superblock. This wait time is reduced in allintra mode, by delaying the sync wait until the data from top-right superblock is needed. This change is applicable for resolutions < 4k in speed >= 9 as cost update frequencies are set to COST_UPD_OFF for these resolutions. For AVIF still-image encode, an average encode time reduction of ~6.12% is observed for 360p-720p resolutions with speed=9 and 4 threads. Change-Id: I3cdeb7ad58df976788cc6bd058184dfc65b63593
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index 0e6baae..80eb7f3 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -734,11 +734,36 @@ } } -static AOM_INLINE int is_rtc_mode(const CostUpdateFreq *cost_upd_freq, - MODE mode) { - return ((mode == REALTIME) && cost_upd_freq->coeff >= 2 && - cost_upd_freq->mode >= 2 && cost_upd_freq->mv >= 2 && - cost_upd_freq->dv >= 2); +// Check if the cost update of symbols mode, coeff and dv are tile or off. +static AOM_INLINE int is_mode_coeff_dv_upd_freq_tile_or_off( + const AV1_COMP *const cpi, const CostUpdateFreq *const cost_upd_freq) { + const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf; + + return ((cost_upd_freq->coeff >= COST_UPD_TILE || + inter_sf->coeff_cost_upd_level == INTERNAL_COST_UPD_OFF) && + (cost_upd_freq->mode >= COST_UPD_TILE || + inter_sf->mode_cost_upd_level == INTERNAL_COST_UPD_OFF) && + (cost_upd_freq->dv >= COST_UPD_TILE || + cpi->sf.intra_sf.dv_cost_upd_level == INTERNAL_COST_UPD_OFF)); +} + +// When row-mt is enabled and cost update frequencies are set to off/tile, +// processing of current SB can start even before processing of top-right SB +// is finished. This function checks if it is sufficient to wait for top SB +// to finish processing before current SB starts processing. +static AOM_INLINE int delay_wait_for_top_right_sb(const AV1_COMP *const cpi) { + const MODE mode = cpi->oxcf.mode; + if (mode == GOOD) return 0; + + const CostUpdateFreq *const cost_upd_freq = &cpi->oxcf.cost_upd_freq; + if (mode == ALLINTRA) + return is_mode_coeff_dv_upd_freq_tile_or_off(cpi, cost_upd_freq); + else if (mode == REALTIME) + return (is_mode_coeff_dv_upd_freq_tile_or_off(cpi, cost_upd_freq) && + (cost_upd_freq->mv >= COST_UPD_TILE || + cpi->sf.inter_sf.mv_cost_upd_level == INTERNAL_COST_UPD_OFF)); + else + return 0; } /*!\brief Encode a superblock row by breaking it into superblocks @@ -766,8 +791,6 @@ const int mib_size_log2 = cm->seq_params->mib_size_log2; const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2; const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode; - const CostUpdateFreq *const cost_upd_freq = &cpi->oxcf.cost_upd_freq; - const int rtc_mode = is_rtc_mode(cost_upd_freq, cpi->oxcf.mode); #if CONFIG_COLLECT_COMPONENT_TIMING start_timing(cpi, encode_sb_row_time); @@ -790,11 +813,11 @@ // Code each SB in the row for (int mi_col = tile_info->mi_col_start, sb_col_in_tile = 0; mi_col < tile_info->mi_col_end; mi_col += mib_size, sb_col_in_tile++) { - // In realtime mode and when frequency of cost updates is off/tile, wait for - // the top superblock to finish encoding. Otherwise, wait for the top-right - // superblock to finish encoding. - (*(enc_row_mt->sync_read_ptr))(row_mt_sync, sb_row, - sb_col_in_tile - rtc_mode); + // In realtime/allintra mode and when frequency of cost updates is off/tile, + // wait for the top superblock to finish encoding. Otherwise, wait for the + // top-right superblock to finish encoding. + (*(enc_row_mt->sync_read_ptr))( + row_mt_sync, sb_row, sb_col_in_tile - delay_wait_for_top_right_sb(cpi)); const int update_cdf = tile_data->allow_update_cdf && row_mt_enabled; if (update_cdf && (tile_info->mi_row_start != mi_row)) { if ((tile_info->mi_col_start == mi_col)) { @@ -904,8 +927,6 @@ TokenList *tplist = token_info->tplist[0][0]; unsigned int tile_tok = 0; int tplist_count = 0; - const CostUpdateFreq *const cost_upd_freq = &cpi->oxcf.cost_upd_freq; - const int rtc_mode = is_rtc_mode(cost_upd_freq, cpi->oxcf.mode); if (!is_stat_generation_stage(cpi) && cm->features.allow_screen_content_tools) { @@ -949,7 +970,7 @@ tile_data->allow_update_cdf = !cm->tiles.large_scale; tile_data->allow_update_cdf = tile_data->allow_update_cdf && !cm->features.disable_cdf_update && - !rtc_mode; + !delay_wait_for_top_right_sb(cpi); tile_data->tctx = *cm->fc; } }
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c index f010a20..61aa878 100644 --- a/av1/encoder/partition_search.c +++ b/av1/encoder/partition_search.c
@@ -713,9 +713,9 @@ av1_nonrd_pick_intra_mode(cpi, x, rd_cost, bsize, ctx); } -// For real time row-mt enabled multi-threaded encoding with cost update -// frequency set to COST_UPD_TILE/COST_UPD_OFF, tile ctxt is not updated at -// superblock level. Thus, it is not required for the encoding of top-right +// For real time/allintra row-mt enabled multi-threaded encoding with cost +// update frequency set to COST_UPD_TILE/COST_UPD_OFF, tile ctxt is not updated +// at superblock level. Thus, it is not required for the encoding of top-right // superblock be complete for updating tile ctxt. However, when encoding a block // whose right edge is also the superblock edge, intra and inter mode evaluation // (ref mv list population) require the encoding of the top-right superblock to @@ -812,8 +812,8 @@ int i; - // This is only needed for real time row-mt enabled multi-threaded encoding - // with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF. + // This is only needed for real time/allintra row-mt enabled multi-threaded + // encoding with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF. wait_for_top_right_sb(&cpi->mt_info.enc_row_mt, &tile_data->row_mt_sync, &tile_data->tile_info, cm->seq_params->sb_size, cm->seq_params->mib_size_log2, bsize, mi_row, mi_col); @@ -2148,8 +2148,8 @@ TxfmSearchInfo *txfm_info = &x->txfm_search_info; int i; - // This is only needed for real time row-mt enabled multi-threaded encoding - // with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF. + // This is only needed for real time/allintra row-mt enabled multi-threaded + // encoding with cost update frequency set to COST_UPD_TILE/COST_UPD_OFF. wait_for_top_right_sb(&cpi->mt_info.enc_row_mt, &tile_data->row_mt_sync, &tile_data->tile_info, cm->seq_params->sb_size, cm->seq_params->mib_size_log2, bsize, mi_row, mi_col);