/* * Copyright (c) 2016, 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.
*/
staticvoid auto_tile_size_balancing(AV1_COMMON *const cm, int num_sbs, int num_tiles_lg, int tile_col_row) {
CommonTileParams *const tiles = &cm->tiles; int i, start_sb; int size_sb = num_sbs >> num_tiles_lg; int res_sbs = num_sbs - (size_sb << num_tiles_lg); int num_tiles = 1 << num_tiles_lg; int inc_index = num_tiles - res_sbs;
tiles->uniform_spacing = 0;
for (i = 0, start_sb = 0; start_sb < num_sbs && i < MAX_TILE_COLS; ++i) { if (i == inc_index) ++size_sb; if (tile_col_row)
tiles->col_start_sb[i] = start_sb; else
tiles->row_start_sb[i] = start_sb;
// Setup mi_params here in case we need more mi's.
CommonModeInfoParams *const mi_params = &cm->mi_params;
mi_params->set_mb_mi(mi_params, cm->width, cm->height,
cpi->sf.part_sf.default_min_partition_size);
av1_init_macroblockd(cm, xd);
if (!cpi->ppi->seq_params_locked)
set_sb_size(cm->seq_params,
av1_select_sb_size(&cpi->oxcf, cm->width, cm->height,
cpi->ppi->number_spatial_layers));
staticvoid set_bitstream_level_tier(AV1_PRIMARY *const ppi, int width, int height, double init_framerate) {
SequenceHeader *const seq_params = &ppi->seq_params; const AV1LevelParams *const level_params = &ppi->level_params; // TODO(any): This is a placeholder function that only addresses dimensions // and max display sample rates. // Need to add checks for max bit rate, max decoded luma sample rate, header // rate, etc. that are not covered by this function.
AV1_LEVEL level = SEQ_LEVEL_MAX; if (does_level_match(width, height, init_framerate, 512, 288, 30.0, 4)) {
level = SEQ_LEVEL_2_0;
} elseif (does_level_match(width, height, init_framerate, 704, 396, 30.0,
4)) {
level = SEQ_LEVEL_2_1;
} elseif (does_level_match(width, height, init_framerate, 1088, 612, 30.0,
4)) {
level = SEQ_LEVEL_3_0;
} elseif (does_level_match(width, height, init_framerate, 1376, 774, 30.0,
4)) {
level = SEQ_LEVEL_3_1;
} elseif (does_level_match(width, height, init_framerate, 2048, 1152, 30.0,
3)) {
level = SEQ_LEVEL_4_0;
} elseif (does_level_match(width, height, init_framerate, 2048, 1152, 60.0,
3)) {
level = SEQ_LEVEL_4_1;
} elseif (does_level_match(width, height, init_framerate, 4096, 2176, 30.0,
2)) {
level = SEQ_LEVEL_5_0;
} elseif (does_level_match(width, height, init_framerate, 4096, 2176, 60.0,
2)) {
level = SEQ_LEVEL_5_1;
} elseif (does_level_match(width, height, init_framerate, 4096, 2176, 120.0,
2)) {
level = SEQ_LEVEL_5_2;
} elseif (does_level_match(width, height, init_framerate, 8192, 4352, 30.0,
2)) {
level = SEQ_LEVEL_6_0;
} elseif (does_level_match(width, height, init_framerate, 8192, 4352, 60.0,
2)) {
level = SEQ_LEVEL_6_1;
} elseif (does_level_match(width, height, init_framerate, 8192, 4352, 120.0,
2)) {
level = SEQ_LEVEL_6_2;
} #if CONFIG_CWG_C013 // TODO(bohanli): currently target level is only working for the 0th operating // point, so scalable coding is not supported. elseif (level_params->target_seq_level_idx[0] >= SEQ_LEVEL_7_0 &&
level_params->target_seq_level_idx[0] <= SEQ_LEVEL_8_3) { // Only use level 7.x to 8.x when explicitly asked to. if (does_level_match(width, height, init_framerate, 16384, 8704, 30.0, 2)) {
level = SEQ_LEVEL_7_0;
} elseif (does_level_match(width, height, init_framerate, 16384, 8704,
60.0, 2)) {
level = SEQ_LEVEL_7_1;
} elseif (does_level_match(width, height, init_framerate, 16384, 8704,
120.0, 2)) {
level = SEQ_LEVEL_7_2;
} elseif (does_level_match(width, height, init_framerate, 32768, 17408,
30.0, 2)) {
level = SEQ_LEVEL_8_0;
} elseif (does_level_match(width, height, init_framerate, 32768, 17408,
60.0, 2)) {
level = SEQ_LEVEL_8_1;
} elseif (does_level_match(width, height, init_framerate, 32768, 17408,
120.0, 2)) {
level = SEQ_LEVEL_8_2;
}
} #endif
for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
assert(is_valid_seq_level_idx(level_params->target_seq_level_idx[i]) ||
level_params->target_seq_level_idx[i] == SEQ_LEVEL_KEEP_STATS); // If a higher target level is specified, it is then used rather than the // inferred one from resolution and framerate.
seq_params->seq_level_idx[i] =
level_params->target_seq_level_idx[i] < SEQ_LEVELS &&
level_params->target_seq_level_idx[i] > level
? level_params->target_seq_level_idx[i]
: level; // Set the maximum parameters for bitrate and buffer size for this profile, // level, and tier
seq_params->op_params[i].bitrate = av1_max_level_bitrate(
seq_params->profile, seq_params->seq_level_idx[i], seq_params->tier[i]); // Level with seq_level_idx = 31 returns a high "dummy" bitrate to pass the // check if (seq_params->op_params[i].bitrate == 0)
aom_internal_error(
&ppi->error, AOM_CODEC_UNSUP_BITSTREAM, "AV1 does not support this combination of profile, level, and tier."); // Buffer size in bits/s is bitrate in bits/s * 1 s
seq_params->op_params[i].buffer_size = seq_params->op_params[i].bitrate;
}
}
int sb_size = seq_params->sb_size; // Superblock size should not be updated after the first key frame. if (!ppi->seq_params_locked) {
set_sb_size(seq_params, av1_select_sb_size(oxcf, frm_dim_cfg->width,
frm_dim_cfg->height,
ppi->number_spatial_layers)); for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i)
seq_params->tier[i] = (oxcf->tier_mask >> i) & 1;
} if (is_sb_size_changed != NULL && sb_size != seq_params->sb_size)
*is_sb_size_changed = true;
// Init sequence level coding tools // This should not be called after the first key frame. if (!ppi->seq_params_locked) {
seq_params->operating_points_cnt_minus_1 =
(ppi->number_spatial_layers > 1 || ppi->number_temporal_layers > 1)
? ppi->number_spatial_layers * ppi->number_temporal_layers - 1
: 0;
init_seq_coding_tools(ppi, oxcf,
ppi->use_svc || ppi->rtc_ref.set_ref_frame_config);
}
seq_params->timing_info_present &= !seq_params->reduced_still_picture_hdr;
// in case of LAP, lag in frames is set according to number of lap buffers // calculated at init time. This stores and restores LAP's lag in frames to // prevent override by new cfg. int lap_lag_in_frames = -1; if (cpi->ppi->lap_enabled && cpi->compressor_stage == LAP_STAGE) {
lap_lag_in_frames = cpi->oxcf.gf_cfg.lag_in_frames;
}
// When user provides superres_mode = AOM_SUPERRES_AUTO, we still initialize // superres mode for current encoding = AOM_SUPERRES_NONE. This is to ensure // that any analysis (e.g. TPL) happening outside the main encoding loop still // happens at full resolution. // This value will later be set appropriately just before main encoding loop.
cpi->superres_mode = oxcf->superres_cfg.superres_mode == AOM_SUPERRES_AUTO
? AOM_SUPERRES_NONE
: oxcf->superres_cfg.superres_mode; // default
x->e_mbd.bd = (int)seq_params->bit_depth;
x->e_mbd.global_motion = cm->global_motion;
memcpy(level_params->target_seq_level_idx, cpi->oxcf.target_seq_level_idx, sizeof(level_params->target_seq_level_idx));
level_params->keep_level_stats = 0; for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) { if (level_params->target_seq_level_idx[i] < SEQ_LEVELS ||
level_params->target_seq_level_idx[i] == SEQ_LEVEL_KEEP_STATS) {
level_params->keep_level_stats |= 1u << i; if (!level_params->level_info[i]) {
CHECK_MEM_ERROR(cm, level_params->level_info[i],
aom_calloc(1, sizeof(*level_params->level_info[i])));
}
}
}
// TODO(huisu@): level targeting currently only works for the 0th operating // point, so scalable coding is not supported yet. if (level_params->target_seq_level_idx[0] < SEQ_LEVELS) { // Adjust encoder config in order to meet target level.
config_target_level(cpi, level_params->target_seq_level_idx[0],
seq_params->tier[0]);
}
if (has_no_stats_stage(cpi) && (rc_cfg->mode == AOM_Q)) {
p_rc->baseline_gf_interval = FIXED_GF_INTERVAL;
} elseif (!is_one_pass_rt_params(cpi) ||
cm->current_frame.frame_number == 0) { // For rtc mode: logic for setting the baseline_gf_interval is done // in av1_get_one_pass_rt_params(), and it should not be reset here in // change_config(), unless after init_config (first frame).
p_rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
}
if (x->palette_buffer == NULL) {
CHECK_MEM_ERROR(cm, x->palette_buffer,
aom_memalign(16, sizeof(*x->palette_buffer)));
}
if (x->tmp_conv_dst == NULL) {
CHECK_MEM_ERROR(
cm, x->tmp_conv_dst,
aom_memalign(32, MAX_SB_SIZE * MAX_SB_SIZE * sizeof(*x->tmp_conv_dst)));
x->e_mbd.tmp_conv_dst = x->tmp_conv_dst;
} // The buffers 'tmp_pred_bufs[]' and 'comp_rd_buffer' are used in inter frames // to store intermediate inter mode prediction results and are not required // for allintra encoding mode. Hence, the memory allocations for these buffers // are avoided for allintra encoding mode. if (cpi->oxcf.kf_cfg.key_freq_max != 0) { if (x->comp_rd_buffer.pred0 == NULL)
alloc_compound_type_rd_buffers(cm->error, &x->comp_rd_buffer);
for (int i = 0; i < 2; ++i) { if (x->tmp_pred_bufs[i] == NULL) {
CHECK_MEM_ERROR(cm, x->tmp_pred_bufs[i],
aom_memalign(32, 2 * MAX_MB_PLANE * MAX_SB_SQUARE * sizeof(*x->tmp_pred_bufs[i])));
x->e_mbd.tmp_obmc_bufs[i] = x->tmp_pred_bufs[i];
}
}
}
av1_reset_segment_features(cm);
av1_set_high_precision_mv(cpi, 1, 0);
// Under a configuration change, where maximum_buffer_size may change, // keep buffer level clipped to the maximum allowed buffer size.
p_rc->bits_off_target =
AOMMIN(p_rc->bits_off_target, p_rc->maximum_buffer_size);
p_rc->buffer_level = AOMMIN(p_rc->buffer_level, p_rc->maximum_buffer_size);
// Set up frame rate and related parameters rate control values.
av1_new_framerate(cpi, cpi->framerate);
// Set absolute upper and lower quality limits
rc->worst_quality = rc_cfg->worst_allowed_q;
rc->best_quality = rc_cfg->best_allowed_q;
// If lossless has been requested make sure average Q accumulators are reset. if (is_lossless_requested(&cpi->oxcf.rc_cfg)) { int i; for (i = 0; i < FRAME_TYPES; ++i) {
p_rc->avg_frame_qindex[i] = 0;
}
}
AV1_PRIMARY *av1_create_primary_compressor( struct aom_codec_pkt_list *pkt_list_head, int num_lap_buffers, const AV1EncoderConfig *oxcf) {
AV1_PRIMARY *volatileconst ppi = aom_memalign(32, sizeof(AV1_PRIMARY)); if (!ppi) return NULL;
av1_zero(*ppi);
// The jmp_buf is valid only for the duration of the function that calls // setjmp(). Therefore, this function must reset the 'setjmp' field to 0 // before it returns. if (setjmp(ppi->error.jmp)) {
ppi->error.setjmp = 0;
av1_remove_primary_compressor(ppi); return 0;
}
ppi->error.setjmp = 1;
{ // As cm->mi_params is a part of the frame level context (cpi), it is // unavailable at this point. mi_params is created as a local temporary // variable, to be passed into the functions used for allocating tpl // buffers. The values in this variable are populated according to initial // width and height of the frame.
CommonModeInfoParams mi_params;
enc_set_mb_mi(&mi_params, oxcf->frm_dim_cfg.width, oxcf->frm_dim_cfg.height,
BLOCK_4X4);
const BLOCK_SIZE bsize = BLOCK_16X16; constint w = mi_size_wide[bsize]; constint h = mi_size_high[bsize]; constint num_cols = (mi_params.mi_cols + w - 1) / w; constint num_rows = (mi_params.mi_rows + h - 1) / h;
AOM_CHECK_MEM_ERROR(
&ppi->error, ppi->tpl_sb_rdmult_scaling_factors,
aom_calloc(num_rows * num_cols, sizeof(*ppi->tpl_sb_rdmult_scaling_factors)));
// The jmp_buf is valid only for the duration of the function that calls // setjmp(). Therefore, this function must reset the 'setjmp' field to 0 // before it returns. if (setjmp(cm->error->jmp)) {
cm->error->setjmp = 0;
av1_remove_compressor(cpi); return NULL;
}
if (!cpi->ppi->lap_enabled) { /*Re-initialize to stats buffer, populated by application in the case of
* two pass*/
cpi->ppi->twopass.stats_buf_ctx->stats_in_start =
oxcf->twopass_stats_in.buf;
cpi->twopass_frame.stats_in =
cpi->ppi->twopass.stats_buf_ctx->stats_in_start;
cpi->ppi->twopass.stats_buf_ctx->stats_in_end =
&cpi->ppi->twopass.stats_buf_ctx->stats_in_start[packets - 1];
// The buffer size is packets - 1 because the last packet is total_stats.
av1_firstpass_info_init(&cpi->ppi->twopass.firstpass_info,
oxcf->twopass_stats_in.buf, packets - 1);
av1_init_second_pass(cpi);
} else {
av1_firstpass_info_init(&cpi->ppi->twopass.firstpass_info, NULL, 0);
av1_init_single_pass_lap(cpi);
}
} #endif
// The buffer "obmc_buffer" is used in inter frames for fast obmc search. // Hence, the memory allocation for the same is avoided for allintra encoding // mode. if (cpi->oxcf.kf_cfg.key_freq_max != 0)
alloc_obmc_buffers(&cpi->td.mb.obmc_buffer, cm->error);
for (int x = 0; x < 2; x++) for (int y = 0; y < 2; y++)
CHECK_MEM_ERROR(
cm, cpi->td.mb.intrabc_hash_info.hash_value_buffer[x][y],
(uint32_t *)aom_malloc(
AOM_BUFFER_SIZE_FOR_BLOCK_HASH * sizeof(*cpi->td.mb.intrabc_hash_info.hash_value_buffer[0][0])));
#if CONFIG_TUNE_VMAF
{ const BLOCK_SIZE bsize = BLOCK_64X64; constint w = mi_size_wide[bsize]; constint h = mi_size_high[bsize]; constint num_cols = (mi_params->mi_cols + w - 1) / w; constint num_rows = (mi_params->mi_rows + h - 1) / h;
CHECK_MEM_ERROR(cm, cpi->vmaf_info.rdmult_scaling_factors,
aom_calloc(num_rows * num_cols, sizeof(*cpi->vmaf_info.rdmult_scaling_factors))); for (int i = 0; i < MAX_ARF_LAYERS; i++) {
cpi->vmaf_info.last_frame_unsharp_amount[i] = -1.0;
cpi->vmaf_info.last_frame_ysse[i] = -1.0;
cpi->vmaf_info.last_frame_vmaf[i] = -1.0;
}
cpi->vmaf_info.original_qindex = -1;
cpi->vmaf_info.vmaf_model = NULL;
} #endif
#if CONFIG_TUNE_BUTTERAUGLI
{ constint w = mi_size_wide[butteraugli_rdo_bsize]; constint h = mi_size_high[butteraugli_rdo_bsize]; constint num_cols = (mi_params->mi_cols + w - 1) / w; constint num_rows = (mi_params->mi_rows + h - 1) / h;
CHECK_MEM_ERROR(
cm, cpi->butteraugli_info.rdmult_scaling_factors,
aom_malloc(num_rows * num_cols * sizeof(*cpi->butteraugli_info.rdmult_scaling_factors)));
memset(&cpi->butteraugli_info.source, 0, sizeof(cpi->butteraugli_info.source));
memset(&cpi->butteraugli_info.resized_source, 0, sizeof(cpi->butteraugli_info.resized_source));
cpi->butteraugli_info.recon_set = false;
} #endif
#if CONFIG_SALIENCY_MAP
{
CHECK_MEM_ERROR(cm, cpi->saliency_map,
(uint8_t *)aom_calloc(cm->height * cm->width, sizeof(*cpi->saliency_map))); // Buffer initialization based on MIN_MIB_SIZE_LOG2 to ensure that // cpi->sm_scaling_factor buffer is allocated big enough, since we have no // idea of the actual superblock size we are going to use yet. constint min_mi_w_sb = (1 << MIN_MIB_SIZE_LOG2); constint min_mi_h_sb = (1 << MIN_MIB_SIZE_LOG2); constint max_sb_cols =
(cm->mi_params.mi_cols + min_mi_w_sb - 1) / min_mi_w_sb; constint max_sb_rows =
(cm->mi_params.mi_rows + min_mi_h_sb - 1) / min_mi_h_sb;
CHECK_MEM_ERROR(cm, cpi->sm_scaling_factor,
(double *)aom_calloc(max_sb_rows * max_sb_cols, sizeof(*cpi->sm_scaling_factor)));
} #endif
// Initialize the members of DeltaQuantParams with INT_MAX to ensure that // the quantizer tables are correctly initialized using the default deltaq // parameters when av1_init_quantizer is called for the first time.
DeltaQuantParams *const prev_deltaq_params =
&cpi->enc_quant_dequant_params.prev_deltaq_params;
prev_deltaq_params->y_dc_delta_q = INT_MAX;
prev_deltaq_params->u_dc_delta_q = INT_MAX;
prev_deltaq_params->v_dc_delta_q = INT_MAX;
prev_deltaq_params->u_ac_delta_q = INT_MAX;
prev_deltaq_params->v_ac_delta_q = INT_MAX;
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.