1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include <limits.h>
13 #include <float.h>
14 #include <math.h>
15 #include <stdbool.h>
16 #include <stdio.h>
17
18 #include "config/aom_config.h"
19 #include "config/aom_dsp_rtcd.h"
20 #include "config/av1_rtcd.h"
21
22 #include "aom_dsp/aom_dsp_common.h"
23 #include "aom_dsp/binary_codes_writer.h"
24 #include "aom_ports/mem.h"
25 #include "aom_ports/aom_timer.h"
26
27 #if CONFIG_MISMATCH_DEBUG
28 #include "aom_util/debug_util.h"
29 #endif // CONFIG_MISMATCH_DEBUG
30
31 #include "av1/common/cfl.h"
32 #include "av1/common/common.h"
33 #include "av1/common/common_data.h"
34 #include "av1/common/entropy.h"
35 #include "av1/common/entropymode.h"
36 #include "av1/common/idct.h"
37 #include "av1/common/mv.h"
38 #include "av1/common/mvref_common.h"
39 #include "av1/common/pred_common.h"
40 #include "av1/common/quant_common.h"
41 #include "av1/common/reconintra.h"
42 #include "av1/common/reconinter.h"
43 #include "av1/common/seg_common.h"
44 #include "av1/common/tile_common.h"
45 #include "av1/common/warped_motion.h"
46
47 #include "av1/encoder/allintra_vis.h"
48 #include "av1/encoder/aq_complexity.h"
49 #include "av1/encoder/aq_cyclicrefresh.h"
50 #include "av1/encoder/aq_variance.h"
51 #include "av1/encoder/global_motion_facade.h"
52 #include "av1/encoder/encodeframe.h"
53 #include "av1/encoder/encodeframe_utils.h"
54 #include "av1/encoder/encodemb.h"
55 #include "av1/encoder/encodemv.h"
56 #include "av1/encoder/encodetxb.h"
57 #include "av1/encoder/ethread.h"
58 #include "av1/encoder/extend.h"
59 #include "av1/encoder/intra_mode_search_utils.h"
60 #include "av1/encoder/ml.h"
61 #include "av1/encoder/motion_search_facade.h"
62 #include "av1/encoder/partition_strategy.h"
63 #if !CONFIG_REALTIME_ONLY
64 #include "av1/encoder/partition_model_weights.h"
65 #endif
66 #include "av1/encoder/partition_search.h"
67 #include "av1/encoder/rd.h"
68 #include "av1/encoder/rdopt.h"
69 #include "av1/encoder/reconinter_enc.h"
70 #include "av1/encoder/segmentation.h"
71 #include "av1/encoder/tokenize.h"
72 #include "av1/encoder/tpl_model.h"
73 #include "av1/encoder/var_based_part.h"
74
75 #if CONFIG_TUNE_VMAF
76 #include "av1/encoder/tune_vmaf.h"
77 #endif
78
79 /*!\cond */
80 // This is used as a reference when computing the source variance for the
81 // purposes of activity masking.
82 // Eventually this should be replaced by custom no-reference routines,
83 // which will be faster.
84 const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
85 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
86 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
87 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
88 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
89 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
90 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
91 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
92 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
93 128, 128, 128, 128, 128, 128, 128, 128
94 };
95
96 static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
97 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
98 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
99 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
100 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
101 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
102 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
103 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
104 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
105 128, 128, 128, 128, 128, 128, 128, 128
106 };
107
108 static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
109 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
110 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
111 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
112 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
113 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
114 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
115 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
116 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
117 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
118 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
119 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
120 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
121 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
122 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
123 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
124 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
125 };
126
127 static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
128 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
129 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
130 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
131 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
132 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
133 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
134 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
135 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
136 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
137 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
138 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
139 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
140 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
141 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
142 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
143 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
144 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
145 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
146 128 * 16, 128 * 16
147 };
148 /*!\endcond */
149
av1_init_rtc_counters(MACROBLOCK * const x)150 void av1_init_rtc_counters(MACROBLOCK *const x) {
151 av1_init_cyclic_refresh_counters(x);
152 x->cnt_zeromv = 0;
153 }
154
av1_accumulate_rtc_counters(AV1_COMP * cpi,const MACROBLOCK * const x)155 void av1_accumulate_rtc_counters(AV1_COMP *cpi, const MACROBLOCK *const x) {
156 if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ)
157 av1_accumulate_cyclic_refresh_counters(cpi->cyclic_refresh, x);
158 cpi->rc.cnt_zeromv += x->cnt_zeromv;
159 }
160
av1_get_perpixel_variance(const AV1_COMP * cpi,const MACROBLOCKD * xd,const struct buf_2d * ref,BLOCK_SIZE bsize,int plane,int use_hbd)161 unsigned int av1_get_perpixel_variance(const AV1_COMP *cpi,
162 const MACROBLOCKD *xd,
163 const struct buf_2d *ref,
164 BLOCK_SIZE bsize, int plane,
165 int use_hbd) {
166 const int subsampling_x = xd->plane[plane].subsampling_x;
167 const int subsampling_y = xd->plane[plane].subsampling_y;
168 const BLOCK_SIZE plane_bsize =
169 get_plane_block_size(bsize, subsampling_x, subsampling_y);
170 unsigned int var, sse;
171 if (use_hbd) {
172 const int bd = xd->bd;
173 assert(bd == 8 || bd == 10 || bd == 12);
174 const int off_index = (bd - 8) >> 1;
175 static const uint16_t *high_var_offs[3] = { AV1_HIGH_VAR_OFFS_8,
176 AV1_HIGH_VAR_OFFS_10,
177 AV1_HIGH_VAR_OFFS_12 };
178 var = cpi->ppi->fn_ptr[plane_bsize].vf(
179 ref->buf, ref->stride, CONVERT_TO_BYTEPTR(high_var_offs[off_index]), 0,
180 &sse);
181 } else {
182 var = cpi->ppi->fn_ptr[plane_bsize].vf(ref->buf, ref->stride, AV1_VAR_OFFS,
183 0, &sse);
184 }
185 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[plane_bsize]);
186 }
187
av1_get_perpixel_variance_facade(const AV1_COMP * cpi,const MACROBLOCKD * xd,const struct buf_2d * ref,BLOCK_SIZE bsize,int plane)188 unsigned int av1_get_perpixel_variance_facade(const AV1_COMP *cpi,
189 const MACROBLOCKD *xd,
190 const struct buf_2d *ref,
191 BLOCK_SIZE bsize, int plane) {
192 const int use_hbd = is_cur_buf_hbd(xd);
193 return av1_get_perpixel_variance(cpi, xd, ref, bsize, plane, use_hbd);
194 }
195
av1_setup_src_planes(MACROBLOCK * x,const YV12_BUFFER_CONFIG * src,int mi_row,int mi_col,const int num_planes,BLOCK_SIZE bsize)196 void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
197 int mi_row, int mi_col, const int num_planes,
198 BLOCK_SIZE bsize) {
199 // Set current frame pointer.
200 x->e_mbd.cur_buf = src;
201
202 // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
203 // the static analysis warnings.
204 for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); i++) {
205 const int is_uv = i > 0;
206 setup_pred_plane(
207 &x->plane[i].src, bsize, src->buffers[i], src->crop_widths[is_uv],
208 src->crop_heights[is_uv], src->strides[is_uv], mi_row, mi_col, NULL,
209 x->e_mbd.plane[i].subsampling_x, x->e_mbd.plane[i].subsampling_y);
210 }
211 }
212
213 #if !CONFIG_REALTIME_ONLY
214 /*!\brief Assigns different quantization parameters to each super
215 * block based on its TPL weight.
216 *
217 * \ingroup tpl_modelling
218 *
219 * \param[in] cpi Top level encoder instance structure
220 * \param[in,out] td Thread data structure
221 * \param[in,out] x Macro block level data for this block.
222 * \param[in] tile_info Tile infromation / identification
223 * \param[in] mi_row Block row (in "MI_SIZE" units) index
224 * \param[in] mi_col Block column (in "MI_SIZE" units) index
225 * \param[out] num_planes Number of image planes (e.g. Y,U,V)
226 *
227 * \remark No return value but updates macroblock and thread data
228 * related to the q / q delta to be used.
229 */
setup_delta_q(AV1_COMP * const cpi,ThreadData * td,MACROBLOCK * const x,const TileInfo * const tile_info,int mi_row,int mi_col,int num_planes)230 static AOM_INLINE void setup_delta_q(AV1_COMP *const cpi, ThreadData *td,
231 MACROBLOCK *const x,
232 const TileInfo *const tile_info,
233 int mi_row, int mi_col, int num_planes) {
234 AV1_COMMON *const cm = &cpi->common;
235 const CommonModeInfoParams *const mi_params = &cm->mi_params;
236 const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
237 assert(delta_q_info->delta_q_present_flag);
238
239 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
240 // Delta-q modulation based on variance
241 av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
242
243 const int delta_q_res = delta_q_info->delta_q_res;
244 int current_qindex = cm->quant_params.base_qindex;
245 if (cpi->use_ducky_encode && cpi->ducky_encode_info.frame_info.qp_mode ==
246 DUCKY_ENCODE_FRAME_MODE_QINDEX) {
247 const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
248 const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
249 const int sb_cols =
250 CEIL_POWER_OF_TWO(cm->mi_params.mi_cols, MAX_MIB_SIZE_LOG2);
251 const int sb_index = sb_row * sb_cols + sb_col;
252 current_qindex =
253 cpi->ducky_encode_info.frame_info.superblock_encode_qindex[sb_index];
254 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL) {
255 if (DELTA_Q_PERCEPTUAL_MODULATION == 1) {
256 const int block_wavelet_energy_level =
257 av1_block_wavelet_energy_level(cpi, x, sb_size);
258 x->sb_energy_level = block_wavelet_energy_level;
259 current_qindex = av1_compute_q_from_energy_level_deltaq_mode(
260 cpi, block_wavelet_energy_level);
261 } else {
262 const int block_var_level = av1_log_block_var(cpi, x, sb_size);
263 x->sb_energy_level = block_var_level;
264 current_qindex =
265 av1_compute_q_from_energy_level_deltaq_mode(cpi, block_var_level);
266 }
267 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
268 cpi->oxcf.algo_cfg.enable_tpl_model) {
269 // Setup deltaq based on tpl stats
270 current_qindex =
271 av1_get_q_for_deltaq_objective(cpi, td, NULL, sb_size, mi_row, mi_col);
272 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL_AI) {
273 current_qindex = av1_get_sbq_perceptual_ai(cpi, sb_size, mi_row, mi_col);
274 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_USER_RATING_BASED) {
275 current_qindex = av1_get_sbq_user_rating_based(cpi, mi_row, mi_col);
276 } else if (cpi->oxcf.q_cfg.enable_hdr_deltaq) {
277 current_qindex = av1_get_q_for_hdr(cpi, x, sb_size, mi_row, mi_col);
278 }
279
280 x->rdmult_cur_qindex = current_qindex;
281 MACROBLOCKD *const xd = &x->e_mbd;
282 const int adjusted_qindex = av1_adjust_q_from_delta_q_res(
283 delta_q_res, xd->current_base_qindex, current_qindex);
284 if (cpi->use_ducky_encode) {
285 assert(adjusted_qindex == current_qindex);
286 }
287 current_qindex = adjusted_qindex;
288
289 x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
290 x->rdmult_delta_qindex = x->delta_qindex;
291
292 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
293 xd->mi[0]->current_qindex = current_qindex;
294 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
295
296 // keep track of any non-zero delta-q used
297 td->deltaq_used |= (x->delta_qindex != 0);
298
299 if (cpi->oxcf.tool_cfg.enable_deltalf_mode) {
300 const int delta_lf_res = delta_q_info->delta_lf_res;
301 const int lfmask = ~(delta_lf_res - 1);
302 const int delta_lf_from_base =
303 ((x->delta_qindex / 4 + delta_lf_res / 2) & lfmask);
304 const int8_t delta_lf =
305 (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
306 const int frame_lf_count =
307 av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
308 const int mib_size = cm->seq_params->mib_size;
309
310 // pre-set the delta lf for loop filter. Note that this value is set
311 // before mi is assigned for each block in current superblock
312 for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row); j++) {
313 for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col); k++) {
314 const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
315 mi_params->mi_alloc[grid_idx].delta_lf_from_base = delta_lf;
316 for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
317 mi_params->mi_alloc[grid_idx].delta_lf[lf_id] = delta_lf;
318 }
319 }
320 }
321 }
322 }
323
init_ref_frame_space(AV1_COMP * cpi,ThreadData * td,int mi_row,int mi_col)324 static void init_ref_frame_space(AV1_COMP *cpi, ThreadData *td, int mi_row,
325 int mi_col) {
326 const AV1_COMMON *cm = &cpi->common;
327 const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
328 const CommonModeInfoParams *const mi_params = &cm->mi_params;
329 MACROBLOCK *x = &td->mb;
330 const int frame_idx = cpi->gf_frame_index;
331 TplParams *const tpl_data = &cpi->ppi->tpl_data;
332 const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
333
334 av1_zero(x->tpl_keep_ref_frame);
335
336 if (!av1_tpl_stats_ready(tpl_data, frame_idx)) return;
337 if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) return;
338 if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return;
339
340 const int is_overlay =
341 cpi->ppi->gf_group.update_type[frame_idx] == OVERLAY_UPDATE;
342 if (is_overlay) {
343 memset(x->tpl_keep_ref_frame, 1, sizeof(x->tpl_keep_ref_frame));
344 return;
345 }
346
347 TplDepFrame *tpl_frame = &tpl_data->tpl_frame[frame_idx];
348 TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
349 const int tpl_stride = tpl_frame->stride;
350 int64_t inter_cost[INTER_REFS_PER_FRAME] = { 0 };
351 const int step = 1 << block_mis_log2;
352 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
353
354 const int mi_row_end =
355 AOMMIN(mi_size_high[sb_size] + mi_row, mi_params->mi_rows);
356 const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
357 const int mi_col_sr =
358 coded_to_superres_mi(mi_col, cm->superres_scale_denominator);
359 const int mi_col_end_sr =
360 AOMMIN(coded_to_superres_mi(mi_col + mi_size_wide[sb_size],
361 cm->superres_scale_denominator),
362 mi_cols_sr);
363 const int row_step = step;
364 const int col_step_sr =
365 coded_to_superres_mi(step, cm->superres_scale_denominator);
366 for (int row = mi_row; row < mi_row_end; row += row_step) {
367 for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
368 const TplDepStats *this_stats =
369 &tpl_stats[av1_tpl_ptr_pos(row, col, tpl_stride, block_mis_log2)];
370 int64_t tpl_pred_error[INTER_REFS_PER_FRAME] = { 0 };
371 // Find the winner ref frame idx for the current block
372 int64_t best_inter_cost = this_stats->pred_error[0];
373 int best_rf_idx = 0;
374 for (int idx = 1; idx < INTER_REFS_PER_FRAME; ++idx) {
375 if ((this_stats->pred_error[idx] < best_inter_cost) &&
376 (this_stats->pred_error[idx] != 0)) {
377 best_inter_cost = this_stats->pred_error[idx];
378 best_rf_idx = idx;
379 }
380 }
381 // tpl_pred_error is the pred_error reduction of best_ref w.r.t.
382 // LAST_FRAME.
383 tpl_pred_error[best_rf_idx] = this_stats->pred_error[best_rf_idx] -
384 this_stats->pred_error[LAST_FRAME - 1];
385
386 for (int rf_idx = 1; rf_idx < INTER_REFS_PER_FRAME; ++rf_idx)
387 inter_cost[rf_idx] += tpl_pred_error[rf_idx];
388 }
389 }
390
391 int rank_index[INTER_REFS_PER_FRAME - 1];
392 for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
393 rank_index[idx] = idx + 1;
394 for (int i = idx; i > 0; --i) {
395 if (inter_cost[rank_index[i - 1]] > inter_cost[rank_index[i]]) {
396 const int tmp = rank_index[i - 1];
397 rank_index[i - 1] = rank_index[i];
398 rank_index[i] = tmp;
399 }
400 }
401 }
402
403 x->tpl_keep_ref_frame[INTRA_FRAME] = 1;
404 x->tpl_keep_ref_frame[LAST_FRAME] = 1;
405
406 int cutoff_ref = 0;
407 for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
408 x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 1;
409 if (idx > 2) {
410 if (!cutoff_ref) {
411 // If the predictive coding gains are smaller than the previous more
412 // relevant frame over certain amount, discard this frame and all the
413 // frames afterwards.
414 if (llabs(inter_cost[rank_index[idx]]) <
415 llabs(inter_cost[rank_index[idx - 1]]) / 8 ||
416 inter_cost[rank_index[idx]] == 0)
417 cutoff_ref = 1;
418 }
419
420 if (cutoff_ref) x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 0;
421 }
422 }
423 }
424
adjust_rdmult_tpl_model(AV1_COMP * cpi,MACROBLOCK * x,int mi_row,int mi_col)425 static AOM_INLINE void adjust_rdmult_tpl_model(AV1_COMP *cpi, MACROBLOCK *x,
426 int mi_row, int mi_col) {
427 const BLOCK_SIZE sb_size = cpi->common.seq_params->sb_size;
428 const int orig_rdmult = cpi->rd.RDMULT;
429
430 assert(IMPLIES(cpi->ppi->gf_group.size > 0,
431 cpi->gf_frame_index < cpi->ppi->gf_group.size));
432 const int gf_group_index = cpi->gf_frame_index;
433 if (cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
434 cpi->oxcf.q_cfg.deltaq_mode == NO_DELTA_Q && gf_group_index > 0 &&
435 cpi->ppi->gf_group.update_type[gf_group_index] == ARF_UPDATE) {
436 const int dr =
437 av1_get_rdmult_delta(cpi, sb_size, mi_row, mi_col, orig_rdmult);
438 x->rdmult = dr;
439 }
440 }
441 #endif // !CONFIG_REALTIME_ONLY
442
443 #if CONFIG_RT_ML_PARTITIONING
444 // Get a prediction(stored in x->est_pred) for the whole superblock.
get_estimated_pred(AV1_COMP * cpi,const TileInfo * const tile,MACROBLOCK * x,int mi_row,int mi_col)445 static void get_estimated_pred(AV1_COMP *cpi, const TileInfo *const tile,
446 MACROBLOCK *x, int mi_row, int mi_col) {
447 AV1_COMMON *const cm = &cpi->common;
448 const int is_key_frame = frame_is_intra_only(cm);
449 MACROBLOCKD *xd = &x->e_mbd;
450
451 // TODO(kyslov) Extend to 128x128
452 assert(cm->seq_params->sb_size == BLOCK_64X64);
453
454 av1_set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
455
456 if (!is_key_frame) {
457 MB_MODE_INFO *mi = xd->mi[0];
458 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, LAST_FRAME);
459
460 assert(yv12 != NULL);
461
462 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
463 get_ref_scale_factors(cm, LAST_FRAME), 1);
464 mi->ref_frame[0] = LAST_FRAME;
465 mi->ref_frame[1] = NONE;
466 mi->bsize = BLOCK_64X64;
467 mi->mv[0].as_int = 0;
468 mi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
469
470 set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]);
471
472 xd->plane[0].dst.buf = x->est_pred;
473 xd->plane[0].dst.stride = 64;
474 av1_enc_build_inter_predictor_y(xd, mi_row, mi_col);
475 } else {
476 #if CONFIG_AV1_HIGHBITDEPTH
477 switch (xd->bd) {
478 case 8: memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0])); break;
479 case 10:
480 memset(x->est_pred, 128 * 4, 64 * 64 * sizeof(x->est_pred[0]));
481 break;
482 case 12:
483 memset(x->est_pred, 128 * 16, 64 * 64 * sizeof(x->est_pred[0]));
484 break;
485 }
486 #else
487 memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0]));
488 #endif // CONFIG_VP9_HIGHBITDEPTH
489 }
490 }
491 #endif // CONFIG_RT_ML_PARTITIONING
492
493 #define AVG_CDF_WEIGHT_LEFT 3
494 #define AVG_CDF_WEIGHT_TOP_RIGHT 1
495
496 /*!\brief Encode a superblock (minimal RD search involved)
497 *
498 * \ingroup partition_search
499 * Encodes the superblock by a pre-determined partition pattern, only minor
500 * rd-based searches are allowed to adjust the initial pattern. It is only used
501 * by realtime encoding.
502 */
encode_nonrd_sb(AV1_COMP * cpi,ThreadData * td,TileDataEnc * tile_data,TokenExtra ** tp,const int mi_row,const int mi_col,const int seg_skip)503 static AOM_INLINE void encode_nonrd_sb(AV1_COMP *cpi, ThreadData *td,
504 TileDataEnc *tile_data, TokenExtra **tp,
505 const int mi_row, const int mi_col,
506 const int seg_skip) {
507 AV1_COMMON *const cm = &cpi->common;
508 MACROBLOCK *const x = &td->mb;
509 const SPEED_FEATURES *const sf = &cpi->sf;
510 const TileInfo *const tile_info = &tile_data->tile_info;
511 MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
512 get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
513 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
514 PC_TREE *const pc_root = td->rt_pc_root;
515
516 #if CONFIG_RT_ML_PARTITIONING
517 if (sf->part_sf.partition_search_type == ML_BASED_PARTITION) {
518 RD_STATS dummy_rdc;
519 get_estimated_pred(cpi, tile_info, x, mi_row, mi_col);
520 av1_nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col,
521 BLOCK_64X64, &dummy_rdc, 1, INT64_MAX, pc_root);
522 return;
523 }
524 #endif
525 // Set the partition
526 if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip) {
527 // set a fixed-size partition
528 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
529 const BLOCK_SIZE bsize =
530 seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
531 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
532 } else if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
533 // set a variance-based partition
534 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
535 av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
536 }
537 assert(sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip ||
538 sf->part_sf.partition_search_type == VAR_BASED_PARTITION);
539 set_cb_offsets(td->mb.cb_offset, 0, 0);
540
541 // Initialize the flag to skip cdef to 1.
542 if (sf->rt_sf.skip_cdef_sb) {
543 const int block64_in_sb = (sb_size == BLOCK_128X128) ? 2 : 1;
544 // If 128x128 block is used, we need to set the flag for all 4 64x64 sub
545 // "blocks".
546 for (int r = 0; r < block64_in_sb; ++r) {
547 for (int c = 0; c < block64_in_sb; ++c) {
548 const int idx_in_sb =
549 r * MI_SIZE_64X64 * cm->mi_params.mi_stride + c * MI_SIZE_64X64;
550 if (mi[idx_in_sb]) mi[idx_in_sb]->cdef_strength = 1;
551 }
552 }
553 }
554
555 #if CONFIG_COLLECT_COMPONENT_TIMING
556 start_timing(cpi, nonrd_use_partition_time);
557 #endif
558 av1_nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
559 pc_root);
560 #if CONFIG_COLLECT_COMPONENT_TIMING
561 end_timing(cpi, nonrd_use_partition_time);
562 #endif
563 }
564
565 // This function initializes the stats for encode_rd_sb.
init_encode_rd_sb(AV1_COMP * cpi,ThreadData * td,const TileDataEnc * tile_data,SIMPLE_MOTION_DATA_TREE * sms_root,RD_STATS * rd_cost,int mi_row,int mi_col,int gather_tpl_data)566 static INLINE void init_encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
567 const TileDataEnc *tile_data,
568 SIMPLE_MOTION_DATA_TREE *sms_root,
569 RD_STATS *rd_cost, int mi_row, int mi_col,
570 int gather_tpl_data) {
571 const AV1_COMMON *cm = &cpi->common;
572 const TileInfo *tile_info = &tile_data->tile_info;
573 MACROBLOCK *x = &td->mb;
574
575 const SPEED_FEATURES *sf = &cpi->sf;
576 const int use_simple_motion_search =
577 (sf->part_sf.simple_motion_search_split ||
578 sf->part_sf.simple_motion_search_prune_rect ||
579 sf->part_sf.simple_motion_search_early_term_none ||
580 sf->part_sf.ml_early_term_after_part_split_level) &&
581 !frame_is_intra_only(cm);
582 if (use_simple_motion_search) {
583 av1_init_simple_motion_search_mvs_for_sb(cpi, tile_info, x, sms_root,
584 mi_row, mi_col);
585 }
586
587 #if !CONFIG_REALTIME_ONLY
588 if (!(has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
589 cpi->oxcf.gf_cfg.lag_in_frames == 0)) {
590 init_ref_frame_space(cpi, td, mi_row, mi_col);
591 x->sb_energy_level = 0;
592 x->part_search_info.cnn_output_valid = 0;
593 if (gather_tpl_data) {
594 if (cm->delta_q_info.delta_q_present_flag) {
595 const int num_planes = av1_num_planes(cm);
596 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
597 setup_delta_q(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
598 av1_tpl_rdmult_setup_sb(cpi, x, sb_size, mi_row, mi_col);
599 }
600
601 // TODO(jingning): revisit this function.
602 if (cpi->oxcf.algo_cfg.enable_tpl_model && 0) {
603 adjust_rdmult_tpl_model(cpi, x, mi_row, mi_col);
604 }
605 }
606 }
607 #else
608 (void)tile_info;
609 (void)mi_row;
610 (void)mi_col;
611 (void)gather_tpl_data;
612 #endif
613
614 x->reuse_inter_pred = false;
615 x->txfm_search_params.mode_eval_type = DEFAULT_EVAL;
616 reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
617 av1_zero(x->picked_ref_frames_mask);
618 av1_invalid_rd_stats(rd_cost);
619 }
620
621 #if !CONFIG_REALTIME_ONLY
sb_qp_sweep_init_quantizers(AV1_COMP * cpi,ThreadData * td,const TileDataEnc * tile_data,SIMPLE_MOTION_DATA_TREE * sms_tree,RD_STATS * rd_cost,int mi_row,int mi_col,int delta_qp_ofs)622 static void sb_qp_sweep_init_quantizers(AV1_COMP *cpi, ThreadData *td,
623 const TileDataEnc *tile_data,
624 SIMPLE_MOTION_DATA_TREE *sms_tree,
625 RD_STATS *rd_cost, int mi_row,
626 int mi_col, int delta_qp_ofs) {
627 AV1_COMMON *const cm = &cpi->common;
628 MACROBLOCK *const x = &td->mb;
629 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
630 const TileInfo *tile_info = &tile_data->tile_info;
631 const CommonModeInfoParams *const mi_params = &cm->mi_params;
632 const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
633 assert(delta_q_info->delta_q_present_flag);
634 const int delta_q_res = delta_q_info->delta_q_res;
635
636 const SPEED_FEATURES *sf = &cpi->sf;
637 const int use_simple_motion_search =
638 (sf->part_sf.simple_motion_search_split ||
639 sf->part_sf.simple_motion_search_prune_rect ||
640 sf->part_sf.simple_motion_search_early_term_none ||
641 sf->part_sf.ml_early_term_after_part_split_level) &&
642 !frame_is_intra_only(cm);
643 if (use_simple_motion_search) {
644 av1_init_simple_motion_search_mvs_for_sb(cpi, tile_info, x, sms_tree,
645 mi_row, mi_col);
646 }
647
648 int current_qindex = x->rdmult_cur_qindex + delta_qp_ofs;
649
650 MACROBLOCKD *const xd = &x->e_mbd;
651 current_qindex = av1_adjust_q_from_delta_q_res(
652 delta_q_res, xd->current_base_qindex, current_qindex);
653
654 x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
655
656 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
657 xd->mi[0]->current_qindex = current_qindex;
658 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
659
660 // keep track of any non-zero delta-q used
661 td->deltaq_used |= (x->delta_qindex != 0);
662
663 if (cpi->oxcf.tool_cfg.enable_deltalf_mode) {
664 const int delta_lf_res = delta_q_info->delta_lf_res;
665 const int lfmask = ~(delta_lf_res - 1);
666 const int delta_lf_from_base =
667 ((x->delta_qindex / 4 + delta_lf_res / 2) & lfmask);
668 const int8_t delta_lf =
669 (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
670 const int frame_lf_count =
671 av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
672 const int mib_size = cm->seq_params->mib_size;
673
674 // pre-set the delta lf for loop filter. Note that this value is set
675 // before mi is assigned for each block in current superblock
676 for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row); j++) {
677 for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col); k++) {
678 const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
679 mi_params->mi_alloc[grid_idx].delta_lf_from_base = delta_lf;
680 for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
681 mi_params->mi_alloc[grid_idx].delta_lf[lf_id] = delta_lf;
682 }
683 }
684 }
685 }
686
687 x->reuse_inter_pred = false;
688 x->txfm_search_params.mode_eval_type = DEFAULT_EVAL;
689 reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
690 av1_zero(x->picked_ref_frames_mask);
691 av1_invalid_rd_stats(rd_cost);
692 }
693
sb_qp_sweep(AV1_COMP * const cpi,ThreadData * td,TileDataEnc * tile_data,TokenExtra ** tp,int mi_row,int mi_col,BLOCK_SIZE bsize,SIMPLE_MOTION_DATA_TREE * sms_tree,SB_FIRST_PASS_STATS * sb_org_stats)694 static int sb_qp_sweep(AV1_COMP *const cpi, ThreadData *td,
695 TileDataEnc *tile_data, TokenExtra **tp, int mi_row,
696 int mi_col, BLOCK_SIZE bsize,
697 SIMPLE_MOTION_DATA_TREE *sms_tree,
698 SB_FIRST_PASS_STATS *sb_org_stats) {
699 AV1_COMMON *const cm = &cpi->common;
700 MACROBLOCK *const x = &td->mb;
701 RD_STATS rdc_winner, cur_rdc;
702 av1_invalid_rd_stats(&rdc_winner);
703
704 int best_qindex = td->mb.rdmult_delta_qindex;
705 const int start = cm->current_frame.frame_type == KEY_FRAME ? -20 : -12;
706 const int end = cm->current_frame.frame_type == KEY_FRAME ? 20 : 12;
707 const int step = cm->delta_q_info.delta_q_res;
708
709 for (int sweep_qp_delta = start; sweep_qp_delta <= end;
710 sweep_qp_delta += step) {
711 sb_qp_sweep_init_quantizers(cpi, td, tile_data, sms_tree, &cur_rdc, mi_row,
712 mi_col, sweep_qp_delta);
713
714 const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
715 const int backup_current_qindex =
716 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
717
718 av1_reset_mbmi(&cm->mi_params, bsize, mi_row, mi_col);
719 av1_restore_sb_state(sb_org_stats, cpi, td, tile_data, mi_row, mi_col);
720 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex = backup_current_qindex;
721
722 PC_TREE *const pc_root = av1_alloc_pc_tree_node(bsize);
723 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize,
724 &cur_rdc, cur_rdc, pc_root, sms_tree, NULL,
725 SB_DRY_PASS, NULL);
726
727 if ((rdc_winner.rdcost > cur_rdc.rdcost) ||
728 (abs(sweep_qp_delta) < abs(best_qindex - x->rdmult_delta_qindex) &&
729 rdc_winner.rdcost == cur_rdc.rdcost)) {
730 rdc_winner = cur_rdc;
731 best_qindex = x->rdmult_delta_qindex + sweep_qp_delta;
732 }
733 }
734
735 return best_qindex;
736 }
737 #endif //! CONFIG_REALTIME_ONLY
738
739 /*!\brief Encode a superblock (RD-search-based)
740 *
741 * \ingroup partition_search
742 * Conducts partition search for a superblock, based on rate-distortion costs,
743 * from scratch or adjusting from a pre-calculated partition pattern.
744 */
encode_rd_sb(AV1_COMP * cpi,ThreadData * td,TileDataEnc * tile_data,TokenExtra ** tp,const int mi_row,const int mi_col,const int seg_skip)745 static AOM_INLINE void encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
746 TileDataEnc *tile_data, TokenExtra **tp,
747 const int mi_row, const int mi_col,
748 const int seg_skip) {
749 AV1_COMMON *const cm = &cpi->common;
750 MACROBLOCK *const x = &td->mb;
751 const SPEED_FEATURES *const sf = &cpi->sf;
752 const TileInfo *const tile_info = &tile_data->tile_info;
753 MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
754 get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
755 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
756 const int num_planes = av1_num_planes(cm);
757 int dummy_rate;
758 int64_t dummy_dist;
759 RD_STATS dummy_rdc;
760 SIMPLE_MOTION_DATA_TREE *const sms_root = td->sms_root;
761
762 #if CONFIG_REALTIME_ONLY
763 (void)seg_skip;
764 #endif // CONFIG_REALTIME_ONLY
765
766 init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row, mi_col,
767 1);
768
769 // Encode the superblock
770 if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
771 // partition search starting from a variance-based partition
772 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
773 av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
774
775 #if CONFIG_COLLECT_COMPONENT_TIMING
776 start_timing(cpi, rd_use_partition_time);
777 #endif
778 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
779 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
780 &dummy_rate, &dummy_dist, 1, pc_root);
781 av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0);
782 #if CONFIG_COLLECT_COMPONENT_TIMING
783 end_timing(cpi, rd_use_partition_time);
784 #endif
785 }
786 #if !CONFIG_REALTIME_ONLY
787 else if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip) {
788 // partition search by adjusting a fixed-size partition
789 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
790 const BLOCK_SIZE bsize =
791 seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
792 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
793 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
794 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
795 &dummy_rate, &dummy_dist, 1, pc_root);
796 av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0);
797 } else {
798 SB_FIRST_PASS_STATS *sb_org_stats = NULL;
799
800 if (cpi->oxcf.sb_qp_sweep) {
801 CHECK_MEM_ERROR(
802 cm, sb_org_stats,
803 (SB_FIRST_PASS_STATS *)aom_malloc(sizeof(SB_FIRST_PASS_STATS)));
804 av1_backup_sb_state(sb_org_stats, cpi, td, tile_data, mi_row, mi_col);
805 }
806 // The most exhaustive recursive partition search
807 SuperBlockEnc *sb_enc = &x->sb_enc;
808 // No stats for overlay frames. Exclude key frame.
809 av1_get_tpl_stats_sb(cpi, sb_size, mi_row, mi_col, sb_enc);
810
811 // Reset the tree for simple motion search data
812 av1_reset_simple_motion_tree_partition(sms_root, sb_size);
813
814 #if CONFIG_COLLECT_COMPONENT_TIMING
815 start_timing(cpi, rd_pick_partition_time);
816 #endif
817
818 // Estimate the maximum square partition block size, which will be used
819 // as the starting block size for partitioning the sb
820 set_max_min_partition_size(sb_enc, cpi, x, sf, sb_size, mi_row, mi_col);
821
822 // The superblock can be searched only once, or twice consecutively for
823 // better quality. Note that the meaning of passes here is different from
824 // the general concept of 1-pass/2-pass encoders.
825 const int num_passes =
826 cpi->oxcf.unit_test_cfg.sb_multipass_unit_test ? 2 : 1;
827
828 if (cpi->oxcf.sb_qp_sweep &&
829 !(has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
830 cpi->oxcf.gf_cfg.lag_in_frames == 0) &&
831 cm->delta_q_info.delta_q_present_flag) {
832 assert(x->rdmult_delta_qindex == x->delta_qindex);
833 assert(sb_org_stats);
834
835 const int best_qp_diff =
836 sb_qp_sweep(cpi, td, tile_data, tp, mi_row, mi_col, sb_size, sms_root,
837 sb_org_stats) -
838 x->rdmult_delta_qindex;
839
840 sb_qp_sweep_init_quantizers(cpi, td, tile_data, sms_root, &dummy_rdc,
841 mi_row, mi_col, best_qp_diff);
842
843 const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
844 const int backup_current_qindex =
845 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
846
847 av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
848 av1_restore_sb_state(sb_org_stats, cpi, td, tile_data, mi_row, mi_col);
849
850 cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex =
851 backup_current_qindex;
852 }
853 if (num_passes == 1) {
854 #if CONFIG_PARTITION_SEARCH_ORDER
855 if (cpi->ext_part_controller.ready && !frame_is_intra_only(cm)) {
856 av1_reset_part_sf(&cpi->sf.part_sf);
857 av1_reset_sf_for_ext_part(cpi);
858 RD_STATS this_rdc;
859 av1_rd_partition_search(cpi, td, tile_data, tp, sms_root, mi_row,
860 mi_col, sb_size, &this_rdc);
861 } else {
862 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
863 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
864 &dummy_rdc, dummy_rdc, pc_root, sms_root, NULL,
865 SB_SINGLE_PASS, NULL);
866 }
867 #else
868 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
869 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
870 &dummy_rdc, dummy_rdc, pc_root, sms_root, NULL,
871 SB_SINGLE_PASS, NULL);
872 #endif // CONFIG_PARTITION_SEARCH_ORDER
873 } else {
874 // First pass
875 SB_FIRST_PASS_STATS sb_fp_stats;
876 av1_backup_sb_state(&sb_fp_stats, cpi, td, tile_data, mi_row, mi_col);
877 PC_TREE *const pc_root_p0 = av1_alloc_pc_tree_node(sb_size);
878 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
879 &dummy_rdc, dummy_rdc, pc_root_p0, sms_root, NULL,
880 SB_DRY_PASS, NULL);
881
882 // Second pass
883 init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row,
884 mi_col, 0);
885 av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
886 av1_reset_simple_motion_tree_partition(sms_root, sb_size);
887
888 av1_restore_sb_state(&sb_fp_stats, cpi, td, tile_data, mi_row, mi_col);
889
890 PC_TREE *const pc_root_p1 = av1_alloc_pc_tree_node(sb_size);
891 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
892 &dummy_rdc, dummy_rdc, pc_root_p1, sms_root, NULL,
893 SB_WET_PASS, NULL);
894 }
895 aom_free(sb_org_stats);
896
897 // Reset to 0 so that it wouldn't be used elsewhere mistakenly.
898 sb_enc->tpl_data_count = 0;
899 #if CONFIG_COLLECT_COMPONENT_TIMING
900 end_timing(cpi, rd_pick_partition_time);
901 #endif
902 }
903 #endif // !CONFIG_REALTIME_ONLY
904
905 // Update the inter rd model
906 // TODO(angiebird): Let inter_mode_rd_model_estimation support multi-tile.
907 if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1 &&
908 cm->tiles.cols == 1 && cm->tiles.rows == 1) {
909 av1_inter_mode_data_fit(tile_data, x->rdmult);
910 }
911 }
912
913 // Check if the cost update of symbols mode, coeff and dv are tile or off.
is_mode_coeff_dv_upd_freq_tile_or_off(const AV1_COMP * const cpi)914 static AOM_INLINE int is_mode_coeff_dv_upd_freq_tile_or_off(
915 const AV1_COMP *const cpi) {
916 const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf;
917
918 return (inter_sf->coeff_cost_upd_level <= INTERNAL_COST_UPD_TILE &&
919 inter_sf->mode_cost_upd_level <= INTERNAL_COST_UPD_TILE &&
920 cpi->sf.intra_sf.dv_cost_upd_level <= INTERNAL_COST_UPD_TILE);
921 }
922
923 // When row-mt is enabled and cost update frequencies are set to off/tile,
924 // processing of current SB can start even before processing of top-right SB
925 // is finished. This function checks if it is sufficient to wait for top SB
926 // to finish processing before current SB starts processing.
delay_wait_for_top_right_sb(const AV1_COMP * const cpi)927 static AOM_INLINE int delay_wait_for_top_right_sb(const AV1_COMP *const cpi) {
928 const MODE mode = cpi->oxcf.mode;
929 if (mode == GOOD) return 0;
930
931 if (mode == ALLINTRA)
932 return is_mode_coeff_dv_upd_freq_tile_or_off(cpi);
933 else if (mode == REALTIME)
934 return (is_mode_coeff_dv_upd_freq_tile_or_off(cpi) &&
935 cpi->sf.inter_sf.mv_cost_upd_level <= INTERNAL_COST_UPD_TILE);
936 else
937 return 0;
938 }
939
940 /*!\brief Calculate source SAD at superblock level using 64x64 block source SAD
941 *
942 * \ingroup partition_search
943 * \callgraph
944 * \callergraph
945 */
get_sb_source_sad(const AV1_COMP * cpi,int mi_row,int mi_col)946 static AOM_INLINE uint64_t get_sb_source_sad(const AV1_COMP *cpi, int mi_row,
947 int mi_col) {
948 if (cpi->src_sad_blk_64x64 == NULL) return UINT64_MAX;
949
950 const AV1_COMMON *const cm = &cpi->common;
951 const int blk_64x64_in_mis = (cm->seq_params->sb_size == BLOCK_128X128)
952 ? (cm->seq_params->mib_size >> 1)
953 : cm->seq_params->mib_size;
954 const int num_blk_64x64_cols =
955 (cm->mi_params.mi_cols + blk_64x64_in_mis - 1) / blk_64x64_in_mis;
956 const int num_blk_64x64_rows =
957 (cm->mi_params.mi_rows + blk_64x64_in_mis - 1) / blk_64x64_in_mis;
958 const int blk_64x64_col_index = mi_col / blk_64x64_in_mis;
959 const int blk_64x64_row_index = mi_row / blk_64x64_in_mis;
960 uint64_t curr_sb_sad = UINT64_MAX;
961 const uint64_t *const src_sad_blk_64x64_data =
962 &cpi->src_sad_blk_64x64[blk_64x64_col_index +
963 blk_64x64_row_index * num_blk_64x64_cols];
964 if (cm->seq_params->sb_size == BLOCK_128X128 &&
965 blk_64x64_col_index + 1 < num_blk_64x64_cols &&
966 blk_64x64_row_index + 1 < num_blk_64x64_rows) {
967 // Calculate SB source SAD by accumulating source SAD of 64x64 blocks in the
968 // superblock
969 curr_sb_sad = src_sad_blk_64x64_data[0] + src_sad_blk_64x64_data[1] +
970 src_sad_blk_64x64_data[num_blk_64x64_cols] +
971 src_sad_blk_64x64_data[num_blk_64x64_cols + 1];
972 } else if (cm->seq_params->sb_size == BLOCK_64X64) {
973 curr_sb_sad = src_sad_blk_64x64_data[0];
974 }
975 return curr_sb_sad;
976 }
977
978 /*!\brief Determine whether grading content can be skipped based on sad stat
979 *
980 * \ingroup partition_search
981 * \callgraph
982 * \callergraph
983 */
is_calc_src_content_needed(AV1_COMP * cpi,MACROBLOCK * const x,int mi_row,int mi_col)984 static AOM_INLINE bool is_calc_src_content_needed(AV1_COMP *cpi,
985 MACROBLOCK *const x,
986 int mi_row, int mi_col) {
987 if (cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)
988 return true;
989 const uint64_t curr_sb_sad = get_sb_source_sad(cpi, mi_row, mi_col);
990 if (curr_sb_sad == UINT64_MAX) return true;
991 if (curr_sb_sad == 0) {
992 x->content_state_sb.source_sad_nonrd = kZeroSad;
993 return false;
994 }
995 AV1_COMMON *const cm = &cpi->common;
996 bool do_calc_src_content = true;
997
998 if (cpi->oxcf.speed < 9) return do_calc_src_content;
999
1000 // TODO(yunqing): Tune/validate the thresholds for 128x128 SB size.
1001 if (AOMMIN(cm->width, cm->height) < 360) {
1002 // Derive Average 64x64 block source SAD from SB source SAD
1003 const uint64_t avg_64x64_blk_sad =
1004 (cm->seq_params->sb_size == BLOCK_128X128) ? ((curr_sb_sad + 2) >> 2)
1005 : curr_sb_sad;
1006
1007 // The threshold is determined based on kLowSad and kHighSad threshold and
1008 // test results.
1009 const uint64_t thresh_low = 15000;
1010 const uint64_t thresh_high = 40000;
1011
1012 if (avg_64x64_blk_sad > thresh_low && avg_64x64_blk_sad < thresh_high) {
1013 do_calc_src_content = false;
1014 // Note: set x->content_state_sb.source_sad_rd as well if this is extended
1015 // to RTC rd path.
1016 x->content_state_sb.source_sad_nonrd = kMedSad;
1017 }
1018 }
1019
1020 return do_calc_src_content;
1021 }
1022
1023 /*!\brief Determine whether grading content is needed based on sf and frame stat
1024 *
1025 * \ingroup partition_search
1026 * \callgraph
1027 * \callergraph
1028 */
1029 // TODO(any): consolidate sfs to make interface cleaner
grade_source_content_sb(AV1_COMP * cpi,MACROBLOCK * const x,TileDataEnc * tile_data,int mi_row,int mi_col)1030 static AOM_INLINE void grade_source_content_sb(AV1_COMP *cpi,
1031 MACROBLOCK *const x,
1032 TileDataEnc *tile_data,
1033 int mi_row, int mi_col) {
1034 AV1_COMMON *const cm = &cpi->common;
1035 if (cm->current_frame.frame_type == KEY_FRAME ||
1036 (cpi->ppi->use_svc &&
1037 cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) {
1038 assert(x->content_state_sb.source_sad_nonrd == kMedSad);
1039 assert(x->content_state_sb.source_sad_rd == kMedSad);
1040 return;
1041 }
1042 bool calc_src_content = false;
1043
1044 if (cpi->sf.rt_sf.source_metrics_sb_nonrd) {
1045 if (!cpi->sf.rt_sf.check_scene_detection || cpi->rc.frame_source_sad > 0) {
1046 calc_src_content = is_calc_src_content_needed(cpi, x, mi_row, mi_col);
1047 } else {
1048 x->content_state_sb.source_sad_nonrd = kZeroSad;
1049 }
1050 } else if ((cpi->sf.rt_sf.var_part_based_on_qidx >= 1) &&
1051 (cm->width * cm->height <= 352 * 288)) {
1052 if (cpi->rc.frame_source_sad > 0)
1053 calc_src_content = true;
1054 else
1055 x->content_state_sb.source_sad_rd = kZeroSad;
1056 }
1057 if (calc_src_content)
1058 av1_source_content_sb(cpi, x, tile_data, mi_row, mi_col);
1059 }
1060
1061 /*!\brief Encode a superblock row by breaking it into superblocks
1062 *
1063 * \ingroup partition_search
1064 * \callgraph
1065 * \callergraph
1066 * Do partition and mode search for an sb row: one row of superblocks filling up
1067 * the width of the current tile.
1068 */
encode_sb_row(AV1_COMP * cpi,ThreadData * td,TileDataEnc * tile_data,int mi_row,TokenExtra ** tp)1069 static AOM_INLINE void encode_sb_row(AV1_COMP *cpi, ThreadData *td,
1070 TileDataEnc *tile_data, int mi_row,
1071 TokenExtra **tp) {
1072 AV1_COMMON *const cm = &cpi->common;
1073 const TileInfo *const tile_info = &tile_data->tile_info;
1074 MultiThreadInfo *const mt_info = &cpi->mt_info;
1075 AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
1076 AV1EncRowMultiThreadSync *const row_mt_sync = &tile_data->row_mt_sync;
1077 bool row_mt_enabled = mt_info->row_mt_enabled;
1078 MACROBLOCK *const x = &td->mb;
1079 MACROBLOCKD *const xd = &x->e_mbd;
1080 const int sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_info);
1081 const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
1082 const int mib_size = cm->seq_params->mib_size;
1083 const int mib_size_log2 = cm->seq_params->mib_size_log2;
1084 const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2;
1085 const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
1086
1087 #if CONFIG_COLLECT_COMPONENT_TIMING
1088 start_timing(cpi, encode_sb_row_time);
1089 #endif
1090
1091 // Initialize the left context for the new SB row
1092 av1_zero_left_context(xd);
1093
1094 // Reset delta for quantizer and loof filters at the beginning of every tile
1095 if (mi_row == tile_info->mi_row_start || row_mt_enabled) {
1096 if (cm->delta_q_info.delta_q_present_flag)
1097 xd->current_base_qindex = cm->quant_params.base_qindex;
1098 if (cm->delta_q_info.delta_lf_present_flag) {
1099 av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
1100 }
1101 }
1102
1103 reset_thresh_freq_fact(x);
1104
1105 // Code each SB in the row
1106 for (int mi_col = tile_info->mi_col_start, sb_col_in_tile = 0;
1107 mi_col < tile_info->mi_col_end; mi_col += mib_size, sb_col_in_tile++) {
1108 // In realtime/allintra mode and when frequency of cost updates is off/tile,
1109 // wait for the top superblock to finish encoding. Otherwise, wait for the
1110 // top-right superblock to finish encoding.
1111 enc_row_mt->sync_read_ptr(
1112 row_mt_sync, sb_row, sb_col_in_tile - delay_wait_for_top_right_sb(cpi));
1113 const int update_cdf = tile_data->allow_update_cdf && row_mt_enabled;
1114 if (update_cdf && (tile_info->mi_row_start != mi_row)) {
1115 if ((tile_info->mi_col_start == mi_col)) {
1116 // restore frame context at the 1st column sb
1117 memcpy(xd->tile_ctx, x->row_ctx, sizeof(*xd->tile_ctx));
1118 } else {
1119 // update context
1120 int wt_left = AVG_CDF_WEIGHT_LEFT;
1121 int wt_tr = AVG_CDF_WEIGHT_TOP_RIGHT;
1122 if (tile_info->mi_col_end > (mi_col + mib_size))
1123 av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile,
1124 wt_left, wt_tr);
1125 else
1126 av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile - 1,
1127 wt_left, wt_tr);
1128 }
1129 }
1130
1131 // Update the rate cost tables for some symbols
1132 av1_set_cost_upd_freq(cpi, td, tile_info, mi_row, mi_col);
1133
1134 // Reset color coding related parameters
1135 x->color_sensitivity_sb[0] = 0;
1136 x->color_sensitivity_sb[1] = 0;
1137 x->color_sensitivity_sb_g[0] = 0;
1138 x->color_sensitivity_sb_g[1] = 0;
1139 x->color_sensitivity[0] = 0;
1140 x->color_sensitivity[1] = 0;
1141 x->content_state_sb.source_sad_nonrd = kMedSad;
1142 x->content_state_sb.source_sad_rd = kMedSad;
1143 x->content_state_sb.lighting_change = 0;
1144 x->content_state_sb.low_sumdiff = 0;
1145 x->force_zeromv_skip_for_sb = 0;
1146
1147 if (cpi->oxcf.mode == ALLINTRA) {
1148 x->intra_sb_rdmult_modifier = 128;
1149 }
1150
1151 xd->cur_frame_force_integer_mv = cm->features.cur_frame_force_integer_mv;
1152 x->source_variance = UINT_MAX;
1153 td->mb.cb_coef_buff = av1_get_cb_coeff_buffer(cpi, mi_row, mi_col);
1154
1155 // Get segment id and skip flag
1156 const struct segmentation *const seg = &cm->seg;
1157 int seg_skip = 0;
1158 if (seg->enabled) {
1159 const uint8_t *const map =
1160 seg->update_map ? cpi->enc_seg.map : cm->last_frame_seg_map;
1161 const uint8_t segment_id =
1162 map ? get_segment_id(&cm->mi_params, map, sb_size, mi_row, mi_col)
1163 : 0;
1164 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
1165 }
1166
1167 produce_gradients_for_sb(cpi, x, sb_size, mi_row, mi_col);
1168
1169 init_src_var_info_of_4x4_sub_blocks(cpi, x->src_var_info_of_4x4_sub_blocks,
1170 sb_size);
1171
1172 // Grade the temporal variation of the sb, the grade will be used to decide
1173 // fast mode search strategy for coding blocks
1174 grade_source_content_sb(cpi, x, tile_data, mi_row, mi_col);
1175
1176 // encode the superblock
1177 if (use_nonrd_mode) {
1178 encode_nonrd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
1179 } else {
1180 encode_rd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
1181 }
1182
1183 // Update the top-right context in row_mt coding
1184 if (update_cdf && (tile_info->mi_row_end > (mi_row + mib_size))) {
1185 if (sb_cols_in_tile == 1)
1186 memcpy(x->row_ctx, xd->tile_ctx, sizeof(*xd->tile_ctx));
1187 else if (sb_col_in_tile >= 1)
1188 memcpy(x->row_ctx + sb_col_in_tile - 1, xd->tile_ctx,
1189 sizeof(*xd->tile_ctx));
1190 }
1191 enc_row_mt->sync_write_ptr(row_mt_sync, sb_row, sb_col_in_tile,
1192 sb_cols_in_tile);
1193 }
1194
1195 #if CONFIG_COLLECT_COMPONENT_TIMING
1196 end_timing(cpi, encode_sb_row_time);
1197 #endif
1198 }
1199
init_encode_frame_mb_context(AV1_COMP * cpi)1200 static AOM_INLINE void init_encode_frame_mb_context(AV1_COMP *cpi) {
1201 AV1_COMMON *const cm = &cpi->common;
1202 const int num_planes = av1_num_planes(cm);
1203 MACROBLOCK *const x = &cpi->td.mb;
1204 MACROBLOCKD *const xd = &x->e_mbd;
1205
1206 // Copy data over into macro block data structures.
1207 av1_setup_src_planes(x, cpi->source, 0, 0, num_planes,
1208 cm->seq_params->sb_size);
1209
1210 av1_setup_block_planes(xd, cm->seq_params->subsampling_x,
1211 cm->seq_params->subsampling_y, num_planes);
1212 }
1213
av1_alloc_tile_data(AV1_COMP * cpi)1214 void av1_alloc_tile_data(AV1_COMP *cpi) {
1215 AV1_COMMON *const cm = &cpi->common;
1216 const int tile_cols = cm->tiles.cols;
1217 const int tile_rows = cm->tiles.rows;
1218
1219 av1_row_mt_mem_dealloc(cpi);
1220
1221 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
1222 CHECK_MEM_ERROR(
1223 cm, cpi->tile_data,
1224 aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->tile_data)));
1225
1226 cpi->allocated_tiles = tile_cols * tile_rows;
1227 }
1228
av1_init_tile_data(AV1_COMP * cpi)1229 void av1_init_tile_data(AV1_COMP *cpi) {
1230 AV1_COMMON *const cm = &cpi->common;
1231 const int num_planes = av1_num_planes(cm);
1232 const int tile_cols = cm->tiles.cols;
1233 const int tile_rows = cm->tiles.rows;
1234 int tile_col, tile_row;
1235 TokenInfo *const token_info = &cpi->token_info;
1236 TokenExtra *pre_tok = token_info->tile_tok[0][0];
1237 TokenList *tplist = token_info->tplist[0][0];
1238 unsigned int tile_tok = 0;
1239 int tplist_count = 0;
1240
1241 if (!is_stat_generation_stage(cpi) &&
1242 cm->features.allow_screen_content_tools) {
1243 // Number of tokens for which token info needs to be allocated.
1244 unsigned int tokens_required =
1245 get_token_alloc(cm->mi_params.mb_rows, cm->mi_params.mb_cols,
1246 MAX_SB_SIZE_LOG2, num_planes);
1247 // Allocate/reallocate memory for token related info if the number of tokens
1248 // required is more than the number of tokens already allocated. This could
1249 // occur in case of the following:
1250 // 1) If the memory is not yet allocated
1251 // 2) If the frame dimensions have changed
1252 const bool realloc_tokens = tokens_required > token_info->tokens_allocated;
1253 if (realloc_tokens) {
1254 free_token_info(token_info);
1255 alloc_token_info(cm, token_info, tokens_required);
1256 pre_tok = token_info->tile_tok[0][0];
1257 tplist = token_info->tplist[0][0];
1258 }
1259 }
1260
1261 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
1262 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
1263 TileDataEnc *const tile_data =
1264 &cpi->tile_data[tile_row * tile_cols + tile_col];
1265 TileInfo *const tile_info = &tile_data->tile_info;
1266 av1_tile_init(tile_info, cm, tile_row, tile_col);
1267 tile_data->firstpass_top_mv = kZeroMv;
1268 tile_data->abs_sum_level = 0;
1269
1270 if (is_token_info_allocated(token_info)) {
1271 token_info->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
1272 pre_tok = token_info->tile_tok[tile_row][tile_col];
1273 tile_tok = allocated_tokens(
1274 tile_info, cm->seq_params->mib_size_log2 + MI_SIZE_LOG2,
1275 num_planes);
1276 token_info->tplist[tile_row][tile_col] = tplist + tplist_count;
1277 tplist = token_info->tplist[tile_row][tile_col];
1278 tplist_count = av1_get_sb_rows_in_tile(cm, tile_info);
1279 }
1280 tile_data->allow_update_cdf = !cm->tiles.large_scale;
1281 tile_data->allow_update_cdf = tile_data->allow_update_cdf &&
1282 !cm->features.disable_cdf_update &&
1283 !delay_wait_for_top_right_sb(cpi);
1284 tile_data->tctx = *cm->fc;
1285 }
1286 }
1287 }
1288
1289 // Populate the start palette token info prior to encoding an SB row.
get_token_start(AV1_COMP * cpi,const TileInfo * tile_info,int tile_row,int tile_col,int mi_row,TokenExtra ** tp)1290 static AOM_INLINE void get_token_start(AV1_COMP *cpi, const TileInfo *tile_info,
1291 int tile_row, int tile_col, int mi_row,
1292 TokenExtra **tp) {
1293 const TokenInfo *token_info = &cpi->token_info;
1294 if (!is_token_info_allocated(token_info)) return;
1295
1296 const AV1_COMMON *cm = &cpi->common;
1297 const int num_planes = av1_num_planes(cm);
1298 TokenList *const tplist = cpi->token_info.tplist[tile_row][tile_col];
1299 const int sb_row_in_tile =
1300 (mi_row - tile_info->mi_row_start) >> cm->seq_params->mib_size_log2;
1301
1302 get_start_tok(cpi, tile_row, tile_col, mi_row, tp,
1303 cm->seq_params->mib_size_log2 + MI_SIZE_LOG2, num_planes);
1304 assert(tplist != NULL);
1305 tplist[sb_row_in_tile].start = *tp;
1306 }
1307
1308 // Populate the token count after encoding an SB row.
populate_token_count(AV1_COMP * cpi,const TileInfo * tile_info,int tile_row,int tile_col,int mi_row,TokenExtra * tok)1309 static AOM_INLINE void populate_token_count(AV1_COMP *cpi,
1310 const TileInfo *tile_info,
1311 int tile_row, int tile_col,
1312 int mi_row, TokenExtra *tok) {
1313 const TokenInfo *token_info = &cpi->token_info;
1314 if (!is_token_info_allocated(token_info)) return;
1315
1316 const AV1_COMMON *cm = &cpi->common;
1317 const int num_planes = av1_num_planes(cm);
1318 TokenList *const tplist = token_info->tplist[tile_row][tile_col];
1319 const int sb_row_in_tile =
1320 (mi_row - tile_info->mi_row_start) >> cm->seq_params->mib_size_log2;
1321 const int tile_mb_cols =
1322 (tile_info->mi_col_end - tile_info->mi_col_start + 2) >> 2;
1323 const int num_mb_rows_in_sb =
1324 ((1 << (cm->seq_params->mib_size_log2 + MI_SIZE_LOG2)) + 8) >> 4;
1325 tplist[sb_row_in_tile].count =
1326 (unsigned int)(tok - tplist[sb_row_in_tile].start);
1327
1328 assert((unsigned int)(tok - tplist[sb_row_in_tile].start) <=
1329 get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
1330 cm->seq_params->mib_size_log2 + MI_SIZE_LOG2,
1331 num_planes));
1332
1333 (void)num_planes;
1334 (void)tile_mb_cols;
1335 (void)num_mb_rows_in_sb;
1336 }
1337
1338 /*!\brief Encode a superblock row
1339 *
1340 * \ingroup partition_search
1341 */
av1_encode_sb_row(AV1_COMP * cpi,ThreadData * td,int tile_row,int tile_col,int mi_row)1342 void av1_encode_sb_row(AV1_COMP *cpi, ThreadData *td, int tile_row,
1343 int tile_col, int mi_row) {
1344 AV1_COMMON *const cm = &cpi->common;
1345 const int tile_cols = cm->tiles.cols;
1346 TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col];
1347 const TileInfo *const tile_info = &this_tile->tile_info;
1348 TokenExtra *tok = NULL;
1349
1350 get_token_start(cpi, tile_info, tile_row, tile_col, mi_row, &tok);
1351
1352 encode_sb_row(cpi, td, this_tile, mi_row, &tok);
1353
1354 populate_token_count(cpi, tile_info, tile_row, tile_col, mi_row, tok);
1355 }
1356
1357 /*!\brief Encode a tile
1358 *
1359 * \ingroup partition_search
1360 */
av1_encode_tile(AV1_COMP * cpi,ThreadData * td,int tile_row,int tile_col)1361 void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
1362 int tile_col) {
1363 AV1_COMMON *const cm = &cpi->common;
1364 TileDataEnc *const this_tile =
1365 &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1366 const TileInfo *const tile_info = &this_tile->tile_info;
1367
1368 if (!cpi->sf.rt_sf.use_nonrd_pick_mode) av1_inter_mode_data_init(this_tile);
1369
1370 av1_zero_above_context(cm, &td->mb.e_mbd, tile_info->mi_col_start,
1371 tile_info->mi_col_end, tile_row);
1372 av1_init_above_context(&cm->above_contexts, av1_num_planes(cm), tile_row,
1373 &td->mb.e_mbd);
1374
1375 if (cpi->oxcf.intra_mode_cfg.enable_cfl_intra)
1376 cfl_init(&td->mb.e_mbd.cfl, cm->seq_params);
1377
1378 if (td->mb.txfm_search_info.mb_rd_record != NULL) {
1379 av1_crc32c_calculator_init(
1380 &td->mb.txfm_search_info.mb_rd_record->crc_calculator);
1381 }
1382
1383 for (int mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
1384 mi_row += cm->seq_params->mib_size) {
1385 av1_encode_sb_row(cpi, td, tile_row, tile_col, mi_row);
1386 }
1387 this_tile->abs_sum_level = td->abs_sum_level;
1388 }
1389
1390 /*!\brief Break one frame into tiles and encode the tiles
1391 *
1392 * \ingroup partition_search
1393 *
1394 * \param[in] cpi Top-level encoder structure
1395 */
encode_tiles(AV1_COMP * cpi)1396 static AOM_INLINE void encode_tiles(AV1_COMP *cpi) {
1397 AV1_COMMON *const cm = &cpi->common;
1398 const int tile_cols = cm->tiles.cols;
1399 const int tile_rows = cm->tiles.rows;
1400 int tile_col, tile_row;
1401
1402 MACROBLOCK *const mb = &cpi->td.mb;
1403 assert(IMPLIES(cpi->tile_data == NULL,
1404 cpi->allocated_tiles < tile_cols * tile_rows));
1405 if (cpi->allocated_tiles < tile_cols * tile_rows) av1_alloc_tile_data(cpi);
1406
1407 av1_init_tile_data(cpi);
1408 av1_alloc_mb_data(cpi, mb);
1409
1410 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
1411 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
1412 TileDataEnc *const this_tile =
1413 &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1414 cpi->td.intrabc_used = 0;
1415 cpi->td.deltaq_used = 0;
1416 cpi->td.abs_sum_level = 0;
1417 cpi->td.rd_counts.seg_tmp_pred_cost[0] = 0;
1418 cpi->td.rd_counts.seg_tmp_pred_cost[1] = 0;
1419 cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx;
1420 cpi->td.mb.tile_pb_ctx = &this_tile->tctx;
1421 av1_init_rtc_counters(&cpi->td.mb);
1422 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
1423 if (!frame_is_intra_only(&cpi->common))
1424 av1_accumulate_rtc_counters(cpi, &cpi->td.mb);
1425 cpi->intrabc_used |= cpi->td.intrabc_used;
1426 cpi->deltaq_used |= cpi->td.deltaq_used;
1427 }
1428 }
1429
1430 av1_dealloc_mb_data(cm, mb);
1431 }
1432
1433 // Set the relative distance of a reference frame w.r.t. current frame
set_rel_frame_dist(const AV1_COMMON * const cm,RefFrameDistanceInfo * const ref_frame_dist_info,const int ref_frame_flags)1434 static AOM_INLINE void set_rel_frame_dist(
1435 const AV1_COMMON *const cm, RefFrameDistanceInfo *const ref_frame_dist_info,
1436 const int ref_frame_flags) {
1437 MV_REFERENCE_FRAME ref_frame;
1438 int min_past_dist = INT32_MAX, min_future_dist = INT32_MAX;
1439 ref_frame_dist_info->nearest_past_ref = NONE_FRAME;
1440 ref_frame_dist_info->nearest_future_ref = NONE_FRAME;
1441 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
1442 ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = 0;
1443 if (ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
1444 int dist = av1_encoder_get_relative_dist(
1445 cm->cur_frame->ref_display_order_hint[ref_frame - LAST_FRAME],
1446 cm->current_frame.display_order_hint);
1447 ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = dist;
1448 // Get the nearest ref_frame in the past
1449 if (abs(dist) < min_past_dist && dist < 0) {
1450 ref_frame_dist_info->nearest_past_ref = ref_frame;
1451 min_past_dist = abs(dist);
1452 }
1453 // Get the nearest ref_frame in the future
1454 if (dist < min_future_dist && dist > 0) {
1455 ref_frame_dist_info->nearest_future_ref = ref_frame;
1456 min_future_dist = dist;
1457 }
1458 }
1459 }
1460 }
1461
refs_are_one_sided(const AV1_COMMON * cm)1462 static INLINE int refs_are_one_sided(const AV1_COMMON *cm) {
1463 assert(!frame_is_intra_only(cm));
1464
1465 int one_sided_refs = 1;
1466 const int cur_display_order_hint = cm->current_frame.display_order_hint;
1467 for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
1468 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
1469 if (buf == NULL) continue;
1470 if (av1_encoder_get_relative_dist(buf->display_order_hint,
1471 cur_display_order_hint) > 0) {
1472 one_sided_refs = 0; // bwd reference
1473 break;
1474 }
1475 }
1476 return one_sided_refs;
1477 }
1478
get_skip_mode_ref_offsets(const AV1_COMMON * cm,int ref_order_hint[2])1479 static INLINE void get_skip_mode_ref_offsets(const AV1_COMMON *cm,
1480 int ref_order_hint[2]) {
1481 const SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
1482 ref_order_hint[0] = ref_order_hint[1] = 0;
1483 if (!skip_mode_info->skip_mode_allowed) return;
1484
1485 const RefCntBuffer *const buf_0 =
1486 get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_0);
1487 const RefCntBuffer *const buf_1 =
1488 get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_1);
1489 assert(buf_0 != NULL && buf_1 != NULL);
1490
1491 ref_order_hint[0] = buf_0->order_hint;
1492 ref_order_hint[1] = buf_1->order_hint;
1493 }
1494
check_skip_mode_enabled(AV1_COMP * const cpi)1495 static int check_skip_mode_enabled(AV1_COMP *const cpi) {
1496 AV1_COMMON *const cm = &cpi->common;
1497
1498 av1_setup_skip_mode_allowed(cm);
1499 if (!cm->current_frame.skip_mode_info.skip_mode_allowed) return 0;
1500
1501 // Turn off skip mode if the temporal distances of the reference pair to the
1502 // current frame are different by more than 1 frame.
1503 const int cur_offset = (int)cm->current_frame.order_hint;
1504 int ref_offset[2];
1505 get_skip_mode_ref_offsets(cm, ref_offset);
1506 const int cur_to_ref0 = get_relative_dist(&cm->seq_params->order_hint_info,
1507 cur_offset, ref_offset[0]);
1508 const int cur_to_ref1 = abs(get_relative_dist(
1509 &cm->seq_params->order_hint_info, cur_offset, ref_offset[1]));
1510 if (abs(cur_to_ref0 - cur_to_ref1) > 1) return 0;
1511
1512 // High Latency: Turn off skip mode if all refs are fwd.
1513 if (cpi->all_one_sided_refs && cpi->oxcf.gf_cfg.lag_in_frames > 0) return 0;
1514
1515 static const int flag_list[REF_FRAMES] = { 0,
1516 AOM_LAST_FLAG,
1517 AOM_LAST2_FLAG,
1518 AOM_LAST3_FLAG,
1519 AOM_GOLD_FLAG,
1520 AOM_BWD_FLAG,
1521 AOM_ALT2_FLAG,
1522 AOM_ALT_FLAG };
1523 const int ref_frame[2] = {
1524 cm->current_frame.skip_mode_info.ref_frame_idx_0 + LAST_FRAME,
1525 cm->current_frame.skip_mode_info.ref_frame_idx_1 + LAST_FRAME
1526 };
1527 if (!(cpi->ref_frame_flags & flag_list[ref_frame[0]]) ||
1528 !(cpi->ref_frame_flags & flag_list[ref_frame[1]]))
1529 return 0;
1530
1531 return 1;
1532 }
1533
set_default_interp_skip_flags(const AV1_COMMON * cm,InterpSearchFlags * interp_search_flags)1534 static AOM_INLINE void set_default_interp_skip_flags(
1535 const AV1_COMMON *cm, InterpSearchFlags *interp_search_flags) {
1536 const int num_planes = av1_num_planes(cm);
1537 interp_search_flags->default_interp_skip_flags =
1538 (num_planes == 1) ? INTERP_SKIP_LUMA_EVAL_CHROMA
1539 : INTERP_SKIP_LUMA_SKIP_CHROMA;
1540 }
1541
setup_prune_ref_frame_mask(AV1_COMP * cpi)1542 static AOM_INLINE void setup_prune_ref_frame_mask(AV1_COMP *cpi) {
1543 if ((!cpi->oxcf.ref_frm_cfg.enable_onesided_comp ||
1544 cpi->sf.inter_sf.disable_onesided_comp) &&
1545 cpi->all_one_sided_refs) {
1546 // Disable all compound references
1547 cpi->prune_ref_frame_mask = (1 << MODE_CTX_REF_FRAMES) - (1 << REF_FRAMES);
1548 } else if (!cpi->sf.rt_sf.use_nonrd_pick_mode &&
1549 cpi->sf.inter_sf.selective_ref_frame >= 2) {
1550 AV1_COMMON *const cm = &cpi->common;
1551 const int cur_frame_display_order_hint =
1552 cm->current_frame.display_order_hint;
1553 unsigned int *ref_display_order_hint =
1554 cm->cur_frame->ref_display_order_hint;
1555 const int arf2_dist = av1_encoder_get_relative_dist(
1556 ref_display_order_hint[ALTREF2_FRAME - LAST_FRAME],
1557 cur_frame_display_order_hint);
1558 const int bwd_dist = av1_encoder_get_relative_dist(
1559 ref_display_order_hint[BWDREF_FRAME - LAST_FRAME],
1560 cur_frame_display_order_hint);
1561
1562 for (int ref_idx = REF_FRAMES; ref_idx < MODE_CTX_REF_FRAMES; ++ref_idx) {
1563 MV_REFERENCE_FRAME rf[2];
1564 av1_set_ref_frame(rf, ref_idx);
1565 if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[0]]) ||
1566 !(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[1]])) {
1567 continue;
1568 }
1569
1570 if (!cpi->all_one_sided_refs) {
1571 int ref_dist[2];
1572 for (int i = 0; i < 2; ++i) {
1573 ref_dist[i] = av1_encoder_get_relative_dist(
1574 ref_display_order_hint[rf[i] - LAST_FRAME],
1575 cur_frame_display_order_hint);
1576 }
1577
1578 // One-sided compound is used only when all reference frames are
1579 // one-sided.
1580 if ((ref_dist[0] > 0) == (ref_dist[1] > 0)) {
1581 cpi->prune_ref_frame_mask |= 1 << ref_idx;
1582 }
1583 }
1584
1585 if (cpi->sf.inter_sf.selective_ref_frame >= 4 &&
1586 (rf[0] == ALTREF2_FRAME || rf[1] == ALTREF2_FRAME) &&
1587 (cpi->ref_frame_flags & av1_ref_frame_flag_list[BWDREF_FRAME])) {
1588 // Check if both ALTREF2_FRAME and BWDREF_FRAME are future references.
1589 if (arf2_dist > 0 && bwd_dist > 0 && bwd_dist <= arf2_dist) {
1590 // Drop ALTREF2_FRAME as a reference if BWDREF_FRAME is a closer
1591 // reference to the current frame than ALTREF2_FRAME
1592 cpi->prune_ref_frame_mask |= 1 << ref_idx;
1593 }
1594 }
1595 }
1596 }
1597 }
1598
allow_deltaq_mode(AV1_COMP * cpi)1599 static int allow_deltaq_mode(AV1_COMP *cpi) {
1600 #if !CONFIG_REALTIME_ONLY
1601 AV1_COMMON *const cm = &cpi->common;
1602 BLOCK_SIZE sb_size = cm->seq_params->sb_size;
1603 int sbs_wide = mi_size_wide[sb_size];
1604 int sbs_high = mi_size_high[sb_size];
1605
1606 int64_t delta_rdcost = 0;
1607 for (int mi_row = 0; mi_row < cm->mi_params.mi_rows; mi_row += sbs_high) {
1608 for (int mi_col = 0; mi_col < cm->mi_params.mi_cols; mi_col += sbs_wide) {
1609 int64_t this_delta_rdcost = 0;
1610 av1_get_q_for_deltaq_objective(cpi, &cpi->td, &this_delta_rdcost, sb_size,
1611 mi_row, mi_col);
1612 delta_rdcost += this_delta_rdcost;
1613 }
1614 }
1615 return delta_rdcost < 0;
1616 #else
1617 (void)cpi;
1618 return 1;
1619 #endif // !CONFIG_REALTIME_ONLY
1620 }
1621
1622 #define FORCE_ZMV_SKIP_128X128_BLK_DIFF 10000
1623 #define FORCE_ZMV_SKIP_MAX_PER_PIXEL_DIFF 4
1624
1625 // Populates block level thresholds for force zeromv-skip decision
populate_thresh_to_force_zeromv_skip(AV1_COMP * cpi)1626 static void populate_thresh_to_force_zeromv_skip(AV1_COMP *cpi) {
1627 if (cpi->sf.rt_sf.part_early_exit_zeromv == 0) return;
1628
1629 // Threshold for forcing zeromv-skip decision is as below:
1630 // For 128x128 blocks, threshold is 10000 and per pixel threshold is 0.6103.
1631 // For 64x64 blocks, threshold is 5000 and per pixel threshold is 1.221
1632 // allowing slightly higher error for smaller blocks.
1633 // Per Pixel Threshold of 64x64 block Area of 64x64 block 1 1
1634 // ------------------------------------=sqrt(---------------------)=sqrt(-)=-
1635 // Per Pixel Threshold of 128x128 block Area of 128x128 block 4 2
1636 // Thus, per pixel thresholds for blocks of size 32x32, 16x16,... can be
1637 // chosen as 2.442, 4.884,.... As the per pixel error tends to be higher for
1638 // small blocks, the same is clipped to 4.
1639 const unsigned int thresh_exit_128x128_part = FORCE_ZMV_SKIP_128X128_BLK_DIFF;
1640 const int num_128x128_pix =
1641 block_size_wide[BLOCK_128X128] * block_size_high[BLOCK_128X128];
1642
1643 for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES_ALL; bsize++) {
1644 const int num_block_pix = block_size_wide[bsize] * block_size_high[bsize];
1645
1646 // Calculate the threshold for zeromv-skip decision based on area of the
1647 // partition
1648 unsigned int thresh_exit_part_blk =
1649 (unsigned int)(thresh_exit_128x128_part *
1650 sqrt((double)num_block_pix / num_128x128_pix) +
1651 0.5);
1652 thresh_exit_part_blk = AOMMIN(
1653 thresh_exit_part_blk,
1654 (unsigned int)(FORCE_ZMV_SKIP_MAX_PER_PIXEL_DIFF * num_block_pix));
1655 cpi->zeromv_skip_thresh_exit_part[bsize] = thresh_exit_part_blk;
1656 }
1657 }
1658
1659 /*!\brief Encoder setup(only for the current frame), encoding, and recontruction
1660 * for a single frame
1661 *
1662 * \ingroup high_level_algo
1663 */
encode_frame_internal(AV1_COMP * cpi)1664 static AOM_INLINE void encode_frame_internal(AV1_COMP *cpi) {
1665 ThreadData *const td = &cpi->td;
1666 MACROBLOCK *const x = &td->mb;
1667 AV1_COMMON *const cm = &cpi->common;
1668 CommonModeInfoParams *const mi_params = &cm->mi_params;
1669 FeatureFlags *const features = &cm->features;
1670 MACROBLOCKD *const xd = &x->e_mbd;
1671 RD_COUNTS *const rdc = &cpi->td.rd_counts;
1672 #if CONFIG_FPMT_TEST
1673 FrameProbInfo *const temp_frame_probs = &cpi->ppi->temp_frame_probs;
1674 FrameProbInfo *const temp_frame_probs_simulation =
1675 &cpi->ppi->temp_frame_probs_simulation;
1676 #endif
1677 FrameProbInfo *const frame_probs = &cpi->ppi->frame_probs;
1678 IntraBCHashInfo *const intrabc_hash_info = &x->intrabc_hash_info;
1679 MultiThreadInfo *const mt_info = &cpi->mt_info;
1680 AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
1681 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
1682 const DELTAQ_MODE deltaq_mode = oxcf->q_cfg.deltaq_mode;
1683 int i;
1684
1685 if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
1686 mi_params->setup_mi(mi_params);
1687 }
1688
1689 set_mi_offsets(mi_params, xd, 0, 0);
1690
1691 av1_zero(*td->counts);
1692 av1_zero(rdc->tx_type_used);
1693 av1_zero(rdc->obmc_used);
1694 av1_zero(rdc->warped_used);
1695 av1_zero(rdc->seg_tmp_pred_cost);
1696
1697 // Reset the flag.
1698 cpi->intrabc_used = 0;
1699 // Need to disable intrabc when superres is selected
1700 if (av1_superres_scaled(cm)) {
1701 features->allow_intrabc = 0;
1702 }
1703
1704 features->allow_intrabc &= (oxcf->kf_cfg.enable_intrabc);
1705
1706 if (features->allow_warped_motion &&
1707 cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
1708 const FRAME_UPDATE_TYPE update_type =
1709 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
1710 int warped_probability =
1711 #if CONFIG_FPMT_TEST
1712 cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE
1713 ? temp_frame_probs->warped_probs[update_type]
1714 :
1715 #endif // CONFIG_FPMT_TEST
1716 frame_probs->warped_probs[update_type];
1717 if (warped_probability < cpi->sf.inter_sf.prune_warped_prob_thresh)
1718 features->allow_warped_motion = 0;
1719 }
1720
1721 int hash_table_created = 0;
1722 if (!is_stat_generation_stage(cpi) && av1_use_hash_me(cpi) &&
1723 !cpi->sf.rt_sf.use_nonrd_pick_mode) {
1724 // TODO(any): move this outside of the recoding loop to avoid recalculating
1725 // the hash table.
1726 // add to hash table
1727 const int pic_width = cpi->source->y_crop_width;
1728 const int pic_height = cpi->source->y_crop_height;
1729 uint32_t *block_hash_values[2][2];
1730 int8_t *is_block_same[2][3];
1731 int k, j;
1732
1733 for (k = 0; k < 2; k++) {
1734 for (j = 0; j < 2; j++) {
1735 CHECK_MEM_ERROR(cm, block_hash_values[k][j],
1736 aom_malloc(sizeof(uint32_t) * pic_width * pic_height));
1737 }
1738
1739 for (j = 0; j < 3; j++) {
1740 CHECK_MEM_ERROR(cm, is_block_same[k][j],
1741 aom_malloc(sizeof(int8_t) * pic_width * pic_height));
1742 }
1743 }
1744
1745 av1_hash_table_init(intrabc_hash_info);
1746 if (!av1_hash_table_create(&intrabc_hash_info->intrabc_hash_table)) {
1747 aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
1748 "Error allocating intrabc_hash_table");
1749 }
1750 hash_table_created = 1;
1751 av1_generate_block_2x2_hash_value(intrabc_hash_info, cpi->source,
1752 block_hash_values[0], is_block_same[0]);
1753 // Hash data generated for screen contents is used for intraBC ME
1754 const int min_alloc_size = block_size_wide[mi_params->mi_alloc_bsize];
1755 const int max_sb_size =
1756 (1 << (cm->seq_params->mib_size_log2 + MI_SIZE_LOG2));
1757 int src_idx = 0;
1758 bool error = false;
1759 for (int size = 4; size <= max_sb_size; size *= 2, src_idx = !src_idx) {
1760 const int dst_idx = !src_idx;
1761 av1_generate_block_hash_value(
1762 intrabc_hash_info, cpi->source, size, block_hash_values[src_idx],
1763 block_hash_values[dst_idx], is_block_same[src_idx],
1764 is_block_same[dst_idx]);
1765 if (size >= min_alloc_size) {
1766 if (!av1_add_to_hash_map_by_row_with_precal_data(
1767 &intrabc_hash_info->intrabc_hash_table,
1768 block_hash_values[dst_idx], is_block_same[dst_idx][2],
1769 pic_width, pic_height, size)) {
1770 error = true;
1771 break;
1772 }
1773 }
1774 }
1775
1776 for (k = 0; k < 2; k++) {
1777 for (j = 0; j < 2; j++) {
1778 aom_free(block_hash_values[k][j]);
1779 }
1780
1781 for (j = 0; j < 3; j++) {
1782 aom_free(is_block_same[k][j]);
1783 }
1784 }
1785
1786 if (error) {
1787 aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
1788 "Error adding data to intrabc_hash_table");
1789 }
1790 }
1791
1792 const CommonQuantParams *quant_params = &cm->quant_params;
1793 for (i = 0; i < MAX_SEGMENTS; ++i) {
1794 const int qindex =
1795 cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex)
1796 : quant_params->base_qindex;
1797 xd->lossless[i] =
1798 qindex == 0 && quant_params->y_dc_delta_q == 0 &&
1799 quant_params->u_dc_delta_q == 0 && quant_params->u_ac_delta_q == 0 &&
1800 quant_params->v_dc_delta_q == 0 && quant_params->v_ac_delta_q == 0;
1801 if (xd->lossless[i]) cpi->enc_seg.has_lossless_segment = 1;
1802 xd->qindex[i] = qindex;
1803 if (xd->lossless[i]) {
1804 cpi->optimize_seg_arr[i] = NO_TRELLIS_OPT;
1805 } else {
1806 cpi->optimize_seg_arr[i] = cpi->sf.rd_sf.optimize_coefficients;
1807 }
1808 }
1809 features->coded_lossless = is_coded_lossless(cm, xd);
1810 features->all_lossless = features->coded_lossless && !av1_superres_scaled(cm);
1811
1812 // Fix delta q resolution for the moment
1813
1814 cm->delta_q_info.delta_q_res = 0;
1815 if (cpi->use_ducky_encode) {
1816 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_DUCKY_ENCODE;
1817 } else if (cpi->oxcf.q_cfg.aq_mode != CYCLIC_REFRESH_AQ) {
1818 if (deltaq_mode == DELTA_Q_OBJECTIVE)
1819 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_OBJECTIVE;
1820 else if (deltaq_mode == DELTA_Q_PERCEPTUAL)
1821 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
1822 else if (deltaq_mode == DELTA_Q_PERCEPTUAL_AI)
1823 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
1824 else if (deltaq_mode == DELTA_Q_USER_RATING_BASED)
1825 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
1826 else if (deltaq_mode == DELTA_Q_HDR)
1827 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
1828 // Set delta_q_present_flag before it is used for the first time
1829 cm->delta_q_info.delta_lf_res = DEFAULT_DELTA_LF_RES;
1830 cm->delta_q_info.delta_q_present_flag = deltaq_mode != NO_DELTA_Q;
1831
1832 // Turn off cm->delta_q_info.delta_q_present_flag if objective delta_q
1833 // is used for ineligible frames. That effectively will turn off row_mt
1834 // usage. Note objective delta_q and tpl eligible frames are only altref
1835 // frames currently.
1836 const GF_GROUP *gf_group = &cpi->ppi->gf_group;
1837 if (cm->delta_q_info.delta_q_present_flag) {
1838 if (deltaq_mode == DELTA_Q_OBJECTIVE &&
1839 gf_group->update_type[cpi->gf_frame_index] == LF_UPDATE)
1840 cm->delta_q_info.delta_q_present_flag = 0;
1841
1842 if (deltaq_mode == DELTA_Q_OBJECTIVE &&
1843 cm->delta_q_info.delta_q_present_flag) {
1844 cm->delta_q_info.delta_q_present_flag &= allow_deltaq_mode(cpi);
1845 }
1846 }
1847
1848 // Reset delta_q_used flag
1849 cpi->deltaq_used = 0;
1850
1851 cm->delta_q_info.delta_lf_present_flag =
1852 cm->delta_q_info.delta_q_present_flag &&
1853 oxcf->tool_cfg.enable_deltalf_mode;
1854 cm->delta_q_info.delta_lf_multi = DEFAULT_DELTA_LF_MULTI;
1855
1856 // update delta_q_present_flag and delta_lf_present_flag based on
1857 // base_qindex
1858 cm->delta_q_info.delta_q_present_flag &= quant_params->base_qindex > 0;
1859 cm->delta_q_info.delta_lf_present_flag &= quant_params->base_qindex > 0;
1860 } else {
1861 cpi->cyclic_refresh->actual_num_seg1_blocks = 0;
1862 cpi->cyclic_refresh->actual_num_seg2_blocks = 0;
1863 cpi->rc.cnt_zeromv = 0;
1864 }
1865
1866 av1_frame_init_quantizer(cpi);
1867 init_encode_frame_mb_context(cpi);
1868 set_default_interp_skip_flags(cm, &cpi->interp_search_flags);
1869
1870 if (cm->prev_frame && cm->prev_frame->seg.enabled)
1871 cm->last_frame_seg_map = cm->prev_frame->seg_map;
1872 else
1873 cm->last_frame_seg_map = NULL;
1874 if (features->allow_intrabc || features->coded_lossless) {
1875 av1_set_default_ref_deltas(cm->lf.ref_deltas);
1876 av1_set_default_mode_deltas(cm->lf.mode_deltas);
1877 } else if (cm->prev_frame) {
1878 memcpy(cm->lf.ref_deltas, cm->prev_frame->ref_deltas, REF_FRAMES);
1879 memcpy(cm->lf.mode_deltas, cm->prev_frame->mode_deltas, MAX_MODE_LF_DELTAS);
1880 }
1881 memcpy(cm->cur_frame->ref_deltas, cm->lf.ref_deltas, REF_FRAMES);
1882 memcpy(cm->cur_frame->mode_deltas, cm->lf.mode_deltas, MAX_MODE_LF_DELTAS);
1883
1884 cpi->all_one_sided_refs =
1885 frame_is_intra_only(cm) ? 0 : refs_are_one_sided(cm);
1886
1887 cpi->prune_ref_frame_mask = 0;
1888 // Figure out which ref frames can be skipped at frame level.
1889 setup_prune_ref_frame_mask(cpi);
1890
1891 x->txfm_search_info.txb_split_count = 0;
1892 #if CONFIG_SPEED_STATS
1893 x->txfm_search_info.tx_search_count = 0;
1894 #endif // CONFIG_SPEED_STATS
1895
1896 #if !CONFIG_REALTIME_ONLY
1897 #if CONFIG_COLLECT_COMPONENT_TIMING
1898 start_timing(cpi, av1_compute_global_motion_time);
1899 #endif
1900 av1_compute_global_motion_facade(cpi);
1901 #if CONFIG_COLLECT_COMPONENT_TIMING
1902 end_timing(cpi, av1_compute_global_motion_time);
1903 #endif
1904 #endif // !CONFIG_REALTIME_ONLY
1905
1906 #if CONFIG_COLLECT_COMPONENT_TIMING
1907 start_timing(cpi, av1_setup_motion_field_time);
1908 #endif
1909 av1_calculate_ref_frame_side(cm);
1910 if (features->allow_ref_frame_mvs) av1_setup_motion_field(cm);
1911 #if CONFIG_COLLECT_COMPONENT_TIMING
1912 end_timing(cpi, av1_setup_motion_field_time);
1913 #endif
1914
1915 cm->current_frame.skip_mode_info.skip_mode_flag =
1916 check_skip_mode_enabled(cpi);
1917
1918 // Initialization of skip mode cost depends on the value of
1919 // 'skip_mode_flag'. This initialization happens in the function
1920 // av1_fill_mode_rates(), which is in turn called in
1921 // av1_initialize_rd_consts(). Thus, av1_initialize_rd_consts()
1922 // has to be called after 'skip_mode_flag' is initialized.
1923 av1_initialize_rd_consts(cpi);
1924 av1_set_sad_per_bit(cpi, &x->sadperbit, quant_params->base_qindex);
1925 populate_thresh_to_force_zeromv_skip(cpi);
1926
1927 enc_row_mt->sync_read_ptr = av1_row_mt_sync_read_dummy;
1928 enc_row_mt->sync_write_ptr = av1_row_mt_sync_write_dummy;
1929 mt_info->row_mt_enabled = 0;
1930 mt_info->pack_bs_mt_enabled = AOMMIN(mt_info->num_mod_workers[MOD_PACK_BS],
1931 cm->tiles.cols * cm->tiles.rows) > 1;
1932
1933 if (oxcf->row_mt && (mt_info->num_workers > 1)) {
1934 mt_info->row_mt_enabled = 1;
1935 enc_row_mt->sync_read_ptr = av1_row_mt_sync_read;
1936 enc_row_mt->sync_write_ptr = av1_row_mt_sync_write;
1937 av1_encode_tiles_row_mt(cpi);
1938 } else {
1939 if (AOMMIN(mt_info->num_workers, cm->tiles.cols * cm->tiles.rows) > 1) {
1940 av1_encode_tiles_mt(cpi);
1941 } else {
1942 // Preallocate the pc_tree for realtime coding to reduce the cost of
1943 // memory allocation.
1944 const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
1945 td->rt_pc_root = use_nonrd_mode
1946 ? av1_alloc_pc_tree_node(cm->seq_params->sb_size)
1947 : NULL;
1948 encode_tiles(cpi);
1949 av1_free_pc_tree_recursive(td->rt_pc_root, av1_num_planes(cm), 0, 0);
1950 }
1951 }
1952
1953 // If intrabc is allowed but never selected, reset the allow_intrabc flag.
1954 if (features->allow_intrabc && !cpi->intrabc_used) {
1955 features->allow_intrabc = 0;
1956 }
1957 if (features->allow_intrabc) {
1958 cm->delta_q_info.delta_lf_present_flag = 0;
1959 }
1960
1961 if (cm->delta_q_info.delta_q_present_flag && cpi->deltaq_used == 0) {
1962 cm->delta_q_info.delta_q_present_flag = 0;
1963 }
1964
1965 // Set the transform size appropriately before bitstream creation
1966 const MODE_EVAL_TYPE eval_type =
1967 cpi->sf.winner_mode_sf.enable_winner_mode_for_tx_size_srch
1968 ? WINNER_MODE_EVAL
1969 : DEFAULT_EVAL;
1970 const TX_SIZE_SEARCH_METHOD tx_search_type =
1971 cpi->winner_mode_params.tx_size_search_methods[eval_type];
1972 assert(oxcf->txfm_cfg.enable_tx64 || tx_search_type != USE_LARGESTALL);
1973 features->tx_mode = select_tx_mode(cm, tx_search_type);
1974
1975 // Retain the frame level probability update conditions for parallel frames.
1976 // These conditions will be consumed during postencode stage to update the
1977 // probability.
1978 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
1979 cpi->do_update_frame_probs_txtype[cpi->num_frame_recode] =
1980 cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats;
1981 cpi->do_update_frame_probs_obmc[cpi->num_frame_recode] =
1982 (cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
1983 cpi->sf.inter_sf.prune_obmc_prob_thresh < INT_MAX);
1984 cpi->do_update_frame_probs_warp[cpi->num_frame_recode] =
1985 (features->allow_warped_motion &&
1986 cpi->sf.inter_sf.prune_warped_prob_thresh > 0);
1987 cpi->do_update_frame_probs_interpfilter[cpi->num_frame_recode] =
1988 (cm->current_frame.frame_type != KEY_FRAME &&
1989 cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
1990 features->interp_filter == SWITCHABLE);
1991 }
1992
1993 if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats ||
1994 ((cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh !=
1995 INT_MAX) &&
1996 (cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh != 0))) {
1997 const FRAME_UPDATE_TYPE update_type =
1998 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
1999 for (i = 0; i < TX_SIZES_ALL; i++) {
2000 int sum = 0;
2001 int j;
2002 int left = MAX_TX_TYPE_PROB;
2003
2004 for (j = 0; j < TX_TYPES; j++)
2005 sum += cpi->td.rd_counts.tx_type_used[i][j];
2006
2007 for (j = TX_TYPES - 1; j >= 0; j--) {
2008 int update_txtype_frameprobs = 1;
2009 const int new_prob =
2010 sum ? MAX_TX_TYPE_PROB * cpi->td.rd_counts.tx_type_used[i][j] / sum
2011 : (j ? 0 : MAX_TX_TYPE_PROB);
2012 #if CONFIG_FPMT_TEST
2013 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2014 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
2015 0) {
2016 int prob =
2017 (temp_frame_probs_simulation->tx_type_probs[update_type][i][j] +
2018 new_prob) >>
2019 1;
2020 left -= prob;
2021 if (j == 0) prob += left;
2022 temp_frame_probs_simulation->tx_type_probs[update_type][i][j] =
2023 prob;
2024 // Copy temp_frame_probs_simulation to temp_frame_probs
2025 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2026 update_type_idx++) {
2027 temp_frame_probs->tx_type_probs[update_type_idx][i][j] =
2028 temp_frame_probs_simulation
2029 ->tx_type_probs[update_type_idx][i][j];
2030 }
2031 }
2032 update_txtype_frameprobs = 0;
2033 }
2034 #endif // CONFIG_FPMT_TEST
2035 // Track the frame probabilities of parallel encode frames to update
2036 // during postencode stage.
2037 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2038 update_txtype_frameprobs = 0;
2039 cpi->frame_new_probs[cpi->num_frame_recode]
2040 .tx_type_probs[update_type][i][j] = new_prob;
2041 }
2042 if (update_txtype_frameprobs) {
2043 int prob =
2044 (frame_probs->tx_type_probs[update_type][i][j] + new_prob) >> 1;
2045 left -= prob;
2046 if (j == 0) prob += left;
2047 frame_probs->tx_type_probs[update_type][i][j] = prob;
2048 }
2049 }
2050 }
2051 }
2052
2053 if (cm->seg.enabled) {
2054 cm->seg.temporal_update = 1;
2055 if (rdc->seg_tmp_pred_cost[0] < rdc->seg_tmp_pred_cost[1])
2056 cm->seg.temporal_update = 0;
2057 }
2058
2059 if (cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
2060 cpi->sf.inter_sf.prune_obmc_prob_thresh < INT_MAX) {
2061 const FRAME_UPDATE_TYPE update_type =
2062 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2063
2064 for (i = 0; i < BLOCK_SIZES_ALL; i++) {
2065 int sum = 0;
2066 int update_obmc_frameprobs = 1;
2067 for (int j = 0; j < 2; j++) sum += cpi->td.rd_counts.obmc_used[i][j];
2068
2069 const int new_prob =
2070 sum ? 128 * cpi->td.rd_counts.obmc_used[i][1] / sum : 0;
2071 #if CONFIG_FPMT_TEST
2072 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2073 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2074 temp_frame_probs_simulation->obmc_probs[update_type][i] =
2075 (temp_frame_probs_simulation->obmc_probs[update_type][i] +
2076 new_prob) >>
2077 1;
2078 // Copy temp_frame_probs_simulation to temp_frame_probs
2079 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2080 update_type_idx++) {
2081 temp_frame_probs->obmc_probs[update_type_idx][i] =
2082 temp_frame_probs_simulation->obmc_probs[update_type_idx][i];
2083 }
2084 }
2085 update_obmc_frameprobs = 0;
2086 }
2087 #endif // CONFIG_FPMT_TEST
2088 // Track the frame probabilities of parallel encode frames to update
2089 // during postencode stage.
2090 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2091 update_obmc_frameprobs = 0;
2092 cpi->frame_new_probs[cpi->num_frame_recode].obmc_probs[update_type][i] =
2093 new_prob;
2094 }
2095 if (update_obmc_frameprobs) {
2096 frame_probs->obmc_probs[update_type][i] =
2097 (frame_probs->obmc_probs[update_type][i] + new_prob) >> 1;
2098 }
2099 }
2100 }
2101
2102 if (features->allow_warped_motion &&
2103 cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
2104 const FRAME_UPDATE_TYPE update_type =
2105 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2106 int update_warp_frameprobs = 1;
2107 int sum = 0;
2108 for (i = 0; i < 2; i++) sum += cpi->td.rd_counts.warped_used[i];
2109 const int new_prob = sum ? 128 * cpi->td.rd_counts.warped_used[1] / sum : 0;
2110 #if CONFIG_FPMT_TEST
2111 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2112 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2113 temp_frame_probs_simulation->warped_probs[update_type] =
2114 (temp_frame_probs_simulation->warped_probs[update_type] +
2115 new_prob) >>
2116 1;
2117 // Copy temp_frame_probs_simulation to temp_frame_probs
2118 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2119 update_type_idx++) {
2120 temp_frame_probs->warped_probs[update_type_idx] =
2121 temp_frame_probs_simulation->warped_probs[update_type_idx];
2122 }
2123 }
2124 update_warp_frameprobs = 0;
2125 }
2126 #endif // CONFIG_FPMT_TEST
2127 // Track the frame probabilities of parallel encode frames to update
2128 // during postencode stage.
2129 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2130 update_warp_frameprobs = 0;
2131 cpi->frame_new_probs[cpi->num_frame_recode].warped_probs[update_type] =
2132 new_prob;
2133 }
2134 if (update_warp_frameprobs) {
2135 frame_probs->warped_probs[update_type] =
2136 (frame_probs->warped_probs[update_type] + new_prob) >> 1;
2137 }
2138 }
2139
2140 if (cm->current_frame.frame_type != KEY_FRAME &&
2141 cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
2142 features->interp_filter == SWITCHABLE) {
2143 const FRAME_UPDATE_TYPE update_type =
2144 get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2145
2146 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
2147 int sum = 0;
2148 int j;
2149 int left = 1536;
2150
2151 for (j = 0; j < SWITCHABLE_FILTERS; j++) {
2152 sum += cpi->td.counts->switchable_interp[i][j];
2153 }
2154
2155 for (j = SWITCHABLE_FILTERS - 1; j >= 0; j--) {
2156 int update_interpfilter_frameprobs = 1;
2157 const int new_prob =
2158 sum ? 1536 * cpi->td.counts->switchable_interp[i][j] / sum
2159 : (j ? 0 : 1536);
2160 #if CONFIG_FPMT_TEST
2161 if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2162 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
2163 0) {
2164 int prob = (temp_frame_probs_simulation
2165 ->switchable_interp_probs[update_type][i][j] +
2166 new_prob) >>
2167 1;
2168 left -= prob;
2169 if (j == 0) prob += left;
2170 temp_frame_probs_simulation
2171 ->switchable_interp_probs[update_type][i][j] = prob;
2172 // Copy temp_frame_probs_simulation to temp_frame_probs
2173 for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2174 update_type_idx++) {
2175 temp_frame_probs->switchable_interp_probs[update_type_idx][i][j] =
2176 temp_frame_probs_simulation
2177 ->switchable_interp_probs[update_type_idx][i][j];
2178 }
2179 }
2180 update_interpfilter_frameprobs = 0;
2181 }
2182 #endif // CONFIG_FPMT_TEST
2183 // Track the frame probabilities of parallel encode frames to update
2184 // during postencode stage.
2185 if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2186 update_interpfilter_frameprobs = 0;
2187 cpi->frame_new_probs[cpi->num_frame_recode]
2188 .switchable_interp_probs[update_type][i][j] = new_prob;
2189 }
2190 if (update_interpfilter_frameprobs) {
2191 int prob = (frame_probs->switchable_interp_probs[update_type][i][j] +
2192 new_prob) >>
2193 1;
2194 left -= prob;
2195 if (j == 0) prob += left;
2196 frame_probs->switchable_interp_probs[update_type][i][j] = prob;
2197 }
2198 }
2199 }
2200 }
2201 if (hash_table_created) {
2202 av1_hash_table_destroy(&intrabc_hash_info->intrabc_hash_table);
2203 }
2204 }
2205
2206 /*!\brief Setup reference frame buffers and encode a frame
2207 *
2208 * \ingroup high_level_algo
2209 * \callgraph
2210 * \callergraph
2211 *
2212 * \param[in] cpi Top-level encoder structure
2213 */
av1_encode_frame(AV1_COMP * cpi)2214 void av1_encode_frame(AV1_COMP *cpi) {
2215 AV1_COMMON *const cm = &cpi->common;
2216 CurrentFrame *const current_frame = &cm->current_frame;
2217 FeatureFlags *const features = &cm->features;
2218 const int num_planes = av1_num_planes(cm);
2219 RD_COUNTS *const rdc = &cpi->td.rd_counts;
2220 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2221 // Indicates whether or not to use a default reduced set for ext-tx
2222 // rather than the potential full set of 16 transforms
2223 features->reduced_tx_set_used = oxcf->txfm_cfg.reduced_tx_type_set;
2224
2225 // Make sure segment_id is no larger than last_active_segid.
2226 if (cm->seg.enabled && cm->seg.update_map) {
2227 const int mi_rows = cm->mi_params.mi_rows;
2228 const int mi_cols = cm->mi_params.mi_cols;
2229 const int last_active_segid = cm->seg.last_active_segid;
2230 uint8_t *map = cpi->enc_seg.map;
2231 for (int mi_row = 0; mi_row < mi_rows; ++mi_row) {
2232 for (int mi_col = 0; mi_col < mi_cols; ++mi_col) {
2233 map[mi_col] = AOMMIN(map[mi_col], last_active_segid);
2234 }
2235 map += mi_cols;
2236 }
2237 }
2238
2239 av1_setup_frame_buf_refs(cm);
2240 enforce_max_ref_frames(cpi, &cpi->ref_frame_flags,
2241 cm->cur_frame->ref_display_order_hint,
2242 cm->current_frame.display_order_hint);
2243 set_rel_frame_dist(&cpi->common, &cpi->ref_frame_dist_info,
2244 cpi->ref_frame_flags);
2245 av1_setup_frame_sign_bias(cm);
2246
2247 #if CONFIG_MISMATCH_DEBUG
2248 mismatch_reset_frame(num_planes);
2249 #else
2250 (void)num_planes;
2251 #endif
2252
2253 rdc->newmv_or_intra_blocks = 0;
2254
2255 if (cpi->sf.hl_sf.frame_parameter_update ||
2256 cpi->sf.rt_sf.use_comp_ref_nonrd) {
2257 if (frame_is_intra_only(cm))
2258 current_frame->reference_mode = SINGLE_REFERENCE;
2259 else
2260 current_frame->reference_mode = REFERENCE_MODE_SELECT;
2261
2262 features->interp_filter = SWITCHABLE;
2263 if (cm->tiles.large_scale) features->interp_filter = EIGHTTAP_REGULAR;
2264
2265 features->switchable_motion_mode = is_switchable_motion_mode_allowed(
2266 features->allow_warped_motion, oxcf->motion_mode_cfg.enable_obmc);
2267
2268 rdc->compound_ref_used_flag = 0;
2269 rdc->skip_mode_used_flag = 0;
2270
2271 encode_frame_internal(cpi);
2272
2273 if (current_frame->reference_mode == REFERENCE_MODE_SELECT) {
2274 // Use a flag that includes 4x4 blocks
2275 if (rdc->compound_ref_used_flag == 0) {
2276 current_frame->reference_mode = SINGLE_REFERENCE;
2277 #if CONFIG_ENTROPY_STATS
2278 av1_zero(cpi->td.counts->comp_inter);
2279 #endif // CONFIG_ENTROPY_STATS
2280 }
2281 }
2282 // Re-check on the skip mode status as reference mode may have been
2283 // changed.
2284 SkipModeInfo *const skip_mode_info = ¤t_frame->skip_mode_info;
2285 if (frame_is_intra_only(cm) ||
2286 current_frame->reference_mode == SINGLE_REFERENCE) {
2287 skip_mode_info->skip_mode_allowed = 0;
2288 skip_mode_info->skip_mode_flag = 0;
2289 }
2290 if (skip_mode_info->skip_mode_flag && rdc->skip_mode_used_flag == 0)
2291 skip_mode_info->skip_mode_flag = 0;
2292
2293 if (!cm->tiles.large_scale) {
2294 if (features->tx_mode == TX_MODE_SELECT &&
2295 cpi->td.mb.txfm_search_info.txb_split_count == 0)
2296 features->tx_mode = TX_MODE_LARGEST;
2297 }
2298 } else {
2299 // This is needed if real-time speed setting is changed on the fly
2300 // from one using compound prediction to one using single reference.
2301 if (current_frame->reference_mode == REFERENCE_MODE_SELECT)
2302 current_frame->reference_mode = SINGLE_REFERENCE;
2303 encode_frame_internal(cpi);
2304 }
2305 }
2306