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