• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &current_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