/* * Copyright (c) 2020, 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.
*/
/*!\file * \brief Defines utility functions used in intra mode search. * * This includes rdcost estimations, histogram based pruning, etc.
*/ #ifndef AOM_AV1_ENCODER_INTRA_MODE_SEARCH_UTILS_H_ #define AOM_AV1_ENCODER_INTRA_MODE_SEARCH_UTILS_H_
/*!\cond */ // Macro for computing the speed-preset dependent threshold which is used for // deciding whether to enable/disable variance calculations in // intra_rd_variance_factor(). #define INTRA_RD_VAR_THRESH(X) (1.0 - (0.25 * (X)))
// Gradient caching at superblock level is allowed only if all of the following // conditions are satisfied: // (1) The current frame is an intra only frame // (2) Non-RD mode decisions are not enabled // (3) The sf partition_search_type is set to SEARCH_PARTITION // (4) Either intra_pruning_with_hog or chroma_intra_pruning_with_hog is enabled // // SB level caching of gradient data may not help in speedup for the following // cases: // (1) Inter frames (due to early intra gating) // (2) When partition_search_type is not SEARCH_PARTITION // Hence, gradient data is computed at block level in such cases. staticinlinebool is_gradient_caching_for_hog_enabled( const AV1_COMP *const cpi) { const SPEED_FEATURES *const sf = &cpi->sf; return frame_is_intra_only(&cpi->common) && !sf->rt_sf.use_nonrd_pick_mode &&
(sf->part_sf.partition_search_type == SEARCH_PARTITION) &&
(sf->intra_sf.intra_pruning_with_hog ||
sf->intra_sf.chroma_intra_pruning_with_hog);
}
// Function to generate pixel level gradient information for a given superblock. // Sets the flags 'is_sb_gradient_cached' for the specific plane-type if // gradient info is generated for the same. staticinlinevoid produce_gradients_for_sb(AV1_COMP *cpi, MACROBLOCK *x,
BLOCK_SIZE sb_size, int mi_row, int mi_col) { // Initialise flags related to hog data caching.
x->is_sb_gradient_cached[PLANE_TYPE_Y] = false;
x->is_sb_gradient_cached[PLANE_TYPE_UV] = false; if (!is_gradient_caching_for_hog_enabled(cpi)) return;
// Returns whether caching of source variance for 4x4 sub-blocks is allowed. staticinlinebool is_src_var_for_4x4_sub_blocks_caching_enabled( const AV1_COMP *const cpi) { const SPEED_FEATURES *const sf = &cpi->sf; if (cpi->oxcf.mode != ALLINTRA) returnfalse;
if (sf->part_sf.partition_search_type == SEARCH_PARTITION) returntrue;
if (INTRA_RD_VAR_THRESH(cpi->oxcf.speed) <= 0 ||
(sf->rt_sf.use_nonrd_pick_mode && !sf->rt_sf.hybrid_intra_pickmode)) returnfalse;
returntrue;
}
// Initialize the members of Block4x4VarInfo structure to -1 at the start // of every superblock. staticinlinevoid init_src_var_info_of_4x4_sub_blocks( const AV1_COMP *const cpi, Block4x4VarInfo *src_var_info_of_4x4_sub_blocks, const BLOCK_SIZE sb_size) { if (!is_src_var_for_4x4_sub_blocks_caching_enabled(cpi)) return;
constint mi_count_in_sb = mi_size_wide[sb_size] * mi_size_high[sb_size]; for (int i = 0; i < mi_count_in_sb; i++) {
src_var_info_of_4x4_sub_blocks[i].var = -1;
src_var_info_of_4x4_sub_blocks[i].log_var = -1.0;
}
}
// Returns the cost needed to send a uniformly distributed r.v. staticinlineint write_uniform_cost(int n, int v) { constint l = get_unsigned_bits(n); constint m = (1 << l) - n; if (l == 0) return 0; if (v < m) return av1_cost_literal(l - 1); else return av1_cost_literal(l);
} /*!\endcond */
/*!\cond */ // Makes a quick intra prediction and estimate the rdcost with a model without // going through the whole txfm/quantize/itxfm process. static int64_t intra_model_rd(const AV1_COMMON *cm, MACROBLOCK *const x, int plane, BLOCK_SIZE plane_bsize,
TX_SIZE tx_size, int use_hadamard) {
MACROBLOCKD *const xd = &x->e_mbd; const BitDepthInfo bd_info = get_bit_depth_info(xd); int row, col;
assert(!is_inter_block(xd->mi[0])); constint stepr = tx_size_high_unit[tx_size]; constint stepc = tx_size_wide_unit[tx_size]; constint txbw = tx_size_wide[tx_size]; constint txbh = tx_size_high[tx_size]; constint max_blocks_wide = max_block_wide(xd, plane_bsize, plane); constint max_blocks_high = max_block_high(xd, plane_bsize, plane);
int64_t satd_cost = 0; struct macroblock_plane *p = &x->plane[plane]; struct macroblockd_plane *pd = &xd->plane[plane]; // Prediction. for (row = 0; row < max_blocks_high; row += stepr) { for (col = 0; col < max_blocks_wide; col += stepc) {
av1_predict_intra_block_facade(cm, xd, plane, col, row, tx_size); // Here we use p->src_diff and p->coeff as temporary buffers for // prediction residue and transform coefficients. The buffers are only // used in this for loop, therefore we don't need to properly add offset // to the buffers.
av1_subtract_block(
bd_info, txbh, txbw, p->src_diff, block_size_wide[plane_bsize],
p->src.buf + (((row * p->src.stride) + col) << 2), p->src.stride,
pd->dst.buf + (((row * pd->dst.stride) + col) << 2), pd->dst.stride);
av1_quick_txfm(use_hadamard, tx_size, bd_info, p->src_diff,
block_size_wide[plane_bsize], p->coeff);
satd_cost += aom_satd(p->coeff, tx_size_2d[tx_size]);
}
} return satd_cost;
} /*!\endcond */
/*!\brief Estimate the luma rdcost of a given intra mode and try to prune it. * * \ingroup intra_mode_search * \callergraph * This function first makes a quick luma prediction and estimates the rdcost * with a model without going through the txfm, then try to prune the current * mode if the new estimate y_rd > 1.25 * best_model_rd. * * \return Returns 1 if the given mode is prune; 0 otherwise.
*/ staticinlineint model_intra_yrd_and_prune(const AV1_COMP *const cpi,
MACROBLOCK *x, BLOCK_SIZE bsize,
int64_t *best_model_rd) { const TX_SIZE tx_size = AOMMIN(TX_32X32, max_txsize_lookup[bsize]); constint plane = 0; const AV1_COMMON *cm = &cpi->common; const int64_t this_model_rd =
intra_model_rd(cm, x, plane, bsize, tx_size, /*use_hadamard=*/1); if (*best_model_rd != INT64_MAX &&
this_model_rd > *best_model_rd + (*best_model_rd >> 2)) { return 1;
} elseif (this_model_rd < *best_model_rd) {
*best_model_rd = this_model_rd;
} return 0;
}
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.