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 #include "aom_ports/system_state.h"
27
28 #if CONFIG_MISMATCH_DEBUG
29 #include "aom_util/debug_util.h"
30 #endif // CONFIG_MISMATCH_DEBUG
31
32 #include "av1/common/cfl.h"
33 #include "av1/common/common.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/aq_complexity.h"
48 #include "av1/encoder/aq_cyclicrefresh.h"
49 #include "av1/encoder/aq_variance.h"
50 #include "av1/encoder/global_motion_facade.h"
51 #include "av1/encoder/encodeframe.h"
52 #include "av1/encoder/encodeframe_utils.h"
53 #include "av1/encoder/encodemb.h"
54 #include "av1/encoder/encodemv.h"
55 #include "av1/encoder/encodetxb.h"
56 #include "av1/encoder/ethread.h"
57 #include "av1/encoder/extend.h"
58 #include "av1/encoder/ml.h"
59 #include "av1/encoder/motion_search_facade.h"
60 #include "av1/encoder/partition_strategy.h"
61 #if !CONFIG_REALTIME_ONLY
62 #include "av1/encoder/partition_model_weights.h"
63 #endif
64 #include "av1/encoder/partition_search.h"
65 #include "av1/encoder/rd.h"
66 #include "av1/encoder/rdopt.h"
67 #include "av1/encoder/reconinter_enc.h"
68 #include "av1/encoder/segmentation.h"
69 #include "av1/encoder/tokenize.h"
70 #include "av1/encoder/tpl_model.h"
71 #include "av1/encoder/var_based_part.h"
72
73 #if CONFIG_TUNE_VMAF
74 #include "av1/encoder/tune_vmaf.h"
75 #endif
76
77 /*!\cond */
78 // This is used as a reference when computing the source variance for the
79 // purposes of activity masking.
80 // Eventually this should be replaced by custom no-reference routines,
81 // which will be faster.
82 const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
83 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
84 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
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
92 };
93
94 static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
95 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
96 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
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
104 };
105
106 static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
107 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
108 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
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 };
124
125 static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
126 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
127 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
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
145 };
146 /*!\endcond */
147
av1_get_sby_perpixel_variance(const AV1_COMP * cpi,const struct buf_2d * ref,BLOCK_SIZE bs)148 unsigned int av1_get_sby_perpixel_variance(const AV1_COMP *cpi,
149 const struct buf_2d *ref,
150 BLOCK_SIZE bs) {
151 unsigned int sse;
152 const unsigned int var =
153 cpi->fn_ptr[bs].vf(ref->buf, ref->stride, AV1_VAR_OFFS, 0, &sse);
154 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
155 }
156
av1_high_get_sby_perpixel_variance(const AV1_COMP * cpi,const struct buf_2d * ref,BLOCK_SIZE bs,int bd)157 unsigned int av1_high_get_sby_perpixel_variance(const AV1_COMP *cpi,
158 const struct buf_2d *ref,
159 BLOCK_SIZE bs, int bd) {
160 unsigned int var, sse;
161 assert(bd == 8 || bd == 10 || bd == 12);
162 const int off_index = (bd - 8) >> 1;
163 const uint16_t *high_var_offs[3] = { AV1_HIGH_VAR_OFFS_8,
164 AV1_HIGH_VAR_OFFS_10,
165 AV1_HIGH_VAR_OFFS_12 };
166 var =
167 cpi->fn_ptr[bs].vf(ref->buf, ref->stride,
168 CONVERT_TO_BYTEPTR(high_var_offs[off_index]), 0, &sse);
169 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
170 }
171
get_sby_perpixel_diff_variance(const AV1_COMP * const cpi,const struct buf_2d * ref,int mi_row,int mi_col,BLOCK_SIZE bs)172 static unsigned int get_sby_perpixel_diff_variance(const AV1_COMP *const cpi,
173 const struct buf_2d *ref,
174 int mi_row, int mi_col,
175 BLOCK_SIZE bs) {
176 unsigned int sse, var;
177 uint8_t *last_y;
178 const YV12_BUFFER_CONFIG *last =
179 get_ref_frame_yv12_buf(&cpi->common, LAST_FRAME);
180
181 assert(last != NULL);
182 last_y =
183 &last->y_buffer[mi_row * MI_SIZE * last->y_stride + mi_col * MI_SIZE];
184 var = cpi->fn_ptr[bs].vf(ref->buf, ref->stride, last_y, last->y_stride, &sse);
185 return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[bs]);
186 }
187
get_rd_var_based_fixed_partition(AV1_COMP * cpi,MACROBLOCK * x,int mi_row,int mi_col)188 static BLOCK_SIZE get_rd_var_based_fixed_partition(AV1_COMP *cpi, MACROBLOCK *x,
189 int mi_row, int mi_col) {
190 unsigned int var = get_sby_perpixel_diff_variance(
191 cpi, &x->plane[0].src, mi_row, mi_col, BLOCK_64X64);
192 if (var < 8)
193 return BLOCK_64X64;
194 else if (var < 128)
195 return BLOCK_32X32;
196 else if (var < 2048)
197 return BLOCK_16X16;
198 else
199 return BLOCK_8X8;
200 }
201
av1_setup_src_planes(MACROBLOCK * x,const YV12_BUFFER_CONFIG * src,int mi_row,int mi_col,const int num_planes,BLOCK_SIZE bsize)202 void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
203 int mi_row, int mi_col, const int num_planes,
204 BLOCK_SIZE bsize) {
205 // Set current frame pointer.
206 x->e_mbd.cur_buf = src;
207
208 // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
209 // the static analysis warnings.
210 for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); i++) {
211 const int is_uv = i > 0;
212 setup_pred_plane(
213 &x->plane[i].src, bsize, src->buffers[i], src->crop_widths[is_uv],
214 src->crop_heights[is_uv], src->strides[is_uv], mi_row, mi_col, NULL,
215 x->e_mbd.plane[i].subsampling_x, x->e_mbd.plane[i].subsampling_y);
216 }
217 }
218
219 #if !CONFIG_REALTIME_ONLY
220 /*!\brief Assigns different quantization parameters to each super
221 * block based on its TPL weight.
222 *
223 * \ingroup tpl_modelling
224 *
225 * \param[in] cpi Top level encoder instance structure
226 * \param[in,out] td Thread data structure
227 * \param[in,out] x Macro block level data for this block.
228 * \param[in] tile_info Tile infromation / identification
229 * \param[in] mi_row Block row (in "MI_SIZE" units) index
230 * \param[in] mi_col Block column (in "MI_SIZE" units) index
231 * \param[out] num_planes Number of image planes (e.g. Y,U,V)
232 *
233 * \return No return value but updates macroblock and thread data
234 * related to the q / q delta to be used.
235 */
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)236 static AOM_INLINE void setup_delta_q(AV1_COMP *const cpi, ThreadData *td,
237 MACROBLOCK *const x,
238 const TileInfo *const tile_info,
239 int mi_row, int mi_col, int num_planes) {
240 AV1_COMMON *const cm = &cpi->common;
241 const CommonModeInfoParams *const mi_params = &cm->mi_params;
242 const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
243 assert(delta_q_info->delta_q_present_flag);
244
245 const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
246 // Delta-q modulation based on variance
247 av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
248
249 int current_qindex = cm->quant_params.base_qindex;
250 if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL) {
251 if (DELTA_Q_PERCEPTUAL_MODULATION == 1) {
252 const int block_wavelet_energy_level =
253 av1_block_wavelet_energy_level(cpi, x, sb_size);
254 x->sb_energy_level = block_wavelet_energy_level;
255 current_qindex = av1_compute_q_from_energy_level_deltaq_mode(
256 cpi, block_wavelet_energy_level);
257 } else {
258 const int block_var_level = av1_log_block_var(cpi, x, sb_size);
259 x->sb_energy_level = block_var_level;
260 current_qindex =
261 av1_compute_q_from_energy_level_deltaq_mode(cpi, block_var_level);
262 }
263 } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
264 cpi->oxcf.algo_cfg.enable_tpl_model) {
265 // Setup deltaq based on tpl stats
266 current_qindex =
267 av1_get_q_for_deltaq_objective(cpi, sb_size, mi_row, mi_col);
268 }
269
270 const int delta_q_res = delta_q_info->delta_q_res;
271 // Right now deltaq only works with tpl model. So if tpl is disabled, we set
272 // the current_qindex to base_qindex.
273 if (cpi->oxcf.algo_cfg.enable_tpl_model &&
274 cpi->oxcf.q_cfg.deltaq_mode != NO_DELTA_Q) {
275 current_qindex =
276 clamp(current_qindex, delta_q_res, 256 - delta_q_info->delta_q_res);
277 } else {
278 current_qindex = cm->quant_params.base_qindex;
279 }
280
281 MACROBLOCKD *const xd = &x->e_mbd;
282 const int sign_deltaq_index =
283 current_qindex - xd->current_base_qindex >= 0 ? 1 : -1;
284 const int deltaq_deadzone = delta_q_res / 4;
285 const int qmask = ~(delta_q_res - 1);
286 int abs_deltaq_index = abs(current_qindex - xd->current_base_qindex);
287 abs_deltaq_index = (abs_deltaq_index + deltaq_deadzone) & qmask;
288 current_qindex =
289 xd->current_base_qindex + sign_deltaq_index * abs_deltaq_index;
290 current_qindex = AOMMAX(current_qindex, MINQ + 1);
291 assert(current_qindex > 0);
292
293 x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
294 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
295 xd->mi[0]->current_qindex = current_qindex;
296 av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id);
297
298 // keep track of any non-zero delta-q used
299 td->deltaq_used |= (x->delta_qindex != 0);
300
301 if (cpi->oxcf.tool_cfg.enable_deltalf_mode) {
302 const int delta_lf_res = delta_q_info->delta_lf_res;
303 const int lfmask = ~(delta_lf_res - 1);
304 const int delta_lf_from_base =
305 ((x->delta_qindex / 2 + delta_lf_res / 2) & lfmask);
306 const int8_t delta_lf =
307 (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
308 const int frame_lf_count =
309 av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
310 const int mib_size = cm->seq_params.mib_size;
311
312 // pre-set the delta lf for loop filter. Note that this value is set
313 // before mi is assigned for each block in current superblock
314 for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row); j++) {
315 for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col); k++) {
316 const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
317 mi_params->mi_grid_base[grid_idx]->delta_lf_from_base = delta_lf;
318 for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
319 mi_params->mi_grid_base[grid_idx]->delta_lf[lf_id] = delta_lf;
320 }
321 }
322 }
323 }
324 }
325
init_ref_frame_space(AV1_COMP * cpi,ThreadData * td,int mi_row,int mi_col)326 static void init_ref_frame_space(AV1_COMP *cpi, ThreadData *td, int mi_row,
327 int mi_col) {
328 const AV1_COMMON *cm = &cpi->common;
329 const GF_GROUP *const gf_group = &cpi->gf_group;
330 const CommonModeInfoParams *const mi_params = &cm->mi_params;
331 MACROBLOCK *x = &td->mb;
332 const int frame_idx = cpi->gf_group.index;
333 TplParams *const tpl_data = &cpi->tpl_data;
334 TplDepFrame *tpl_frame = &tpl_data->tpl_frame[frame_idx];
335 const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
336
337 av1_zero(x->tpl_keep_ref_frame);
338
339 if (tpl_frame->is_valid == 0) return;
340 if (!is_frame_tpl_eligible(gf_group, gf_group->index)) return;
341 if (frame_idx >= MAX_TPL_FRAME_IDX) return;
342 if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return;
343
344 const int is_overlay = cpi->gf_group.update_type[frame_idx] == OVERLAY_UPDATE;
345 if (is_overlay) {
346 memset(x->tpl_keep_ref_frame, 1, sizeof(x->tpl_keep_ref_frame));
347 return;
348 }
349
350 TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
351 const int tpl_stride = tpl_frame->stride;
352 int64_t inter_cost[INTER_REFS_PER_FRAME] = { 0 };
353 const int step = 1 << block_mis_log2;
354 const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
355
356 const int mi_row_end =
357 AOMMIN(mi_size_high[sb_size] + mi_row, mi_params->mi_rows);
358 const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
359 const int mi_col_sr =
360 coded_to_superres_mi(mi_col, cm->superres_scale_denominator);
361 const int mi_col_end_sr =
362 AOMMIN(coded_to_superres_mi(mi_col + mi_size_wide[sb_size],
363 cm->superres_scale_denominator),
364 mi_cols_sr);
365 const int row_step = step;
366 const int col_step_sr =
367 coded_to_superres_mi(step, cm->superres_scale_denominator);
368 for (int row = mi_row; row < mi_row_end; row += row_step) {
369 for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
370 const TplDepStats *this_stats =
371 &tpl_stats[av1_tpl_ptr_pos(row, col, tpl_stride, block_mis_log2)];
372 int64_t tpl_pred_error[INTER_REFS_PER_FRAME] = { 0 };
373 // Find the winner ref frame idx for the current block
374 int64_t best_inter_cost = this_stats->pred_error[0];
375 int best_rf_idx = 0;
376 for (int idx = 1; idx < INTER_REFS_PER_FRAME; ++idx) {
377 if ((this_stats->pred_error[idx] < best_inter_cost) &&
378 (this_stats->pred_error[idx] != 0)) {
379 best_inter_cost = this_stats->pred_error[idx];
380 best_rf_idx = idx;
381 }
382 }
383 // tpl_pred_error is the pred_error reduction of best_ref w.r.t.
384 // LAST_FRAME.
385 tpl_pred_error[best_rf_idx] = this_stats->pred_error[best_rf_idx] -
386 this_stats->pred_error[LAST_FRAME - 1];
387
388 for (int rf_idx = 1; rf_idx < INTER_REFS_PER_FRAME; ++rf_idx)
389 inter_cost[rf_idx] += tpl_pred_error[rf_idx];
390 }
391 }
392
393 int rank_index[INTER_REFS_PER_FRAME - 1];
394 for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
395 rank_index[idx] = idx + 1;
396 for (int i = idx; i > 0; --i) {
397 if (inter_cost[rank_index[i - 1]] > inter_cost[rank_index[i]]) {
398 const int tmp = rank_index[i - 1];
399 rank_index[i - 1] = rank_index[i];
400 rank_index[i] = tmp;
401 }
402 }
403 }
404
405 x->tpl_keep_ref_frame[INTRA_FRAME] = 1;
406 x->tpl_keep_ref_frame[LAST_FRAME] = 1;
407
408 int cutoff_ref = 0;
409 for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
410 x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 1;
411 if (idx > 2) {
412 if (!cutoff_ref) {
413 // If the predictive coding gains are smaller than the previous more
414 // relevant frame over certain amount, discard this frame and all the
415 // frames afterwards.
416 if (llabs(inter_cost[rank_index[idx]]) <
417 llabs(inter_cost[rank_index[idx - 1]]) / 8 ||
418 inter_cost[rank_index[idx]] == 0)
419 cutoff_ref = 1;
420 }
421
422 if (cutoff_ref) x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 0;
423 }
424 }
425 }
426
adjust_rdmult_tpl_model(AV1_COMP * cpi,MACROBLOCK * x,int mi_row,int mi_col)427 static AOM_INLINE void adjust_rdmult_tpl_model(AV1_COMP *cpi, MACROBLOCK *x,
428 int mi_row, int mi_col) {
429 const BLOCK_SIZE sb_size = cpi->common.seq_params.sb_size;
430 const int orig_rdmult = cpi->rd.RDMULT;
431
432 assert(IMPLIES(cpi->gf_group.size > 0,
433 cpi->gf_group.index < cpi->gf_group.size));
434 const int gf_group_index = cpi->gf_group.index;
435 if (cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
436 cpi->oxcf.q_cfg.deltaq_mode == NO_DELTA_Q && gf_group_index > 0 &&
437 cpi->gf_group.update_type[gf_group_index] == ARF_UPDATE) {
438 const int dr =
439 av1_get_rdmult_delta(cpi, sb_size, mi_row, mi_col, orig_rdmult);
440 x->rdmult = dr;
441 }
442 }
443 #endif // !CONFIG_REALTIME_ONLY
444
445 // 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)446 static void get_estimated_pred(AV1_COMP *cpi, const TileInfo *const tile,
447 MACROBLOCK *x, int mi_row, int mi_col) {
448 AV1_COMMON *const cm = &cpi->common;
449 const int is_key_frame = frame_is_intra_only(cm);
450 MACROBLOCKD *xd = &x->e_mbd;
451
452 // TODO(kyslov) Extend to 128x128
453 assert(cm->seq_params.sb_size == BLOCK_64X64);
454
455 av1_set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
456
457 if (!is_key_frame) {
458 MB_MODE_INFO *mi = xd->mi[0];
459 const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, LAST_FRAME);
460
461 assert(yv12 != NULL);
462
463 av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
464 get_ref_scale_factors(cm, LAST_FRAME), 1);
465 mi->ref_frame[0] = LAST_FRAME;
466 mi->ref_frame[1] = NONE;
467 mi->bsize = BLOCK_64X64;
468 mi->mv[0].as_int = 0;
469 mi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
470
471 set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]);
472
473 xd->plane[0].dst.buf = x->est_pred;
474 xd->plane[0].dst.stride = 64;
475 av1_enc_build_inter_predictor_y(xd, mi_row, mi_col);
476 } else {
477 #if CONFIG_AV1_HIGHBITDEPTH
478 switch (xd->bd) {
479 case 8: memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0])); break;
480 case 10:
481 memset(x->est_pred, 128 * 4, 64 * 64 * sizeof(x->est_pred[0]));
482 break;
483 case 12:
484 memset(x->est_pred, 128 * 16, 64 * 64 * sizeof(x->est_pred[0]));
485 break;
486 }
487 #else
488 memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0]));
489 #endif // CONFIG_VP9_HIGHBITDEPTH
490 }
491 }
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
515 // Grade the temporal variation of the sb, the grade will be used to decide
516 // fast mode search strategy for coding blocks
517 if (sf->rt_sf.source_metrics_sb_nonrd &&
518 cpi->svc.number_spatial_layers <= 1 &&
519 cm->current_frame.frame_type != KEY_FRAME) {
520 int offset = cpi->source->y_stride * (mi_row << 2) + (mi_col << 2);
521 av1_source_content_sb(cpi, x, offset);
522 }
523
524 if (sf->part_sf.partition_search_type == ML_BASED_PARTITION) {
525 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
526 RD_STATS dummy_rdc;
527 get_estimated_pred(cpi, tile_info, x, mi_row, mi_col);
528 av1_nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col,
529 BLOCK_64X64, &dummy_rdc, 1, INT64_MAX, pc_root);
530 av1_free_pc_tree_recursive(pc_root, av1_num_planes(cm), 0, 0);
531 return;
532 }
533
534 // Set the partition
535 if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip) {
536 // set a fixed-size partition
537 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
538 const BLOCK_SIZE bsize =
539 seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
540 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
541 } else if (cpi->partition_search_skippable_frame) {
542 // set a fixed-size partition for which the size is determined by the source
543 // variance
544 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
545 const BLOCK_SIZE bsize =
546 get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
547 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
548 } else if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
549 // set a variance-based partition
550 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
551 av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
552 }
553 assert(sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip ||
554 cpi->partition_search_skippable_frame ||
555 sf->part_sf.partition_search_type == VAR_BASED_PARTITION);
556 set_cb_offsets(td->mb.cb_offset, 0, 0);
557
558 // Adjust and encode the superblock
559 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
560 av1_nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
561 pc_root);
562 av1_free_pc_tree_recursive(pc_root, av1_num_planes(cm), 0, 0);
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 init_simple_motion_search_mvs(sms_root);
584 }
585
586 #if !CONFIG_REALTIME_ONLY
587 if (has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
588 cpi->oxcf.gf_cfg.lag_in_frames == 0) {
589 (void)tile_info;
590 (void)mi_row;
591 (void)mi_col;
592 (void)gather_tpl_data;
593 } else {
594 init_ref_frame_space(cpi, td, mi_row, mi_col);
595 x->sb_energy_level = 0;
596 x->part_search_info.cnn_output_valid = 0;
597 if (gather_tpl_data) {
598 if (cm->delta_q_info.delta_q_present_flag) {
599 const int num_planes = av1_num_planes(cm);
600 const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
601 setup_delta_q(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
602 av1_tpl_rdmult_setup_sb(cpi, x, sb_size, mi_row, mi_col);
603 }
604 if (cpi->oxcf.algo_cfg.enable_tpl_model) {
605 adjust_rdmult_tpl_model(cpi, x, mi_row, mi_col);
606 }
607 }
608 }
609 #else
610 (void)tile_info;
611 (void)mi_row;
612 (void)mi_col;
613 (void)gather_tpl_data;
614 #endif
615
616 // Reset hash state for transform/mode rd hash information
617 reset_hash_records(&x->txfm_search_info, cpi->sf.tx_sf.use_inter_txb_hash);
618 av1_zero(x->picked_ref_frames_mask);
619 av1_invalid_rd_stats(rd_cost);
620 }
621
622 /*!\brief Encode a superblock (RD-search-based)
623 *
624 * \ingroup partition_search
625 * Conducts partition search for a superblock, based on rate-distortion costs,
626 * from scratch or adjusting from a pre-calculated partition pattern.
627 */
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)628 static AOM_INLINE void encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
629 TileDataEnc *tile_data, TokenExtra **tp,
630 const int mi_row, const int mi_col,
631 const int seg_skip) {
632 AV1_COMMON *const cm = &cpi->common;
633 MACROBLOCK *const x = &td->mb;
634 const SPEED_FEATURES *const sf = &cpi->sf;
635 const TileInfo *const tile_info = &tile_data->tile_info;
636 MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
637 get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
638 const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
639 const int num_planes = av1_num_planes(cm);
640 int dummy_rate;
641 int64_t dummy_dist;
642 RD_STATS dummy_rdc;
643 SIMPLE_MOTION_DATA_TREE *const sms_root = td->sms_root;
644
645 #if CONFIG_REALTIME_ONLY
646 (void)seg_skip;
647 #endif // CONFIG_REALTIME_ONLY
648
649 init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row, mi_col,
650 1);
651
652 // Encode the superblock
653 if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
654 // partition search starting from a variance-based partition
655 av1_set_offsets_without_segment_id(cpi, tile_info, x, mi_row, mi_col,
656 sb_size);
657 av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
658 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
659 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
660 &dummy_rate, &dummy_dist, 1, pc_root);
661 av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0);
662 }
663 #if !CONFIG_REALTIME_ONLY
664 else if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip) {
665 // partition search by adjusting a fixed-size partition
666 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
667 const BLOCK_SIZE bsize =
668 seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
669 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
670 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
671 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
672 &dummy_rate, &dummy_dist, 1, pc_root);
673 av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0);
674 } else if (cpi->partition_search_skippable_frame) {
675 // partition search by adjusting a fixed-size partition for which the size
676 // is determined by the source variance
677 av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
678 const BLOCK_SIZE bsize =
679 get_rd_var_based_fixed_partition(cpi, x, mi_row, mi_col);
680 av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
681 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
682 av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
683 &dummy_rate, &dummy_dist, 1, pc_root);
684 av1_free_pc_tree_recursive(pc_root, num_planes, 0, 0);
685 } else {
686 // The most exhaustive recursive partition search
687 SuperBlockEnc *sb_enc = &x->sb_enc;
688 // No stats for overlay frames. Exclude key frame.
689 av1_get_tpl_stats_sb(cpi, sb_size, mi_row, mi_col, sb_enc);
690
691 // Reset the tree for simple motion search data
692 av1_reset_simple_motion_tree_partition(sms_root, sb_size);
693
694 #if CONFIG_COLLECT_COMPONENT_TIMING
695 start_timing(cpi, rd_pick_partition_time);
696 #endif
697
698 // Estimate the maximum square partition block size, which will be used
699 // as the starting block size for partitioning the sb
700 set_max_min_partition_size(sb_enc, cpi, x, sf, sb_size, mi_row, mi_col);
701
702 // The superblock can be searched only once, or twice consecutively for
703 // better quality. Note that the meaning of passes here is different from
704 // the general concept of 1-pass/2-pass encoders.
705 const int num_passes =
706 cpi->oxcf.unit_test_cfg.sb_multipass_unit_test ? 2 : 1;
707
708 if (num_passes == 1) {
709 PC_TREE *const pc_root = av1_alloc_pc_tree_node(sb_size);
710 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
711 &dummy_rdc, dummy_rdc, pc_root, sms_root, NULL,
712 SB_SINGLE_PASS, NULL);
713 } else {
714 // First pass
715 SB_FIRST_PASS_STATS sb_fp_stats;
716 av1_backup_sb_state(&sb_fp_stats, cpi, td, tile_data, mi_row, mi_col);
717 PC_TREE *const pc_root_p0 = av1_alloc_pc_tree_node(sb_size);
718 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
719 &dummy_rdc, dummy_rdc, pc_root_p0, sms_root, NULL,
720 SB_DRY_PASS, NULL);
721
722 // Second pass
723 init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row,
724 mi_col, 0);
725 av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
726 av1_reset_simple_motion_tree_partition(sms_root, sb_size);
727
728 av1_restore_sb_state(&sb_fp_stats, cpi, td, tile_data, mi_row, mi_col);
729
730 PC_TREE *const pc_root_p1 = av1_alloc_pc_tree_node(sb_size);
731 av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
732 &dummy_rdc, dummy_rdc, pc_root_p1, sms_root, NULL,
733 SB_WET_PASS, NULL);
734 }
735 // Reset to 0 so that it wouldn't be used elsewhere mistakenly.
736 sb_enc->tpl_data_count = 0;
737 #if CONFIG_COLLECT_COMPONENT_TIMING
738 end_timing(cpi, rd_pick_partition_time);
739 #endif
740 }
741 #endif // !CONFIG_REALTIME_ONLY
742
743 // Update the inter rd model
744 // TODO(angiebird): Let inter_mode_rd_model_estimation support multi-tile.
745 if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1 &&
746 cm->tiles.cols == 1 && cm->tiles.rows == 1) {
747 av1_inter_mode_data_fit(tile_data, x->rdmult);
748 }
749 }
750
751 /*!\brief Encode a superblock row by breaking it into superblocks
752 *
753 * \ingroup partition_search
754 * \callgraph
755 * \callergraph
756 * Do partition and mode search for an sb row: one row of superblocks filling up
757 * the width of the current tile.
758 */
encode_sb_row(AV1_COMP * cpi,ThreadData * td,TileDataEnc * tile_data,int mi_row,TokenExtra ** tp)759 static AOM_INLINE void encode_sb_row(AV1_COMP *cpi, ThreadData *td,
760 TileDataEnc *tile_data, int mi_row,
761 TokenExtra **tp) {
762 AV1_COMMON *const cm = &cpi->common;
763 const TileInfo *const tile_info = &tile_data->tile_info;
764 MultiThreadInfo *const mt_info = &cpi->mt_info;
765 AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
766 AV1EncRowMultiThreadSync *const row_mt_sync = &tile_data->row_mt_sync;
767 bool row_mt_enabled = mt_info->row_mt_enabled;
768 MACROBLOCK *const x = &td->mb;
769 MACROBLOCKD *const xd = &x->e_mbd;
770 const int sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_data->tile_info);
771 const BLOCK_SIZE sb_size = cm->seq_params.sb_size;
772 const int mib_size = cm->seq_params.mib_size;
773 const int mib_size_log2 = cm->seq_params.mib_size_log2;
774 const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2;
775 const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
776
777 #if CONFIG_COLLECT_COMPONENT_TIMING
778 start_timing(cpi, encode_sb_time);
779 #endif
780
781 // Initialize the left context for the new SB row
782 av1_zero_left_context(xd);
783
784 // Reset delta for quantizer and loof filters at the beginning of every tile
785 if (mi_row == tile_info->mi_row_start || row_mt_enabled) {
786 if (cm->delta_q_info.delta_q_present_flag)
787 xd->current_base_qindex = cm->quant_params.base_qindex;
788 if (cm->delta_q_info.delta_lf_present_flag) {
789 av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
790 }
791 }
792
793 reset_thresh_freq_fact(x);
794
795 // Code each SB in the row
796 for (int mi_col = tile_info->mi_col_start, sb_col_in_tile = 0;
797 mi_col < tile_info->mi_col_end; mi_col += mib_size, sb_col_in_tile++) {
798 (*(enc_row_mt->sync_read_ptr))(row_mt_sync, sb_row, sb_col_in_tile);
799
800 if (tile_data->allow_update_cdf && row_mt_enabled &&
801 (tile_info->mi_row_start != mi_row)) {
802 if ((tile_info->mi_col_start == mi_col)) {
803 // restore frame context at the 1st column sb
804 memcpy(xd->tile_ctx, x->row_ctx, sizeof(*xd->tile_ctx));
805 } else {
806 // update context
807 int wt_left = AVG_CDF_WEIGHT_LEFT;
808 int wt_tr = AVG_CDF_WEIGHT_TOP_RIGHT;
809 if (tile_info->mi_col_end > (mi_col + mib_size))
810 av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile,
811 wt_left, wt_tr);
812 else
813 av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile - 1,
814 wt_left, wt_tr);
815 }
816 }
817
818 // Update the rate cost tables for some symbols
819 av1_set_cost_upd_freq(cpi, td, tile_info, mi_row, mi_col);
820
821 // Reset color coding related parameters
822 x->color_sensitivity[0] = 0;
823 x->color_sensitivity[1] = 0;
824 x->content_state_sb = 0;
825
826 xd->cur_frame_force_integer_mv = cm->features.cur_frame_force_integer_mv;
827 x->source_variance = UINT_MAX;
828 td->mb.cb_coef_buff = av1_get_cb_coeff_buffer(cpi, mi_row, mi_col);
829
830 // Get segment id and skip flag
831 const struct segmentation *const seg = &cm->seg;
832 int seg_skip = 0;
833 if (seg->enabled) {
834 const uint8_t *const map =
835 seg->update_map ? cpi->enc_seg.map : cm->last_frame_seg_map;
836 const int segment_id =
837 map ? get_segment_id(&cm->mi_params, map, sb_size, mi_row, mi_col)
838 : 0;
839 seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
840 }
841
842 // encode the superblock
843 if (use_nonrd_mode) {
844 encode_nonrd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
845 } else {
846 encode_rd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
847 }
848
849 // Update the top-right context in row_mt coding
850 if (tile_data->allow_update_cdf && row_mt_enabled &&
851 (tile_info->mi_row_end > (mi_row + mib_size))) {
852 if (sb_cols_in_tile == 1)
853 memcpy(x->row_ctx, xd->tile_ctx, sizeof(*xd->tile_ctx));
854 else if (sb_col_in_tile >= 1)
855 memcpy(x->row_ctx + sb_col_in_tile - 1, xd->tile_ctx,
856 sizeof(*xd->tile_ctx));
857 }
858 (*(enc_row_mt->sync_write_ptr))(row_mt_sync, sb_row, sb_col_in_tile,
859 sb_cols_in_tile);
860 }
861 #if CONFIG_COLLECT_COMPONENT_TIMING
862 end_timing(cpi, encode_sb_time);
863 #endif
864 }
865
init_encode_frame_mb_context(AV1_COMP * cpi)866 static AOM_INLINE void init_encode_frame_mb_context(AV1_COMP *cpi) {
867 AV1_COMMON *const cm = &cpi->common;
868 const int num_planes = av1_num_planes(cm);
869 MACROBLOCK *const x = &cpi->td.mb;
870 MACROBLOCKD *const xd = &x->e_mbd;
871
872 // Copy data over into macro block data structures.
873 av1_setup_src_planes(x, cpi->source, 0, 0, num_planes,
874 cm->seq_params.sb_size);
875
876 av1_setup_block_planes(xd, cm->seq_params.subsampling_x,
877 cm->seq_params.subsampling_y, num_planes);
878 }
879
av1_alloc_tile_data(AV1_COMP * cpi)880 void av1_alloc_tile_data(AV1_COMP *cpi) {
881 AV1_COMMON *const cm = &cpi->common;
882 const int tile_cols = cm->tiles.cols;
883 const int tile_rows = cm->tiles.rows;
884
885 if (cpi->tile_data != NULL) aom_free(cpi->tile_data);
886 CHECK_MEM_ERROR(
887 cm, cpi->tile_data,
888 aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->tile_data)));
889
890 cpi->allocated_tiles = tile_cols * tile_rows;
891 }
892
av1_init_tile_data(AV1_COMP * cpi)893 void av1_init_tile_data(AV1_COMP *cpi) {
894 AV1_COMMON *const cm = &cpi->common;
895 const int num_planes = av1_num_planes(cm);
896 const int tile_cols = cm->tiles.cols;
897 const int tile_rows = cm->tiles.rows;
898 int tile_col, tile_row;
899 TokenInfo *const token_info = &cpi->token_info;
900 TokenExtra *pre_tok = token_info->tile_tok[0][0];
901 TokenList *tplist = token_info->tplist[0][0];
902 unsigned int tile_tok = 0;
903 int tplist_count = 0;
904
905 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
906 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
907 TileDataEnc *const tile_data =
908 &cpi->tile_data[tile_row * tile_cols + tile_col];
909 TileInfo *const tile_info = &tile_data->tile_info;
910 av1_tile_init(tile_info, cm, tile_row, tile_col);
911 tile_data->firstpass_top_mv = kZeroMv;
912
913 if (pre_tok != NULL && tplist != NULL) {
914 token_info->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
915 pre_tok = token_info->tile_tok[tile_row][tile_col];
916 tile_tok = allocated_tokens(*tile_info,
917 cm->seq_params.mib_size_log2 + MI_SIZE_LOG2,
918 num_planes);
919 token_info->tplist[tile_row][tile_col] = tplist + tplist_count;
920 tplist = token_info->tplist[tile_row][tile_col];
921 tplist_count = av1_get_sb_rows_in_tile(cm, tile_data->tile_info);
922 }
923 tile_data->allow_update_cdf = !cm->tiles.large_scale;
924 tile_data->allow_update_cdf =
925 tile_data->allow_update_cdf && !cm->features.disable_cdf_update;
926 tile_data->tctx = *cm->fc;
927 }
928 }
929 }
930
931 /*!\brief Encode a superblock row
932 *
933 * \ingroup partition_search
934 */
av1_encode_sb_row(AV1_COMP * cpi,ThreadData * td,int tile_row,int tile_col,int mi_row)935 void av1_encode_sb_row(AV1_COMP *cpi, ThreadData *td, int tile_row,
936 int tile_col, int mi_row) {
937 AV1_COMMON *const cm = &cpi->common;
938 const int num_planes = av1_num_planes(cm);
939 const int tile_cols = cm->tiles.cols;
940 TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col];
941 const TileInfo *const tile_info = &this_tile->tile_info;
942 TokenExtra *tok = NULL;
943 TokenList *const tplist = cpi->token_info.tplist[tile_row][tile_col];
944 const int sb_row_in_tile =
945 (mi_row - tile_info->mi_row_start) >> cm->seq_params.mib_size_log2;
946 const int tile_mb_cols =
947 (tile_info->mi_col_end - tile_info->mi_col_start + 2) >> 2;
948 const int num_mb_rows_in_sb =
949 ((1 << (cm->seq_params.mib_size_log2 + MI_SIZE_LOG2)) + 8) >> 4;
950
951 get_start_tok(cpi, tile_row, tile_col, mi_row, &tok,
952 cm->seq_params.mib_size_log2 + MI_SIZE_LOG2, num_planes);
953 tplist[sb_row_in_tile].start = tok;
954
955 encode_sb_row(cpi, td, this_tile, mi_row, &tok);
956
957 tplist[sb_row_in_tile].count =
958 (unsigned int)(tok - tplist[sb_row_in_tile].start);
959
960 assert((unsigned int)(tok - tplist[sb_row_in_tile].start) <=
961 get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
962 cm->seq_params.mib_size_log2 + MI_SIZE_LOG2,
963 num_planes));
964
965 (void)tile_mb_cols;
966 (void)num_mb_rows_in_sb;
967 }
968
969 /*!\brief Encode a tile
970 *
971 * \ingroup partition_search
972 */
av1_encode_tile(AV1_COMP * cpi,ThreadData * td,int tile_row,int tile_col)973 void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
974 int tile_col) {
975 AV1_COMMON *const cm = &cpi->common;
976 TileDataEnc *const this_tile =
977 &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
978 const TileInfo *const tile_info = &this_tile->tile_info;
979
980 if (!cpi->sf.rt_sf.use_nonrd_pick_mode) av1_inter_mode_data_init(this_tile);
981
982 av1_zero_above_context(cm, &td->mb.e_mbd, tile_info->mi_col_start,
983 tile_info->mi_col_end, tile_row);
984 av1_init_above_context(&cm->above_contexts, av1_num_planes(cm), tile_row,
985 &td->mb.e_mbd);
986
987 if (cpi->oxcf.intra_mode_cfg.enable_cfl_intra)
988 cfl_init(&td->mb.e_mbd.cfl, &cm->seq_params);
989
990 av1_crc32c_calculator_init(
991 &td->mb.txfm_search_info.mb_rd_record.crc_calculator);
992
993 for (int mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
994 mi_row += cm->seq_params.mib_size) {
995 av1_encode_sb_row(cpi, td, tile_row, tile_col, mi_row);
996 }
997 }
998
999 /*!\brief Break one frame into tiles and encode the tiles
1000 *
1001 * \ingroup partition_search
1002 *
1003 * \param[in] cpi Top-level encoder structure
1004 */
encode_tiles(AV1_COMP * cpi)1005 static AOM_INLINE void encode_tiles(AV1_COMP *cpi) {
1006 AV1_COMMON *const cm = &cpi->common;
1007 const int tile_cols = cm->tiles.cols;
1008 const int tile_rows = cm->tiles.rows;
1009 int tile_col, tile_row;
1010
1011 assert(IMPLIES(cpi->tile_data == NULL,
1012 cpi->allocated_tiles < tile_cols * tile_rows));
1013 if (cpi->allocated_tiles < tile_cols * tile_rows) av1_alloc_tile_data(cpi);
1014
1015 av1_init_tile_data(cpi);
1016
1017 for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
1018 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
1019 TileDataEnc *const this_tile =
1020 &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1021 cpi->td.intrabc_used = 0;
1022 cpi->td.deltaq_used = 0;
1023 cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx;
1024 cpi->td.mb.tile_pb_ctx = &this_tile->tctx;
1025 av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
1026 cpi->intrabc_used |= cpi->td.intrabc_used;
1027 cpi->deltaq_used |= cpi->td.deltaq_used;
1028 }
1029 }
1030 }
1031
1032 // 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)1033 static AOM_INLINE void set_rel_frame_dist(
1034 const AV1_COMMON *const cm, RefFrameDistanceInfo *const ref_frame_dist_info,
1035 const int ref_frame_flags) {
1036 MV_REFERENCE_FRAME ref_frame;
1037 int min_past_dist = INT32_MAX, min_future_dist = INT32_MAX;
1038 ref_frame_dist_info->nearest_past_ref = NONE_FRAME;
1039 ref_frame_dist_info->nearest_future_ref = NONE_FRAME;
1040 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
1041 ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = 0;
1042 if (ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
1043 int dist = av1_encoder_get_relative_dist(
1044 cm->cur_frame->ref_display_order_hint[ref_frame - LAST_FRAME],
1045 cm->current_frame.display_order_hint);
1046 ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = dist;
1047 // Get the nearest ref_frame in the past
1048 if (abs(dist) < min_past_dist && dist < 0) {
1049 ref_frame_dist_info->nearest_past_ref = ref_frame;
1050 min_past_dist = abs(dist);
1051 }
1052 // Get the nearest ref_frame in the future
1053 if (dist < min_future_dist && dist > 0) {
1054 ref_frame_dist_info->nearest_future_ref = ref_frame;
1055 min_future_dist = dist;
1056 }
1057 }
1058 }
1059 }
1060
refs_are_one_sided(const AV1_COMMON * cm)1061 static INLINE int refs_are_one_sided(const AV1_COMMON *cm) {
1062 assert(!frame_is_intra_only(cm));
1063
1064 int one_sided_refs = 1;
1065 const int cur_display_order_hint = cm->current_frame.display_order_hint;
1066 for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
1067 const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
1068 if (buf == NULL) continue;
1069 if (av1_encoder_get_relative_dist(buf->display_order_hint,
1070 cur_display_order_hint) > 0) {
1071 one_sided_refs = 0; // bwd reference
1072 break;
1073 }
1074 }
1075 return one_sided_refs;
1076 }
1077
get_skip_mode_ref_offsets(const AV1_COMMON * cm,int ref_order_hint[2])1078 static INLINE void get_skip_mode_ref_offsets(const AV1_COMMON *cm,
1079 int ref_order_hint[2]) {
1080 const SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
1081 ref_order_hint[0] = ref_order_hint[1] = 0;
1082 if (!skip_mode_info->skip_mode_allowed) return;
1083
1084 const RefCntBuffer *const buf_0 =
1085 get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_0);
1086 const RefCntBuffer *const buf_1 =
1087 get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_1);
1088 assert(buf_0 != NULL && buf_1 != NULL);
1089
1090 ref_order_hint[0] = buf_0->order_hint;
1091 ref_order_hint[1] = buf_1->order_hint;
1092 }
1093
check_skip_mode_enabled(AV1_COMP * const cpi)1094 static int check_skip_mode_enabled(AV1_COMP *const cpi) {
1095 AV1_COMMON *const cm = &cpi->common;
1096
1097 av1_setup_skip_mode_allowed(cm);
1098 if (!cm->current_frame.skip_mode_info.skip_mode_allowed) return 0;
1099
1100 // Turn off skip mode if the temporal distances of the reference pair to the
1101 // current frame are different by more than 1 frame.
1102 const int cur_offset = (int)cm->current_frame.order_hint;
1103 int ref_offset[2];
1104 get_skip_mode_ref_offsets(cm, ref_offset);
1105 const int cur_to_ref0 = get_relative_dist(&cm->seq_params.order_hint_info,
1106 cur_offset, ref_offset[0]);
1107 const int cur_to_ref1 = abs(get_relative_dist(&cm->seq_params.order_hint_info,
1108 cur_offset, ref_offset[1]));
1109 if (abs(cur_to_ref0 - cur_to_ref1) > 1) return 0;
1110
1111 // High Latency: Turn off skip mode if all refs are fwd.
1112 if (cpi->all_one_sided_refs && cpi->oxcf.gf_cfg.lag_in_frames > 0) return 0;
1113
1114 static const int flag_list[REF_FRAMES] = { 0,
1115 AOM_LAST_FLAG,
1116 AOM_LAST2_FLAG,
1117 AOM_LAST3_FLAG,
1118 AOM_GOLD_FLAG,
1119 AOM_BWD_FLAG,
1120 AOM_ALT2_FLAG,
1121 AOM_ALT_FLAG };
1122 const int ref_frame[2] = {
1123 cm->current_frame.skip_mode_info.ref_frame_idx_0 + LAST_FRAME,
1124 cm->current_frame.skip_mode_info.ref_frame_idx_1 + LAST_FRAME
1125 };
1126 if (!(cpi->ref_frame_flags & flag_list[ref_frame[0]]) ||
1127 !(cpi->ref_frame_flags & flag_list[ref_frame[1]]))
1128 return 0;
1129
1130 return 1;
1131 }
1132
set_default_interp_skip_flags(const AV1_COMMON * cm,InterpSearchFlags * interp_search_flags)1133 static AOM_INLINE void set_default_interp_skip_flags(
1134 const AV1_COMMON *cm, InterpSearchFlags *interp_search_flags) {
1135 const int num_planes = av1_num_planes(cm);
1136 interp_search_flags->default_interp_skip_flags =
1137 (num_planes == 1) ? INTERP_SKIP_LUMA_EVAL_CHROMA
1138 : INTERP_SKIP_LUMA_SKIP_CHROMA;
1139 }
1140
setup_prune_ref_frame_mask(AV1_COMP * cpi)1141 static AOM_INLINE void setup_prune_ref_frame_mask(AV1_COMP *cpi) {
1142 if ((!cpi->oxcf.ref_frm_cfg.enable_onesided_comp ||
1143 cpi->sf.inter_sf.disable_onesided_comp) &&
1144 cpi->all_one_sided_refs) {
1145 // Disable all compound references
1146 cpi->prune_ref_frame_mask = (1 << MODE_CTX_REF_FRAMES) - (1 << REF_FRAMES);
1147 } else if (!cpi->sf.rt_sf.use_nonrd_pick_mode &&
1148 cpi->sf.inter_sf.selective_ref_frame >= 2) {
1149 AV1_COMMON *const cm = &cpi->common;
1150 const int cur_frame_display_order_hint =
1151 cm->current_frame.display_order_hint;
1152 unsigned int *ref_display_order_hint =
1153 cm->cur_frame->ref_display_order_hint;
1154 const int arf2_dist = av1_encoder_get_relative_dist(
1155 ref_display_order_hint[ALTREF2_FRAME - LAST_FRAME],
1156 cur_frame_display_order_hint);
1157 const int bwd_dist = av1_encoder_get_relative_dist(
1158 ref_display_order_hint[BWDREF_FRAME - LAST_FRAME],
1159 cur_frame_display_order_hint);
1160
1161 for (int ref_idx = REF_FRAMES; ref_idx < MODE_CTX_REF_FRAMES; ++ref_idx) {
1162 MV_REFERENCE_FRAME rf[2];
1163 av1_set_ref_frame(rf, ref_idx);
1164 if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[0]]) ||
1165 !(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[1]])) {
1166 continue;
1167 }
1168
1169 if (!cpi->all_one_sided_refs) {
1170 int ref_dist[2];
1171 for (int i = 0; i < 2; ++i) {
1172 ref_dist[i] = av1_encoder_get_relative_dist(
1173 ref_display_order_hint[rf[i] - LAST_FRAME],
1174 cur_frame_display_order_hint);
1175 }
1176
1177 // One-sided compound is used only when all reference frames are
1178 // one-sided.
1179 if ((ref_dist[0] > 0) == (ref_dist[1] > 0)) {
1180 cpi->prune_ref_frame_mask |= 1 << ref_idx;
1181 }
1182 }
1183
1184 if (cpi->sf.inter_sf.selective_ref_frame >= 4 &&
1185 (rf[0] == ALTREF2_FRAME || rf[1] == ALTREF2_FRAME) &&
1186 (cpi->ref_frame_flags & av1_ref_frame_flag_list[BWDREF_FRAME])) {
1187 // Check if both ALTREF2_FRAME and BWDREF_FRAME are future references.
1188 if (arf2_dist > 0 && bwd_dist > 0 && bwd_dist <= arf2_dist) {
1189 // Drop ALTREF2_FRAME as a reference if BWDREF_FRAME is a closer
1190 // reference to the current frame than ALTREF2_FRAME
1191 cpi->prune_ref_frame_mask |= 1 << ref_idx;
1192 }
1193 }
1194 }
1195 }
1196 }
1197
1198 /*!\brief Encoder setup(only for the current frame), encoding, and recontruction
1199 * for a single frame
1200 *
1201 * \ingroup high_level_algo
1202 */
encode_frame_internal(AV1_COMP * cpi)1203 static AOM_INLINE void encode_frame_internal(AV1_COMP *cpi) {
1204 ThreadData *const td = &cpi->td;
1205 MACROBLOCK *const x = &td->mb;
1206 AV1_COMMON *const cm = &cpi->common;
1207 CommonModeInfoParams *const mi_params = &cm->mi_params;
1208 FeatureFlags *const features = &cm->features;
1209 MACROBLOCKD *const xd = &x->e_mbd;
1210 RD_COUNTS *const rdc = &cpi->td.rd_counts;
1211 FrameProbInfo *const frame_probs = &cpi->frame_probs;
1212 IntraBCHashInfo *const intrabc_hash_info = &x->intrabc_hash_info;
1213 MultiThreadInfo *const mt_info = &cpi->mt_info;
1214 AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
1215 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
1216 const DELTAQ_MODE deltaq_mode = oxcf->q_cfg.deltaq_mode;
1217 int i;
1218
1219 if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
1220 mi_params->setup_mi(mi_params);
1221 }
1222
1223 set_mi_offsets(mi_params, xd, 0, 0);
1224
1225 av1_zero(*td->counts);
1226 av1_zero(rdc->comp_pred_diff);
1227 av1_zero(rdc->tx_type_used);
1228 av1_zero(rdc->obmc_used);
1229 av1_zero(rdc->warped_used);
1230
1231 // Reset the flag.
1232 cpi->intrabc_used = 0;
1233 // Need to disable intrabc when superres is selected
1234 if (av1_superres_scaled(cm)) {
1235 features->allow_intrabc = 0;
1236 }
1237
1238 features->allow_intrabc &= (oxcf->kf_cfg.enable_intrabc);
1239
1240 if (features->allow_warped_motion &&
1241 cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
1242 const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
1243 if (frame_probs->warped_probs[update_type] <
1244 cpi->sf.inter_sf.prune_warped_prob_thresh)
1245 features->allow_warped_motion = 0;
1246 }
1247
1248 int hash_table_created = 0;
1249 if (!is_stat_generation_stage(cpi) && av1_use_hash_me(cpi) &&
1250 !cpi->sf.rt_sf.use_nonrd_pick_mode) {
1251 // TODO(any): move this outside of the recoding loop to avoid recalculating
1252 // the hash table.
1253 // add to hash table
1254 const int pic_width = cpi->source->y_crop_width;
1255 const int pic_height = cpi->source->y_crop_height;
1256 uint32_t *block_hash_values[2][2];
1257 int8_t *is_block_same[2][3];
1258 int k, j;
1259
1260 for (k = 0; k < 2; k++) {
1261 for (j = 0; j < 2; j++) {
1262 CHECK_MEM_ERROR(cm, block_hash_values[k][j],
1263 aom_malloc(sizeof(uint32_t) * pic_width * pic_height));
1264 }
1265
1266 for (j = 0; j < 3; j++) {
1267 CHECK_MEM_ERROR(cm, is_block_same[k][j],
1268 aom_malloc(sizeof(int8_t) * pic_width * pic_height));
1269 }
1270 }
1271
1272 av1_hash_table_init(intrabc_hash_info);
1273 av1_hash_table_create(&intrabc_hash_info->intrabc_hash_table);
1274 hash_table_created = 1;
1275 av1_generate_block_2x2_hash_value(intrabc_hash_info, cpi->source,
1276 block_hash_values[0], is_block_same[0]);
1277 // Hash data generated for screen contents is used for intraBC ME
1278 const int min_alloc_size = block_size_wide[mi_params->mi_alloc_bsize];
1279 const int max_sb_size =
1280 (1 << (cm->seq_params.mib_size_log2 + MI_SIZE_LOG2));
1281 int src_idx = 0;
1282 for (int size = 4; size <= max_sb_size; size *= 2, src_idx = !src_idx) {
1283 const int dst_idx = !src_idx;
1284 av1_generate_block_hash_value(
1285 intrabc_hash_info, cpi->source, size, block_hash_values[src_idx],
1286 block_hash_values[dst_idx], is_block_same[src_idx],
1287 is_block_same[dst_idx]);
1288 if (size >= min_alloc_size) {
1289 av1_add_to_hash_map_by_row_with_precal_data(
1290 &intrabc_hash_info->intrabc_hash_table, block_hash_values[dst_idx],
1291 is_block_same[dst_idx][2], pic_width, pic_height, size);
1292 }
1293 }
1294
1295 for (k = 0; k < 2; k++) {
1296 for (j = 0; j < 2; j++) {
1297 aom_free(block_hash_values[k][j]);
1298 }
1299
1300 for (j = 0; j < 3; j++) {
1301 aom_free(is_block_same[k][j]);
1302 }
1303 }
1304 }
1305
1306 const CommonQuantParams *quant_params = &cm->quant_params;
1307 for (i = 0; i < MAX_SEGMENTS; ++i) {
1308 const int qindex =
1309 cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex)
1310 : quant_params->base_qindex;
1311 xd->lossless[i] =
1312 qindex == 0 && quant_params->y_dc_delta_q == 0 &&
1313 quant_params->u_dc_delta_q == 0 && quant_params->u_ac_delta_q == 0 &&
1314 quant_params->v_dc_delta_q == 0 && quant_params->v_ac_delta_q == 0;
1315 if (xd->lossless[i]) cpi->enc_seg.has_lossless_segment = 1;
1316 xd->qindex[i] = qindex;
1317 if (xd->lossless[i]) {
1318 cpi->optimize_seg_arr[i] = NO_TRELLIS_OPT;
1319 } else {
1320 cpi->optimize_seg_arr[i] = cpi->sf.rd_sf.optimize_coefficients;
1321 }
1322 }
1323 features->coded_lossless = is_coded_lossless(cm, xd);
1324 features->all_lossless = features->coded_lossless && !av1_superres_scaled(cm);
1325
1326 // Fix delta q resolution for the moment
1327 cm->delta_q_info.delta_q_res = 0;
1328 if (cpi->oxcf.q_cfg.aq_mode != CYCLIC_REFRESH_AQ) {
1329 if (deltaq_mode == DELTA_Q_OBJECTIVE)
1330 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_OBJECTIVE;
1331 else if (deltaq_mode == DELTA_Q_PERCEPTUAL)
1332 cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
1333 // Set delta_q_present_flag before it is used for the first time
1334 cm->delta_q_info.delta_lf_res = DEFAULT_DELTA_LF_RES;
1335 cm->delta_q_info.delta_q_present_flag = deltaq_mode != NO_DELTA_Q;
1336
1337 // Turn off cm->delta_q_info.delta_q_present_flag if objective delta_q
1338 // is used for ineligible frames. That effectively will turn off row_mt
1339 // usage. Note objective delta_q and tpl eligible frames are only altref
1340 // frames currently.
1341 const GF_GROUP *gf_group = &cpi->gf_group;
1342 if (cm->delta_q_info.delta_q_present_flag) {
1343 if (deltaq_mode == DELTA_Q_OBJECTIVE &&
1344 !is_frame_tpl_eligible(gf_group, gf_group->index))
1345 cm->delta_q_info.delta_q_present_flag = 0;
1346 }
1347
1348 // Reset delta_q_used flag
1349 cpi->deltaq_used = 0;
1350
1351 cm->delta_q_info.delta_lf_present_flag =
1352 cm->delta_q_info.delta_q_present_flag &&
1353 oxcf->tool_cfg.enable_deltalf_mode;
1354 cm->delta_q_info.delta_lf_multi = DEFAULT_DELTA_LF_MULTI;
1355
1356 // update delta_q_present_flag and delta_lf_present_flag based on
1357 // base_qindex
1358 cm->delta_q_info.delta_q_present_flag &= quant_params->base_qindex > 0;
1359 cm->delta_q_info.delta_lf_present_flag &= quant_params->base_qindex > 0;
1360 }
1361
1362 av1_frame_init_quantizer(cpi);
1363 av1_initialize_rd_consts(cpi);
1364 av1_set_sad_per_bit(cpi, &x->mv_costs, quant_params->base_qindex);
1365
1366 init_encode_frame_mb_context(cpi);
1367 set_default_interp_skip_flags(cm, &cpi->interp_search_flags);
1368 if (cm->prev_frame && cm->prev_frame->seg.enabled)
1369 cm->last_frame_seg_map = cm->prev_frame->seg_map;
1370 else
1371 cm->last_frame_seg_map = NULL;
1372 if (features->allow_intrabc || features->coded_lossless) {
1373 av1_set_default_ref_deltas(cm->lf.ref_deltas);
1374 av1_set_default_mode_deltas(cm->lf.mode_deltas);
1375 } else if (cm->prev_frame) {
1376 memcpy(cm->lf.ref_deltas, cm->prev_frame->ref_deltas, REF_FRAMES);
1377 memcpy(cm->lf.mode_deltas, cm->prev_frame->mode_deltas, MAX_MODE_LF_DELTAS);
1378 }
1379 memcpy(cm->cur_frame->ref_deltas, cm->lf.ref_deltas, REF_FRAMES);
1380 memcpy(cm->cur_frame->mode_deltas, cm->lf.mode_deltas, MAX_MODE_LF_DELTAS);
1381
1382 cpi->all_one_sided_refs =
1383 frame_is_intra_only(cm) ? 0 : refs_are_one_sided(cm);
1384
1385 cpi->prune_ref_frame_mask = 0;
1386 // Figure out which ref frames can be skipped at frame level.
1387 setup_prune_ref_frame_mask(cpi);
1388
1389 x->txfm_search_info.txb_split_count = 0;
1390 #if CONFIG_SPEED_STATS
1391 x->txfm_search_info.tx_search_count = 0;
1392 #endif // CONFIG_SPEED_STATS
1393
1394 #if !CONFIG_REALTIME_ONLY
1395 #if CONFIG_COLLECT_COMPONENT_TIMING
1396 start_timing(cpi, av1_compute_global_motion_time);
1397 #endif
1398 av1_compute_global_motion_facade(cpi);
1399 #if CONFIG_COLLECT_COMPONENT_TIMING
1400 end_timing(cpi, av1_compute_global_motion_time);
1401 #endif
1402 #endif // !CONFIG_REALTIME_ONLY
1403
1404 #if CONFIG_COLLECT_COMPONENT_TIMING
1405 start_timing(cpi, av1_setup_motion_field_time);
1406 #endif
1407 if (features->allow_ref_frame_mvs) av1_setup_motion_field(cm);
1408 #if CONFIG_COLLECT_COMPONENT_TIMING
1409 end_timing(cpi, av1_setup_motion_field_time);
1410 #endif
1411
1412 cm->current_frame.skip_mode_info.skip_mode_flag =
1413 check_skip_mode_enabled(cpi);
1414
1415 enc_row_mt->sync_read_ptr = av1_row_mt_sync_read_dummy;
1416 enc_row_mt->sync_write_ptr = av1_row_mt_sync_write_dummy;
1417 mt_info->row_mt_enabled = 0;
1418
1419 if (oxcf->row_mt && (mt_info->num_workers > 1)) {
1420 mt_info->row_mt_enabled = 1;
1421 enc_row_mt->sync_read_ptr = av1_row_mt_sync_read;
1422 enc_row_mt->sync_write_ptr = av1_row_mt_sync_write;
1423 av1_encode_tiles_row_mt(cpi);
1424 } else {
1425 if (AOMMIN(mt_info->num_workers, cm->tiles.cols * cm->tiles.rows) > 1)
1426 av1_encode_tiles_mt(cpi);
1427 else
1428 encode_tiles(cpi);
1429 }
1430
1431 // If intrabc is allowed but never selected, reset the allow_intrabc flag.
1432 if (features->allow_intrabc && !cpi->intrabc_used) {
1433 features->allow_intrabc = 0;
1434 }
1435 if (features->allow_intrabc) {
1436 cm->delta_q_info.delta_lf_present_flag = 0;
1437 }
1438
1439 if (cm->delta_q_info.delta_q_present_flag && cpi->deltaq_used == 0) {
1440 cm->delta_q_info.delta_q_present_flag = 0;
1441 }
1442
1443 // Set the transform size appropriately before bitstream creation
1444 const MODE_EVAL_TYPE eval_type =
1445 cpi->sf.winner_mode_sf.enable_winner_mode_for_tx_size_srch
1446 ? WINNER_MODE_EVAL
1447 : DEFAULT_EVAL;
1448 const TX_SIZE_SEARCH_METHOD tx_search_type =
1449 cpi->winner_mode_params.tx_size_search_methods[eval_type];
1450 assert(oxcf->txfm_cfg.enable_tx64 || tx_search_type != USE_LARGESTALL);
1451 features->tx_mode = select_tx_mode(cm, tx_search_type);
1452
1453 if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats) {
1454 const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
1455
1456 for (i = 0; i < TX_SIZES_ALL; i++) {
1457 int sum = 0;
1458 int j;
1459 int left = 1024;
1460
1461 for (j = 0; j < TX_TYPES; j++)
1462 sum += cpi->td.rd_counts.tx_type_used[i][j];
1463
1464 for (j = TX_TYPES - 1; j >= 0; j--) {
1465 const int new_prob =
1466 sum ? 1024 * cpi->td.rd_counts.tx_type_used[i][j] / sum
1467 : (j ? 0 : 1024);
1468 int prob =
1469 (frame_probs->tx_type_probs[update_type][i][j] + new_prob) >> 1;
1470 left -= prob;
1471 if (j == 0) prob += left;
1472 frame_probs->tx_type_probs[update_type][i][j] = prob;
1473 }
1474 }
1475 }
1476
1477 if (!cpi->sf.inter_sf.disable_obmc &&
1478 cpi->sf.inter_sf.prune_obmc_prob_thresh > 0) {
1479 const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
1480
1481 for (i = 0; i < BLOCK_SIZES_ALL; i++) {
1482 int sum = 0;
1483 for (int j = 0; j < 2; j++) sum += cpi->td.rd_counts.obmc_used[i][j];
1484
1485 const int new_prob =
1486 sum ? 128 * cpi->td.rd_counts.obmc_used[i][1] / sum : 0;
1487 frame_probs->obmc_probs[update_type][i] =
1488 (frame_probs->obmc_probs[update_type][i] + new_prob) >> 1;
1489 }
1490 }
1491
1492 if (features->allow_warped_motion &&
1493 cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
1494 const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
1495 int sum = 0;
1496 for (i = 0; i < 2; i++) sum += cpi->td.rd_counts.warped_used[i];
1497 const int new_prob = sum ? 128 * cpi->td.rd_counts.warped_used[1] / sum : 0;
1498 frame_probs->warped_probs[update_type] =
1499 (frame_probs->warped_probs[update_type] + new_prob) >> 1;
1500 }
1501
1502 if (cm->current_frame.frame_type != KEY_FRAME &&
1503 cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
1504 features->interp_filter == SWITCHABLE) {
1505 const FRAME_UPDATE_TYPE update_type = get_frame_update_type(&cpi->gf_group);
1506
1507 for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
1508 int sum = 0;
1509 int j;
1510 int left = 1536;
1511
1512 for (j = 0; j < SWITCHABLE_FILTERS; j++) {
1513 sum += cpi->td.counts->switchable_interp[i][j];
1514 }
1515
1516 for (j = SWITCHABLE_FILTERS - 1; j >= 0; j--) {
1517 const int new_prob =
1518 sum ? 1536 * cpi->td.counts->switchable_interp[i][j] / sum
1519 : (j ? 0 : 1536);
1520 int prob = (frame_probs->switchable_interp_probs[update_type][i][j] +
1521 new_prob) >>
1522 1;
1523 left -= prob;
1524 if (j == 0) prob += left;
1525 frame_probs->switchable_interp_probs[update_type][i][j] = prob;
1526 }
1527 }
1528 }
1529
1530 if (hash_table_created) {
1531 av1_hash_table_destroy(&intrabc_hash_info->intrabc_hash_table);
1532 }
1533 }
1534
1535 /*!\brief Setup reference frame buffers and encode a frame
1536 *
1537 * \ingroup high_level_algo
1538 * \callgraph
1539 * \callergraph
1540 *
1541 * \param[in] cpi Top-level encoder structure
1542 */
av1_encode_frame(AV1_COMP * cpi)1543 void av1_encode_frame(AV1_COMP *cpi) {
1544 AV1_COMMON *const cm = &cpi->common;
1545 CurrentFrame *const current_frame = &cm->current_frame;
1546 FeatureFlags *const features = &cm->features;
1547 const int num_planes = av1_num_planes(cm);
1548 // Indicates whether or not to use a default reduced set for ext-tx
1549 // rather than the potential full set of 16 transforms
1550 features->reduced_tx_set_used = cpi->oxcf.txfm_cfg.reduced_tx_type_set;
1551
1552 // Make sure segment_id is no larger than last_active_segid.
1553 if (cm->seg.enabled && cm->seg.update_map) {
1554 const int mi_rows = cm->mi_params.mi_rows;
1555 const int mi_cols = cm->mi_params.mi_cols;
1556 const int last_active_segid = cm->seg.last_active_segid;
1557 uint8_t *map = cpi->enc_seg.map;
1558 for (int mi_row = 0; mi_row < mi_rows; ++mi_row) {
1559 for (int mi_col = 0; mi_col < mi_cols; ++mi_col) {
1560 map[mi_col] = AOMMIN(map[mi_col], last_active_segid);
1561 }
1562 map += mi_cols;
1563 }
1564 }
1565
1566 av1_setup_frame_buf_refs(cm);
1567 enforce_max_ref_frames(cpi, &cpi->ref_frame_flags,
1568 cm->cur_frame->ref_display_order_hint,
1569 cm->current_frame.display_order_hint);
1570 set_rel_frame_dist(&cpi->common, &cpi->ref_frame_dist_info,
1571 cpi->ref_frame_flags);
1572 av1_setup_frame_sign_bias(cm);
1573
1574 #if CONFIG_MISMATCH_DEBUG
1575 mismatch_reset_frame(num_planes);
1576 #else
1577 (void)num_planes;
1578 #endif
1579
1580 if (cpi->sf.hl_sf.frame_parameter_update) {
1581 RD_COUNTS *const rdc = &cpi->td.rd_counts;
1582
1583 if (frame_is_intra_only(cm))
1584 current_frame->reference_mode = SINGLE_REFERENCE;
1585 else
1586 current_frame->reference_mode = REFERENCE_MODE_SELECT;
1587
1588 features->interp_filter = SWITCHABLE;
1589 if (cm->tiles.large_scale) features->interp_filter = EIGHTTAP_REGULAR;
1590
1591 features->switchable_motion_mode = 1;
1592
1593 rdc->compound_ref_used_flag = 0;
1594 rdc->skip_mode_used_flag = 0;
1595
1596 encode_frame_internal(cpi);
1597
1598 if (current_frame->reference_mode == REFERENCE_MODE_SELECT) {
1599 // Use a flag that includes 4x4 blocks
1600 if (rdc->compound_ref_used_flag == 0) {
1601 current_frame->reference_mode = SINGLE_REFERENCE;
1602 #if CONFIG_ENTROPY_STATS
1603 av1_zero(cpi->td.counts->comp_inter);
1604 #endif // CONFIG_ENTROPY_STATS
1605 }
1606 }
1607 // Re-check on the skip mode status as reference mode may have been
1608 // changed.
1609 SkipModeInfo *const skip_mode_info = ¤t_frame->skip_mode_info;
1610 if (frame_is_intra_only(cm) ||
1611 current_frame->reference_mode == SINGLE_REFERENCE) {
1612 skip_mode_info->skip_mode_allowed = 0;
1613 skip_mode_info->skip_mode_flag = 0;
1614 }
1615 if (skip_mode_info->skip_mode_flag && rdc->skip_mode_used_flag == 0)
1616 skip_mode_info->skip_mode_flag = 0;
1617
1618 if (!cm->tiles.large_scale) {
1619 if (features->tx_mode == TX_MODE_SELECT &&
1620 cpi->td.mb.txfm_search_info.txb_split_count == 0)
1621 features->tx_mode = TX_MODE_LARGEST;
1622 }
1623 } else {
1624 encode_frame_internal(cpi);
1625 }
1626 }
1627