/*!\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. static inline bool 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. static inline void 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;
const SPEED_FEATURES *sf = &cpi->sf; const int num_planes = av1_num_planes(&cpi->common);
// Reuses the pixel level gradient data generated at superblock level for block // level histogram computation. static inline void generate_hog_using_gradient_cache(const MACROBLOCK *x,
int rows, int cols,
BLOCK_SIZE sb_size,
PLANE_TYPE plane,
float *hist) {
float total = 0.1f; const int ss_x = x->e_mbd.plane[plane].subsampling_x; const int ss_y = x->e_mbd.plane[plane].subsampling_y; const int sb_width = block_size_wide[sb_size] >> ss_x;
// Derive the offset from the starting of the superblock in order to locate // the block level gradient data in the cache. const int mi_row_in_sb = x->e_mbd.mi_row & (mi_size_high[sb_size] - 1); const int mi_col_in_sb = x->e_mbd.mi_col & (mi_size_wide[sb_size] - 1); const int block_offset_in_grad_cache =
sb_width * (mi_row_in_sb << (MI_SIZE_LOG2 - ss_y)) +
(mi_col_in_sb << (MI_SIZE_LOG2 - ss_x)); const PixelLevelGradientInfo *grad_info_blk = x->pixel_gradient_info +
plane * MAX_SB_SQUARE +
block_offset_in_grad_cache;
// Retrieve the cached gradient information and generate the histogram.
for (int r = 1; r < rows - 1; ++r) {
for (int c = 1; c < cols - 1; ++c) { const uint16_t abs_dx_abs_dy_sum =
grad_info_blk[r * sb_width + c].abs_dx_abs_dy_sum;
if (!abs_dx_abs_dy_sum) continue;
total += abs_dx_abs_dy_sum; constbool is_dx_zero = grad_info_blk[r * sb_width + c].is_dx_zero;
if (is_dx_zero) {
hist[0] += abs_dx_abs_dy_sum >> 1;
hist[BINS - 1] += abs_dx_abs_dy_sum >> 1;
} else { const int8_t idx = grad_info_blk[r * sb_width + c].hist_bin_idx;
assert(idx >= 0 && idx < BINS);
hist[idx] += abs_dx_abs_dy_sum;
}
}
}
normalize_hog(total, hist);
}
// Make prediction for each of the mode
float scores[DIRECTIONAL_MODES] = { 0.0f };
av1_nn_predict(hist, &av1_intra_hog_model_nnconfig, 1, scores);
for (UV_PREDICTION_MODE uv_mode = UV_V_PRED; uv_mode <= UV_D67_PRED;
uv_mode++) {
if (scores[uv_mode - UV_V_PRED] <= th) {
directional_mode_skip_mask[uv_mode] = 1;
}
}
} #undef BINS
int av1_calc_normalized_variance(aom_variance_fn_t vf, const uint8_t *const buf, const int stride, const int is_hbd);
// Returns whether caching of source variance for 4x4 sub-blocks is allowed. static inline bool 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) return false;
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)) return false;
returntrue;
}
// Initialize the members of Block4x4VarInfo structure to -1 at the start // of every superblock. static inline void 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;
const int 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. static inline int write_uniform_cost(int n, int v) { const int l = get_unsigned_bits(n); const int m = (1 << l) - n;
if (l == 0) return0;
if (v < m) return av1_cost_literal(l - 1); else return av1_cost_literal(l);
} /*!\endcond */
/*!\brief Returns the rate cost for luma prediction mode info of intra blocks. * *\callergraph
*/ static inline int intra_mode_info_cost_y(const AV1_COMP *cpi, const MACROBLOCK *x, const MB_MODE_INFO *mbmi,
BLOCK_SIZE bsize, int mode_cost,
int discount_color_cost) {
int total_rate = mode_cost; const ModeCosts *mode_costs = &x->mode_costs; const int use_palette = mbmi->palette_mode_info.palette_size[0] > 0; const int use_filter_intra = mbmi->filter_intra_mode_info.use_filter_intra; const int use_intrabc = mbmi->use_intrabc; // Can only activate one mode.
assert(((mbmi->mode != DC_PRED) + use_palette + use_intrabc +
use_filter_intra) <= 1); const int try_palette = av1_allow_palette(
cpi->common.features.allow_screen_content_tools, mbmi->bsize);
if (try_palette && mbmi->mode == DC_PRED) { const MACROBLOCKD *xd = &x->e_mbd; const int bsize_ctx = av1_get_palette_bsize_ctx(bsize); const int mode_ctx = av1_get_palette_mode_ctx(xd);
total_rate +=
mode_costs->palette_y_mode_cost[bsize_ctx][mode_ctx][use_palette];
if (use_palette) { const uint8_t *const color_map = xd->plane[0].color_index_map;
int block_width, block_height, rows, cols;
av1_get_block_dimensions(bsize, 0, xd, &block_width, &block_height, &rows,
&cols); const int plt_size = mbmi->palette_mode_info.palette_size[0];
int palette_mode_cost =
mode_costs
->palette_y_size_cost[bsize_ctx][plt_size - PALETTE_MIN_SIZE] +
write_uniform_cost(plt_size, color_map[0]);
uint16_t color_cache[2 * PALETTE_MAX_SIZE]; const int n_cache = av1_get_palette_cache(xd, 0, color_cache);
palette_mode_cost +=
av1_palette_color_cost_y(&mbmi->palette_mode_info, color_cache,
n_cache, cpi->common.seq_params->bit_depth);
if (!discount_color_cost)
palette_mode_cost +=
av1_cost_color_map(x, 0, bsize, mbmi->tx_size, PALETTE_MAP);
total_rate += palette_mode_cost;
}
}
if (av1_filter_intra_allowed(&cpi->common, mbmi)) {
total_rate += mode_costs->filter_intra_cost[mbmi->bsize][use_filter_intra];
if (use_filter_intra) {
total_rate +=
mode_costs->filter_intra_mode_cost[mbmi->filter_intra_mode_info
.filter_intra_mode];
}
}
if (av1_is_directional_mode(mbmi->mode)) {
if (av1_use_angle_delta(bsize)) {
total_rate +=
mode_costs->angle_delta_cost[mbmi->mode - V_PRED]
[MAX_ANGLE_DELTA +
mbmi->angle_delta[PLANE_TYPE_Y]];
}
}
if (av1_allow_intrabc(&cpi->common))
total_rate += mode_costs->intrabc_cost[use_intrabc]; return total_rate;
}
/*!\brief Return the rate cost for chroma prediction mode info of intra blocks. * *\callergraph
*/ static inline int intra_mode_info_cost_uv(const AV1_COMP *cpi, const MACROBLOCK *x, const MB_MODE_INFO *mbmi,
BLOCK_SIZE bsize, int mode_cost) {
int total_rate = mode_cost; const ModeCosts *mode_costs = &x->mode_costs; const int use_palette = mbmi->palette_mode_info.palette_size[1] > 0; const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode; // Can only activate one mode.
assert(((uv_mode != UV_DC_PRED) + use_palette + mbmi->use_intrabc) <= 1);
/*!\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])); const int stepr = tx_size_high_unit[tx_size]; const int stepc = tx_size_wide_unit[tx_size]; const int txbw = tx_size_wide[tx_size]; const int txbh = tx_size_high[tx_size]; const int max_blocks_wide = max_block_wide(xd, plane_bsize, plane); const int 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. * *\ingroupintra_mode_search *\callergraph *Thisfunctionfirstmakesaquicklumapredictionandestimatestherdcost *withamodelwithoutgoingthroughthetxfm,thentrytoprunethecurrent *modeifthenewestimatey_rd>1.25*best_model_rd. * *\returnReturns1ifthegivenmodeisprune;0otherwise.
*/ static inline int 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]); const int 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)) { return1;
} else if (this_model_rd < *best_model_rd) {
*best_model_rd = this_model_rd;
} return0;
}
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.