/* * Copyright (c) 2019, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
// Number of winner modes allowed for different values of the speed feature // multi_winner_mode_type. staticconstint winner_mode_count_allowed[MULTI_WINNER_MODE_LEVELS] = {
1, // MULTI_WINNER_MODE_OFF
2, // MULTI_WINNER_MODE_FAST
3 // MULTI_WINNER_MODE_DEFAULT
};
staticinlinevoid restore_dst_buf(MACROBLOCKD *xd, const BUFFER_SET dst, constint num_planes) { for (int i = 0; i < num_planes; i++) {
xd->plane[i].dst.buf = dst.plane[i];
xd->plane[i].dst.stride = dst.stride[i];
}
}
// Get transform block visible dimensions cropped to the MI units. staticinlinevoid get_txb_dimensions(const MACROBLOCKD *xd, int plane,
BLOCK_SIZE plane_bsize, int blk_row, int blk_col, BLOCK_SIZE tx_bsize, int *width, int *height, int *visible_width, int *visible_height) {
assert(tx_bsize <= plane_bsize); constint txb_height = block_size_high[tx_bsize]; constint txb_width = block_size_wide[tx_bsize]; conststruct macroblockd_plane *const pd = &xd->plane[plane];
// TODO(aconverse@google.com): Investigate using crop_width/height here rather // than the MI size if (xd->mb_to_bottom_edge >= 0) {
*visible_height = txb_height;
} else { constint block_height = block_size_high[plane_bsize]; constint block_rows =
(xd->mb_to_bottom_edge >> (3 + pd->subsampling_y)) + block_height;
*visible_height =
clamp(block_rows - (blk_row << MI_SIZE_LOG2), 0, txb_height);
} if (height) *height = txb_height;
// Checks the conditions to disable winner mode processing staticinlineint bypass_winner_mode_processing(const MACROBLOCK *const x, const SPEED_FEATURES *sf, int use_txfm_skip, int actual_txfm_skip,
PREDICTION_MODE best_mode) { constint prune_winner_mode_eval_level =
sf->winner_mode_sf.prune_winner_mode_eval_level;
// Disable winner mode processing for blocks with low source variance. // The aggressiveness of this pruning logic reduces as qindex increases. // The threshold decreases linearly from 64 as qindex varies from 0 to 255. if (prune_winner_mode_eval_level == 1) { constunsignedint src_var_thresh = 64 - 48 * x->qindex / (MAXQ + 1); if (x->source_variance < src_var_thresh) return 1;
} elseif (prune_winner_mode_eval_level == 2) { // Skip winner mode processing of blocks for which transform turns out to be // skip due to nature of eob alone except NEWMV mode. if (!have_newmv_in_inter_mode(best_mode) && actual_txfm_skip) return 1;
} elseif (prune_winner_mode_eval_level == 3) { // Skip winner mode processing of blocks for which transform turns out to be // skip except NEWMV mode and considered based on the quantizer. // At high quantizers: Take conservative approach by considering transform // skip based on eob alone. // At low quantizers: Consider transform skip based on eob nature or RD cost // evaluation. constint is_txfm_skip =
x->qindex > 127 ? actual_txfm_skip : actual_txfm_skip || use_txfm_skip;
if (!have_newmv_in_inter_mode(best_mode) && is_txfm_skip) return 1;
} elseif (prune_winner_mode_eval_level >= 4) { // Do not skip winner mode evaluation at low quantizers if normal mode's // transform search was too aggressive. if (sf->rd_sf.perform_coeff_opt >= 5 && x->qindex <= 70) return 0;
if (use_txfm_skip || actual_txfm_skip) return 1;
}
staticinlinevoid set_tx_domain_dist_params( const WinnerModeParams *winner_mode_params, TxfmSearchParams *txfm_params, int enable_winner_mode_for_tx_domain_dist, int is_winner_mode) { if (txfm_params->use_qm_dist_metric) { // QM-weighted PSNR is computed in transform space, so we need to forcibly // enable the use of tx domain distortion.
txfm_params->use_transform_domain_distortion = 1;
txfm_params->tx_domain_dist_threshold = 0; return;
}
switch (mode_eval_type) { case DEFAULT_EVAL:
txfm_params->default_inter_tx_type_prob_thresh = INT_MAX;
txfm_params->use_default_intra_tx_type = 0;
txfm_params->skip_txfm_level =
winner_mode_params->skip_txfm_level[DEFAULT_EVAL];
txfm_params->predict_dc_level =
winner_mode_params->predict_dc_level[DEFAULT_EVAL]; // Set default transform domain distortion type
set_tx_domain_dist_params(winner_mode_params, txfm_params, 0, 0);
// Get default threshold for R-D optimization of coefficients
get_rd_opt_coeff_thresh(winner_mode_params->coeff_opt_thresholds,
txfm_params, 0, 0);
// Set default transform size search method
set_tx_size_search_method(cm, winner_mode_params, txfm_params, 0, 0); // Set default transform type prune
set_tx_type_prune(sf, txfm_params, 0, 0); break; case MODE_EVAL:
txfm_params->use_default_intra_tx_type =
(cpi->sf.tx_sf.tx_type_search.fast_intra_tx_type_search ||
cpi->oxcf.txfm_cfg.use_intra_default_tx_only);
txfm_params->default_inter_tx_type_prob_thresh =
cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh;
txfm_params->skip_txfm_level =
winner_mode_params->skip_txfm_level[MODE_EVAL];
txfm_params->predict_dc_level =
winner_mode_params->predict_dc_level[MODE_EVAL]; // Set transform domain distortion type for mode evaluation
set_tx_domain_dist_params(
winner_mode_params, txfm_params,
sf->winner_mode_sf.enable_winner_mode_for_use_tx_domain_dist, 0);
// Get threshold for R-D optimization of coefficients during mode // evaluation
get_rd_opt_coeff_thresh(
winner_mode_params->coeff_opt_thresholds, txfm_params,
sf->winner_mode_sf.enable_winner_mode_for_coeff_opt, 0);
// Set the transform size search method for mode evaluation
set_tx_size_search_method(
cm, winner_mode_params, txfm_params,
sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch, 0); // Set transform type prune for mode evaluation
set_tx_type_prune(sf, txfm_params,
sf->tx_sf.tx_type_search.winner_mode_tx_type_pruning,
0); break; case WINNER_MODE_EVAL:
txfm_params->default_inter_tx_type_prob_thresh = INT_MAX;
txfm_params->use_default_intra_tx_type = 0;
txfm_params->skip_txfm_level =
winner_mode_params->skip_txfm_level[WINNER_MODE_EVAL];
txfm_params->predict_dc_level =
winner_mode_params->predict_dc_level[WINNER_MODE_EVAL];
// Set transform domain distortion type for winner mode evaluation
set_tx_domain_dist_params(
winner_mode_params, txfm_params,
sf->winner_mode_sf.enable_winner_mode_for_use_tx_domain_dist, 1);
// Get threshold for R-D optimization of coefficients for winner mode // evaluation
get_rd_opt_coeff_thresh(
winner_mode_params->coeff_opt_thresholds, txfm_params,
sf->winner_mode_sf.enable_winner_mode_for_coeff_opt, 1);
// Set the transform size search method for winner mode evaluation
set_tx_size_search_method(
cm, winner_mode_params, txfm_params,
sf->winner_mode_sf.enable_winner_mode_for_tx_size_srch, 1); // Set default transform type prune mode for winner mode evaluation
set_tx_type_prune(sf, txfm_params,
sf->tx_sf.tx_type_search.winner_mode_tx_type_pruning,
1); break; default: assert(0);
}
// Rd record collected at a specific mode evaluation stage can not be used // across other evaluation stages as the transform parameters are different. // Hence, reset mb rd record whenever mode evaluation stage type changes. if (txfm_params->mode_eval_type != mode_eval_type)
reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
txfm_params->mode_eval_type = mode_eval_type;
}
// Similar to store_cfl_required(), but for use during the RDO process, // where we haven't yet determined whether this block uses CfL. staticinline CFL_ALLOWED_TYPE store_cfl_required_rdo(const AV1_COMMON *cm, const MACROBLOCK *x) { const MACROBLOCKD *xd = &x->e_mbd;
if (cm->seq_params->monochrome || !xd->is_chroma_ref) return CFL_DISALLOWED;
if (!xd->is_chroma_ref) { // For non-chroma-reference blocks, we should always store the luma pixels, // in case the corresponding chroma-reference block uses CfL. // Note that this can only happen for block sizes which are <8 on // their shortest side, as otherwise they would be chroma reference // blocks. return CFL_ALLOWED;
}
// For chroma reference blocks, we should store data in the encoder iff we're // allowed to try out CfL. return is_cfl_allowed(xd);
}
// Store best mode stats for winner mode processing staticinlinevoid store_winner_mode_stats( const AV1_COMMON *const cm, MACROBLOCK *x, const MB_MODE_INFO *mbmi,
RD_STATS *rd_cost, RD_STATS *rd_cost_y, RD_STATS *rd_cost_uv,
THR_MODES mode_index, uint8_t *color_map, BLOCK_SIZE bsize, int64_t this_rd, int multi_winner_mode_type, int txfm_search_done) {
WinnerModeStats *winner_mode_stats = x->winner_mode_stats; int mode_idx = 0; int is_palette_mode = mbmi->palette_mode_info.palette_size[PLANE_TYPE_Y] > 0; // Mode stat is not required when multiwinner mode processing is disabled if (multi_winner_mode_type == MULTI_WINNER_MODE_OFF) return; // Ignore mode with maximum rd if (this_rd == INT64_MAX) return; // TODO(any): Winner mode processing is currently not applicable for palette // mode in Inter frames. Clean-up the following code, once support is added if (!frame_is_intra_only(cm) && is_palette_mode) return;
if (x->winner_mode_count) { // Find the mode which has higher rd cost than this_rd for (mode_idx = 0; mode_idx < x->winner_mode_count; mode_idx++) if (winner_mode_stats[mode_idx].rd > this_rd) break;
if (mode_idx == max_winner_mode_count) { // No mode has higher rd cost than this_rd return;
} elseif (mode_idx < max_winner_mode_count - 1) { // Create a slot for current mode and move others to the next slot
memmove(
&winner_mode_stats[mode_idx + 1], &winner_mode_stats[mode_idx],
(max_winner_mode_count - mode_idx - 1) * sizeof(*winner_mode_stats));
}
} // Add a mode stat for winner mode processing
winner_mode_stats[mode_idx].mbmi = *mbmi;
winner_mode_stats[mode_idx].rd = this_rd;
winner_mode_stats[mode_idx].mode_index = mode_index;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.