diff options
Diffstat (limited to 'third_party/libaom/source/libaom/av1/encoder/aq_cyclicrefresh.c')
-rw-r--r-- | third_party/libaom/source/libaom/av1/encoder/aq_cyclicrefresh.c | 114 |
1 files changed, 80 insertions, 34 deletions
diff --git a/third_party/libaom/source/libaom/av1/encoder/aq_cyclicrefresh.c b/third_party/libaom/source/libaom/av1/encoder/aq_cyclicrefresh.c index c7abe43c87..40b8c254d4 100644 --- a/third_party/libaom/source/libaom/av1/encoder/aq_cyclicrefresh.c +++ b/third_party/libaom/source/libaom/av1/encoder/aq_cyclicrefresh.c @@ -12,6 +12,7 @@ #include <limits.h> #include <math.h> +#include "av1/common/pred_common.h" #include "av1/common/seg_common.h" #include "av1/encoder/aq_cyclicrefresh.h" #include "av1/encoder/ratectrl.h" @@ -82,7 +83,7 @@ static int compute_deltaq(const AV1_COMP *cpi, int q, double rate_factor) { const RATE_CONTROL *const rc = &cpi->rc; int deltaq = av1_compute_qdelta_by_rate( rc, cpi->common.current_frame.frame_type, q, rate_factor, - cpi->is_screen_content_type, cpi->common.seq_params.bit_depth); + cpi->is_screen_content_type, cpi->common.seq_params->bit_depth); if ((-deltaq) > cr->max_qdelta_perc * q / 100) { deltaq = -cr->max_qdelta_perc * q / 100; } @@ -94,7 +95,7 @@ int av1_cyclic_refresh_estimate_bits_at_q(const AV1_COMP *cpi, const AV1_COMMON *const cm = &cpi->common; const FRAME_TYPE frame_type = cm->current_frame.frame_type; const int base_qindex = cm->quant_params.base_qindex; - const int bit_depth = cm->seq_params.bit_depth; + const int bit_depth = cm->seq_params->bit_depth; const CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; const int mbs = cm->mi_params.MBs; const int num4x4bl = mbs << 4; @@ -138,15 +139,51 @@ int av1_cyclic_refresh_rc_bits_per_mb(const AV1_COMP *cpi, int i, bits_per_mb = (int)((1.0 - weight_segment) * av1_rc_bits_per_mb(cm->current_frame.frame_type, i, - correction_factor, cm->seq_params.bit_depth, + correction_factor, cm->seq_params->bit_depth, cpi->is_screen_content_type) + weight_segment * av1_rc_bits_per_mb(cm->current_frame.frame_type, i + deltaq, correction_factor, - cm->seq_params.bit_depth, + cm->seq_params->bit_depth, cpi->is_screen_content_type)); return bits_per_mb; } +void av1_cyclic_reset_segment_skip(const AV1_COMP *cpi, MACROBLOCK *const x, + int mi_row, int mi_col, BLOCK_SIZE bsize) { + int cdf_num; + const AV1_COMMON *const cm = &cpi->common; + MACROBLOCKD *const xd = &x->e_mbd; + MB_MODE_INFO *const mbmi = xd->mi[0]; + const int prev_segment_id = mbmi->segment_id; + mbmi->segment_id = av1_get_spatial_seg_pred(cm, xd, &cdf_num); + if (prev_segment_id != mbmi->segment_id) { + CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; + const int bw = mi_size_wide[bsize]; + const int bh = mi_size_high[bsize]; + const int xmis = AOMMIN(cm->mi_params.mi_cols - mi_col, bw); + const int ymis = AOMMIN(cm->mi_params.mi_rows - mi_row, bh); + const int block_index = mi_row * cm->mi_params.mi_cols + mi_col; + for (int mi_y = 0; mi_y < ymis; mi_y++) { + for (int mi_x = 0; mi_x < xmis; mi_x++) { + const int map_offset = + block_index + mi_y * cm->mi_params.mi_cols + mi_x; + cr->map[map_offset] = 0; + cpi->enc_seg.map[map_offset] = mbmi->segment_id; + cm->cur_frame->seg_map[map_offset] = mbmi->segment_id; + } + } + if (cyclic_refresh_segment_id(prev_segment_id) == CR_SEGMENT_ID_BOOST1) + x->actual_num_seg1_blocks -= xmis * ymis; + else if (cyclic_refresh_segment_id(prev_segment_id) == CR_SEGMENT_ID_BOOST2) + x->actual_num_seg2_blocks -= xmis * ymis; + if (cyclic_refresh_segment_id(mbmi->segment_id) == CR_SEGMENT_ID_BOOST1) + x->actual_num_seg1_blocks += xmis * ymis; + else if (cyclic_refresh_segment_id(mbmi->segment_id) == + CR_SEGMENT_ID_BOOST2) + x->actual_num_seg2_blocks += xmis * ymis; + } +} + void av1_cyclic_refresh_update_segment(const AV1_COMP *cpi, MACROBLOCK *const x, int mi_row, int mi_col, BLOCK_SIZE bsize, int64_t rate, int64_t dist, int skip, @@ -191,22 +228,21 @@ void av1_cyclic_refresh_update_segment(const AV1_COMP *cpi, MACROBLOCK *const x, // Update entries in the cyclic refresh map with new_map_value, and // copy mbmi->segment_id into global segmentation map. - // 8x8 is smallest coding block size for non-key frames. - const int sh = bw << 1; - for (int mi_y = 0; mi_y < ymis; mi_y += 2) { - for (int mi_x = 0; mi_x < xmis; mi_x += 2) { - int map_offset = block_index + mi_y * cm->mi_params.mi_cols + mi_x; + for (int mi_y = 0; mi_y < ymis; mi_y++) { + for (int mi_x = 0; mi_x < xmis; mi_x++) { + const int map_offset = block_index + mi_y * cm->mi_params.mi_cols + mi_x; cr->map[map_offset] = new_map_value; cpi->enc_seg.map[map_offset] = mbmi->segment_id; + cm->cur_frame->seg_map[map_offset] = mbmi->segment_id; } - // Accumulate cyclic refresh update counters. - if (!dry_run && !frame_is_intra_only(cm)) { - if (cyclic_refresh_segment_id(mbmi->segment_id) == CR_SEGMENT_ID_BOOST1) - x->actual_num_seg1_blocks += sh; - else if (cyclic_refresh_segment_id(mbmi->segment_id) == - CR_SEGMENT_ID_BOOST2) - x->actual_num_seg2_blocks += sh; - } + } + // Accumulate cyclic refresh update counters. + if (!dry_run) { + if (cyclic_refresh_segment_id(mbmi->segment_id) == CR_SEGMENT_ID_BOOST1) + x->actual_num_seg1_blocks += xmis * ymis; + else if (cyclic_refresh_segment_id(mbmi->segment_id) == + CR_SEGMENT_ID_BOOST2) + x->actual_num_seg2_blocks += xmis * ymis; } } @@ -234,15 +270,15 @@ void av1_cyclic_refresh_postencode(AV1_COMP *const cpi) { const int avg_cnt_zeromv = 100 * cr->cnt_zeromv / (mi_params->mi_rows * mi_params->mi_cols); - if (!cpi->use_svc || - (cpi->use_svc && + if (!cpi->ppi->use_svc || + (cpi->ppi->use_svc && !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame && cpi->svc.spatial_layer_id == cpi->svc.number_spatial_layers - 1)) { rc->avg_frame_low_motion = (3 * rc->avg_frame_low_motion + avg_cnt_zeromv) / 4; // For SVC: set avg_frame_low_motion (only computed on top spatial layer) // to all lower spatial layers. - if (cpi->use_svc && + if (cpi->ppi->use_svc && svc->spatial_layer_id == svc->number_spatial_layers - 1) { for (int i = 0; i < svc->number_spatial_layers - 1; ++i) { const int layer = LAYER_IDS_TO_IDX(i, svc->temporal_layer_id, @@ -257,15 +293,16 @@ void av1_cyclic_refresh_postencode(AV1_COMP *const cpi) { void av1_cyclic_refresh_set_golden_update(AV1_COMP *const cpi) { RATE_CONTROL *const rc = &cpi->rc; + PRIMARY_RATE_CONTROL *const p_rc = &cpi->ppi->p_rc; CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; // Set minimum gf_interval for GF update to a multiple of the refresh period, // with some max limit. Depending on past encoding stats, GF flag may be // reset and update may not occur until next baseline_gf_interval. if (cr->percent_refresh > 0) - rc->baseline_gf_interval = AOMMIN(2 * (100 / cr->percent_refresh), 40); + p_rc->baseline_gf_interval = AOMMIN(2 * (100 / cr->percent_refresh), 40); else - rc->baseline_gf_interval = 20; - if (rc->avg_frame_low_motion < 40) rc->baseline_gf_interval = 8; + p_rc->baseline_gf_interval = 20; + if (rc->avg_frame_low_motion < 40) p_rc->baseline_gf_interval = 8; } // Update the segmentation map, and related quantities: cyclic refresh map, @@ -282,10 +319,10 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) { int i, block_count, bl_index, sb_rows, sb_cols, sbs_in_frame; int xmis, ymis, x, y; memset(seg_map, CR_SEGMENT_ID_BASE, mi_params->mi_rows * mi_params->mi_cols); - sb_cols = (mi_params->mi_cols + cm->seq_params.mib_size - 1) / - cm->seq_params.mib_size; - sb_rows = (mi_params->mi_rows + cm->seq_params.mib_size - 1) / - cm->seq_params.mib_size; + sb_cols = (mi_params->mi_cols + cm->seq_params->mib_size - 1) / + cm->seq_params->mib_size; + sb_rows = (mi_params->mi_rows + cm->seq_params->mib_size - 1) / + cm->seq_params->mib_size; sbs_in_frame = sb_cols * sb_rows; // Number of target blocks to get the q delta (segment 1). block_count = @@ -302,8 +339,8 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) { // Get the mi_row/mi_col corresponding to superblock index i. int sb_row_index = (i / sb_cols); int sb_col_index = i - sb_row_index * sb_cols; - int mi_row = sb_row_index * cm->seq_params.mib_size; - int mi_col = sb_col_index * cm->seq_params.mib_size; + int mi_row = sb_row_index * cm->seq_params->mib_size; + int mi_col = sb_col_index * cm->seq_params->mib_size; // TODO(any): Ensure the population of // cpi->common.features.allow_screen_content_tools and use the same instead // of cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN @@ -315,8 +352,8 @@ static void cyclic_refresh_update_map(AV1_COMP *const cpi) { assert(mi_col >= 0 && mi_col < mi_params->mi_cols); bl_index = mi_row * mi_params->mi_cols + mi_col; // Loop through all MI blocks in superblock and update map. - xmis = AOMMIN(mi_params->mi_cols - mi_col, cm->seq_params.mib_size); - ymis = AOMMIN(mi_params->mi_rows - mi_row, cm->seq_params.mib_size); + xmis = AOMMIN(mi_params->mi_cols - mi_col, cm->seq_params->mib_size); + ymis = AOMMIN(mi_params->mi_rows - mi_row, cm->seq_params->mib_size); // cr_map only needed at 8x8 blocks. for (y = 0; y < ymis; y += 2) { for (x = 0; x < xmis; x += 2) { @@ -361,11 +398,20 @@ void av1_cyclic_refresh_update_parameters(AV1_COMP *const cpi) { int qp_thresh = AOMMIN(20, rc->best_quality << 1); int qp_max_thresh = 118 * MAXQ >> 7; cr->apply_cyclic_refresh = 1; + int avg_frame_qindex_inter_frame; +#if CONFIG_FRAME_PARALLEL_ENCODE + avg_frame_qindex_inter_frame = + (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) + ? cpi->ppi->temp_avg_frame_qindex[INTER_FRAME] + : rc->avg_frame_qindex[INTER_FRAME]; +#else + avg_frame_qindex_inter_frame = rc->avg_frame_qindex[INTER_FRAME]; +#endif // CONFIG_FRAME_PARALLEL_ENCODE if (frame_is_intra_only(cm) || is_lossless_requested(&cpi->oxcf.rc_cfg) || cpi->svc.temporal_layer_id > 0 || - rc->avg_frame_qindex[INTER_FRAME] < qp_thresh || + avg_frame_qindex_inter_frame < qp_thresh || (rc->frames_since_key > 20 && - rc->avg_frame_qindex[INTER_FRAME] > qp_max_thresh) || + avg_frame_qindex_inter_frame > qp_max_thresh) || (rc->avg_frame_low_motion < 45 && rc->frames_since_key > 40)) { cr->apply_cyclic_refresh = 0; return; @@ -446,7 +492,7 @@ void av1_cyclic_refresh_setup(AV1_COMP *const cpi) { return; } else { const double q = av1_convert_qindex_to_q(cm->quant_params.base_qindex, - cm->seq_params.bit_depth); + cm->seq_params->bit_depth); aom_clear_system_state(); // Set rate threshold to some multiple (set to 2 for now) of the target // rate (target is given by sb64_target_rate and scaled by 256). |