Coverage Report

Created: 2026-11-12 08:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/av1/encoder/encodeframe.c
Line
Count
Source
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/aom_scale_rtcd.h"
21
#include "config/av1_rtcd.h"
22
23
#include "aom_dsp/aom_dsp_common.h"
24
#include "aom_dsp/binary_codes_writer.h"
25
#include "aom_ports/mem.h"
26
#include "aom_ports/aom_timer.h"
27
#include "aom_util/aom_pthread.h"
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/common_data.h"
35
#include "av1/common/entropy.h"
36
#include "av1/common/entropymode.h"
37
#include "av1/common/idct.h"
38
#include "av1/common/mv.h"
39
#include "av1/common/mvref_common.h"
40
#include "av1/common/pred_common.h"
41
#include "av1/common/quant_common.h"
42
#include "av1/common/reconintra.h"
43
#include "av1/common/reconinter.h"
44
#include "av1/common/seg_common.h"
45
#include "av1/common/tile_common.h"
46
#include "av1/common/warped_motion.h"
47
48
#include "av1/encoder/allintra_vis.h"
49
#include "av1/encoder/aq_complexity.h"
50
#include "av1/encoder/aq_cyclicrefresh.h"
51
#include "av1/encoder/aq_variance.h"
52
#include "av1/encoder/av1_quantize.h"
53
#include "av1/encoder/global_motion_facade.h"
54
#include "av1/encoder/encodeframe.h"
55
#include "av1/encoder/encodeframe_utils.h"
56
#include "av1/encoder/encodemb.h"
57
#include "av1/encoder/encodemv.h"
58
#include "av1/encoder/encodetxb.h"
59
#include "av1/encoder/ethread.h"
60
#include "av1/encoder/extend.h"
61
#include "av1/encoder/intra_mode_search_utils.h"
62
#include "av1/encoder/ml.h"
63
#include "av1/encoder/motion_search_facade.h"
64
#include "av1/encoder/partition_strategy.h"
65
#if !CONFIG_REALTIME_ONLY
66
#include "av1/encoder/partition_model_weights.h"
67
#endif
68
#include "av1/encoder/partition_search.h"
69
#include "av1/encoder/rd.h"
70
#include "av1/encoder/rdopt.h"
71
#include "av1/encoder/reconinter_enc.h"
72
#include "av1/encoder/segmentation.h"
73
#include "av1/encoder/tokenize.h"
74
#include "av1/encoder/tpl_model.h"
75
#include "av1/encoder/var_based_part.h"
76
77
#if CONFIG_TUNE_VMAF
78
#include "av1/encoder/tune_vmaf.h"
79
#endif
80
81
/*!\cond */
82
// This is used as a reference when computing the source variance for the
83
//  purposes of activity masking.
84
// Eventually this should be replaced by custom no-reference routines,
85
//  which will be faster.
86
static const uint8_t AV1_VAR_OFFS[MAX_SB_SIZE] = {
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, 128, 128, 128, 128, 128, 128, 128,
94
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
95
  128, 128, 128, 128, 128, 128, 128, 128
96
};
97
98
#if CONFIG_AV1_HIGHBITDEPTH
99
static const uint16_t AV1_HIGH_VAR_OFFS_8[MAX_SB_SIZE] = {
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, 128, 128, 128, 128, 128, 128, 128,
106
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
107
  128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
108
  128, 128, 128, 128, 128, 128, 128, 128
109
};
110
111
static const uint16_t AV1_HIGH_VAR_OFFS_10[MAX_SB_SIZE] = {
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
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
126
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4,
127
  128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4, 128 * 4
128
};
129
130
static const uint16_t AV1_HIGH_VAR_OFFS_12[MAX_SB_SIZE] = {
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, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
147
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
148
  128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16, 128 * 16,
149
  128 * 16, 128 * 16
150
};
151
#endif  // CONFIG_AV1_HIGHBITDEPTH
152
/*!\endcond */
153
154
// For the given bit depth, returns a constant array used to assist the
155
// calculation of source block variance, which will then be used to decide
156
// adaptive quantizers.
157
0
static const uint8_t *get_var_offs(int use_hbd, int bd) {
158
0
#if CONFIG_AV1_HIGHBITDEPTH
159
0
  if (use_hbd) {
160
0
    assert(bd == 8 || bd == 10 || bd == 12);
161
0
    const int off_index = (bd - 8) >> 1;
162
0
    static const uint16_t *high_var_offs[3] = { AV1_HIGH_VAR_OFFS_8,
163
0
                                                AV1_HIGH_VAR_OFFS_10,
164
0
                                                AV1_HIGH_VAR_OFFS_12 };
165
0
    return CONVERT_TO_BYTEPTR(high_var_offs[off_index]);
166
0
  }
167
#else
168
  (void)use_hbd;
169
  (void)bd;
170
  assert(!use_hbd);
171
#endif
172
0
  assert(bd == 8);
173
0
  return AV1_VAR_OFFS;
174
0
}
175
176
0
void av1_init_rtc_counters(MACROBLOCK *const x) {
177
0
  av1_init_cyclic_refresh_counters(x);
178
0
  x->cnt_zeromv = 0;
179
0
  x->sb_col_scroll = 0;
180
0
  x->sb_row_scroll = 0;
181
0
}
182
183
0
void av1_accumulate_rtc_counters(AV1_COMP *cpi, const MACROBLOCK *const x) {
184
0
  if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ)
185
0
    av1_accumulate_cyclic_refresh_counters(cpi->cyclic_refresh, x);
186
0
  cpi->rc.cnt_zeromv += x->cnt_zeromv;
187
0
  cpi->rc.num_col_blscroll_last_tl0 += x->sb_col_scroll;
188
0
  cpi->rc.num_row_blscroll_last_tl0 += x->sb_row_scroll;
189
0
}
190
191
unsigned int av1_get_perpixel_variance(const AV1_COMP *cpi,
192
                                       const MACROBLOCKD *xd,
193
                                       const struct buf_2d *ref,
194
                                       BLOCK_SIZE bsize, int plane,
195
0
                                       int use_hbd) {
196
0
  const int subsampling_x = xd->plane[plane].subsampling_x;
197
0
  const int subsampling_y = xd->plane[plane].subsampling_y;
198
0
  const BLOCK_SIZE plane_bsize =
199
0
      get_plane_block_size(bsize, subsampling_x, subsampling_y);
200
0
  unsigned int sse;
201
0
  const unsigned int var = cpi->ppi->fn_ptr[plane_bsize].vf(
202
0
      ref->buf, ref->stride, get_var_offs(use_hbd, xd->bd), 0, &sse);
203
0
  return ROUND_POWER_OF_TWO(var, num_pels_log2_lookup[plane_bsize]);
204
0
}
205
206
unsigned int av1_get_perpixel_variance_facade(const AV1_COMP *cpi,
207
                                              const MACROBLOCKD *xd,
208
                                              const struct buf_2d *ref,
209
0
                                              BLOCK_SIZE bsize, int plane) {
210
0
  const int use_hbd = is_cur_buf_hbd(xd);
211
0
  return av1_get_perpixel_variance(cpi, xd, ref, bsize, plane, use_hbd);
212
0
}
213
214
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
215
                          int mi_row, int mi_col, const int num_planes,
216
0
                          BLOCK_SIZE bsize) {
217
  // Set current frame pointer.
218
0
  x->e_mbd.cur_buf = src;
219
220
  // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
221
  // the static analysis warnings.
222
0
  for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); i++) {
223
0
    const int is_uv = i > 0;
224
0
    setup_pred_plane(
225
0
        &x->plane[i].src, bsize, src->buffers[i], src->crop_widths[is_uv],
226
0
        src->crop_heights[is_uv], src->strides[is_uv], mi_row, mi_col, NULL,
227
0
        x->e_mbd.plane[i].subsampling_x, x->e_mbd.plane[i].subsampling_y);
228
0
  }
229
0
}
230
231
#if !CONFIG_REALTIME_ONLY
232
/*!\brief Assigns different quantization parameters to each superblock
233
 * based on statistics relevant to the selected delta-q mode (variance).
234
 * This is the non-rd version.
235
 *
236
 * \param[in]     cpi         Top level encoder instance structure
237
 * \param[in,out] td          Thread data structure
238
 * \param[in,out] x           Superblock level data for this block.
239
 * \param[in]     tile_info   Tile information / identification
240
 * \param[in]     mi_row      Block row (in "MI_SIZE" units) index
241
 * \param[in]     mi_col      Block column (in "MI_SIZE" units) index
242
 * \param[out]    num_planes  Number of image planes (e.g. Y,U,V)
243
 *
244
 * \remark No return value but updates superblock and thread data
245
 * related to the q / q delta to be used.
246
 */
247
static inline void setup_delta_q_nonrd(AV1_COMP *const cpi, ThreadData *td,
248
                                       MACROBLOCK *const x,
249
                                       const TileInfo *const tile_info,
250
0
                                       int mi_row, int mi_col, int num_planes) {
251
0
  AV1_COMMON *const cm = &cpi->common;
252
0
  const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
253
0
  assert(delta_q_info->delta_q_present_flag);
254
255
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
256
0
  av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
257
258
0
  const int delta_q_res = delta_q_info->delta_q_res;
259
0
  int current_qindex = cm->quant_params.base_qindex;
260
261
0
  if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_VARIANCE_BOOST) {
262
0
    current_qindex = av1_get_sbq_variance_boost(cpi, x);
263
0
  }
264
265
0
  x->rdmult_cur_qindex = current_qindex;
266
0
  MACROBLOCKD *const xd = &x->e_mbd;
267
0
  current_qindex = av1_adjust_q_from_delta_q_res(
268
0
      delta_q_res, xd->current_base_qindex, current_qindex);
269
270
0
  x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
271
0
  x->rdmult_delta_qindex = x->delta_qindex;
272
273
0
  av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
274
0
  xd->mi[0]->current_qindex = current_qindex;
275
0
  av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
276
277
  // keep track of any non-zero delta-q used
278
0
  td->deltaq_used |= (x->delta_qindex != 0);
279
0
}
280
281
/*!\brief Assigns different quantization parameters to each superblock
282
 * based on statistics relevant to the selected delta-q mode (TPL weight,
283
 * variance, HDR, etc).
284
 *
285
 * \ingroup tpl_modelling
286
 *
287
 * \param[in]     cpi         Top level encoder instance structure
288
 * \param[in,out] td          Thread data structure
289
 * \param[in,out] x           Superblock level data for this block.
290
 * \param[in]     tile_info   Tile information / identification
291
 * \param[in]     mi_row      Block row (in "MI_SIZE" units) index
292
 * \param[in]     mi_col      Block column (in "MI_SIZE" units) index
293
 * \param[out]    num_planes  Number of image planes (e.g. Y,U,V)
294
 *
295
 * \remark No return value but updates superblock and thread data
296
 * related to the q / q delta to be used.
297
 */
298
static inline void setup_delta_q(AV1_COMP *const cpi, ThreadData *td,
299
                                 MACROBLOCK *const x,
300
                                 const TileInfo *const tile_info, int mi_row,
301
0
                                 int mi_col, int num_planes) {
302
0
  AV1_COMMON *const cm = &cpi->common;
303
0
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
304
0
  const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
305
306
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
307
0
  av1_setup_src_planes(x, cpi->source, mi_row, mi_col, num_planes, sb_size);
308
309
0
  const int delta_q_res = delta_q_info->delta_q_res;
310
0
  int current_qindex = cm->quant_params.base_qindex;
311
0
  const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
312
0
  const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
313
0
  const int sb_cols =
314
0
      CEIL_POWER_OF_TWO(cm->mi_params.mi_cols, cm->seq_params->mib_size_log2);
315
0
  const int sb_index = sb_row * sb_cols + sb_col;
316
0
  if (cpi->use_ducky_encode && cpi->ducky_encode_info.frame_info.qp_mode ==
317
0
                                   DUCKY_ENCODE_FRAME_MODE_QINDEX) {
318
0
    current_qindex =
319
0
        cpi->ducky_encode_info.frame_info.superblock_encode_qindex[sb_index];
320
0
  } else if (cpi->ext_ratectrl.ready &&
321
0
             (cpi->ext_ratectrl.funcs.rc_type & AOM_RC_QP) != 0 &&
322
0
             cpi->ext_ratectrl.funcs.get_encodeframe_decision != NULL &&
323
0
             cpi->ext_ratectrl.sb_params_list != NULL) {
324
0
    if (cpi->ext_ratectrl.use_delta_q) {
325
      // Only used for per-coding-block RD mult calculation later.
326
0
      current_qindex = av1_get_q_for_deltaq_objective(cpi, td, NULL, sb_size,
327
0
                                                      mi_row, mi_col);
328
329
0
      const int q_index = cpi->ext_ratectrl.sb_params_list[sb_index].q_index;
330
0
      if (q_index != AOM_DEFAULT_Q) {
331
0
        current_qindex = q_index;
332
0
      }
333
0
    }
334
0
  } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL) {
335
0
    if (DELTA_Q_PERCEPTUAL_MODULATION == 1) {
336
0
      const int block_wavelet_energy_level =
337
0
          av1_block_wavelet_energy_level(cpi, x, sb_size);
338
0
      x->sb_energy_level = block_wavelet_energy_level;
339
0
      current_qindex = av1_compute_q_from_energy_level_deltaq_mode(
340
0
          cpi, block_wavelet_energy_level);
341
0
    } else {
342
0
      const int block_var_level = av1_log_block_var(cpi, x, sb_size);
343
0
      x->sb_energy_level = block_var_level;
344
0
      current_qindex =
345
0
          av1_compute_q_from_energy_level_deltaq_mode(cpi, block_var_level);
346
0
    }
347
0
  } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
348
0
             cpi->oxcf.algo_cfg.enable_tpl_model) {
349
    // Setup deltaq based on tpl stats
350
0
    current_qindex =
351
0
        av1_get_q_for_deltaq_objective(cpi, td, NULL, sb_size, mi_row, mi_col);
352
0
  } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_PERCEPTUAL_AI) {
353
0
    current_qindex = av1_get_sbq_perceptual_ai(cpi, sb_size, mi_row, mi_col);
354
0
  } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_USER_RATING_BASED) {
355
0
    current_qindex = av1_get_sbq_user_rating_based(cpi, mi_row, mi_col);
356
0
  } else if (cpi->oxcf.q_cfg.enable_hdr_deltaq) {
357
0
    current_qindex = av1_get_q_for_hdr(cpi, x, sb_size, mi_row, mi_col);
358
0
  } else if (cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_VARIANCE_BOOST) {
359
0
    current_qindex = av1_get_sbq_variance_boost(cpi, x);
360
0
  }
361
362
0
  x->rdmult_cur_qindex = current_qindex;
363
0
  MACROBLOCKD *const xd = &x->e_mbd;
364
0
  const int adjusted_qindex = av1_adjust_q_from_delta_q_res(
365
0
      delta_q_res, xd->current_base_qindex, current_qindex);
366
0
  if (cpi->use_ducky_encode) {
367
0
    assert(adjusted_qindex == current_qindex);
368
0
  }
369
0
  current_qindex = adjusted_qindex;
370
371
0
  x->delta_qindex = cm->delta_q_info.delta_q_present_flag
372
0
                        ? current_qindex - cm->quant_params.base_qindex
373
0
                        : 0;
374
0
  x->rdmult_delta_qindex = current_qindex - cm->quant_params.base_qindex;
375
376
0
  av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
377
0
  xd->mi[0]->current_qindex = cm->delta_q_info.delta_q_present_flag
378
0
                                  ? current_qindex
379
0
                                  : cm->quant_params.base_qindex;
380
0
  av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
381
382
  // keep track of any non-zero delta-q used
383
0
  td->deltaq_used |= (x->delta_qindex != 0);
384
385
0
  if (cpi->oxcf.tool_cfg.enable_deltalf_mode &&
386
0
      cm->delta_q_info.delta_q_present_flag) {
387
0
    const int delta_lf_res = delta_q_info->delta_lf_res;
388
0
    const int lfmask = ~(delta_lf_res - 1);
389
0
    const int delta_lf_from_base =
390
0
        ((x->delta_qindex / 4 + delta_lf_res / 2) & lfmask);
391
0
    const int8_t delta_lf =
392
0
        (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
393
0
    const int frame_lf_count =
394
0
        av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
395
0
    const int mib_size = cm->seq_params->mib_size;
396
397
    // pre-set the delta lf for loop filter. Note that this value is set
398
    // before mi is assigned for each block in current superblock
399
0
    for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row); j++) {
400
0
      for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col); k++) {
401
0
        const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
402
0
        mi_params->mi_alloc[grid_idx].delta_lf_from_base = delta_lf;
403
0
        for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
404
0
          mi_params->mi_alloc[grid_idx].delta_lf[lf_id] = delta_lf;
405
0
        }
406
0
      }
407
0
    }
408
0
  }
409
0
}
410
411
static void init_ref_frame_space(AV1_COMP *cpi, ThreadData *td, int mi_row,
412
0
                                 int mi_col) {
413
0
  const AV1_COMMON *cm = &cpi->common;
414
0
  const GF_GROUP *const gf_group = &cpi->ppi->gf_group;
415
0
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
416
0
  MACROBLOCK *x = &td->mb;
417
0
  const int frame_idx = cpi->gf_frame_index;
418
0
  TplParams *const tpl_data = &cpi->ppi->tpl_data;
419
0
  const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
420
421
0
  av1_zero(x->tpl_keep_ref_frame);
422
423
0
  if (!av1_tpl_stats_ready(tpl_data, frame_idx)) return;
424
0
  if (!is_frame_tpl_eligible(gf_group, cpi->gf_frame_index)) return;
425
0
  if (cpi->oxcf.q_cfg.aq_mode != NO_AQ) return;
426
427
0
  const int is_overlay =
428
0
      cpi->ppi->gf_group.update_type[frame_idx] == OVERLAY_UPDATE;
429
0
  if (is_overlay) {
430
0
    memset(x->tpl_keep_ref_frame, 1, sizeof(x->tpl_keep_ref_frame));
431
0
    return;
432
0
  }
433
434
0
  TplDepFrame *tpl_frame = &tpl_data->tpl_frame[frame_idx];
435
0
  TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
436
0
  const int tpl_stride = tpl_frame->stride;
437
0
  int64_t inter_cost[INTER_REFS_PER_FRAME] = { 0 };
438
0
  const int step = 1 << block_mis_log2;
439
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
440
441
0
  const int mi_row_end =
442
0
      AOMMIN(mi_size_high[sb_size] + mi_row, mi_params->mi_rows);
443
0
  const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
444
0
  const int mi_col_sr =
445
0
      coded_to_superres_mi(mi_col, cm->superres_scale_denominator);
446
0
  const int mi_col_end_sr =
447
0
      AOMMIN(coded_to_superres_mi(mi_col + mi_size_wide[sb_size],
448
0
                                  cm->superres_scale_denominator),
449
0
             mi_cols_sr);
450
0
  const int row_step = step;
451
0
  const int col_step_sr =
452
0
      coded_to_superres_mi(step, cm->superres_scale_denominator);
453
0
  for (int row = mi_row; row < mi_row_end; row += row_step) {
454
0
    for (int col = mi_col_sr; col < mi_col_end_sr; col += col_step_sr) {
455
0
      const TplDepStats *this_stats =
456
0
          &tpl_stats[av1_tpl_ptr_pos(row, col, tpl_stride, block_mis_log2)];
457
0
      int64_t tpl_pred_error[INTER_REFS_PER_FRAME] = { 0 };
458
      // Find the winner ref frame idx for the current block
459
0
      int64_t best_inter_cost = this_stats->pred_error[0];
460
0
      int best_rf_idx = 0;
461
0
      for (int idx = 1; idx < INTER_REFS_PER_FRAME; ++idx) {
462
0
        if ((this_stats->pred_error[idx] < best_inter_cost) &&
463
0
            (this_stats->pred_error[idx] != 0)) {
464
0
          best_inter_cost = this_stats->pred_error[idx];
465
0
          best_rf_idx = idx;
466
0
        }
467
0
      }
468
      // tpl_pred_error is the pred_error reduction of best_ref w.r.t.
469
      // LAST_FRAME.
470
0
      tpl_pred_error[best_rf_idx] = this_stats->pred_error[best_rf_idx] -
471
0
                                    this_stats->pred_error[LAST_FRAME - 1];
472
473
0
      for (int rf_idx = 1; rf_idx < INTER_REFS_PER_FRAME; ++rf_idx)
474
0
        inter_cost[rf_idx] += tpl_pred_error[rf_idx];
475
0
    }
476
0
  }
477
478
0
  int rank_index[INTER_REFS_PER_FRAME - 1];
479
0
  for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
480
0
    rank_index[idx] = idx + 1;
481
0
    for (int i = idx; i > 0; --i) {
482
0
      if (inter_cost[rank_index[i - 1]] > inter_cost[rank_index[i]]) {
483
0
        const int tmp = rank_index[i - 1];
484
0
        rank_index[i - 1] = rank_index[i];
485
0
        rank_index[i] = tmp;
486
0
      }
487
0
    }
488
0
  }
489
490
0
  x->tpl_keep_ref_frame[INTRA_FRAME] = 1;
491
0
  x->tpl_keep_ref_frame[LAST_FRAME] = 1;
492
493
0
  int cutoff_ref = 0;
494
0
  for (int idx = 0; idx < INTER_REFS_PER_FRAME - 1; ++idx) {
495
0
    x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 1;
496
0
    if (idx > 2) {
497
0
      if (!cutoff_ref) {
498
        // If the predictive coding gains are smaller than the previous more
499
        // relevant frame over certain amount, discard this frame and all the
500
        // frames afterwards.
501
0
        if (llabs(inter_cost[rank_index[idx]]) <
502
0
                llabs(inter_cost[rank_index[idx - 1]]) / 8 ||
503
0
            inter_cost[rank_index[idx]] == 0)
504
0
          cutoff_ref = 1;
505
0
      }
506
507
0
      if (cutoff_ref) x->tpl_keep_ref_frame[rank_index[idx] + LAST_FRAME] = 0;
508
0
    }
509
0
  }
510
0
}
511
512
static inline void adjust_rdmult_tpl_model(AV1_COMP *cpi, MACROBLOCK *x,
513
0
                                           int mi_row, int mi_col) {
514
0
  const BLOCK_SIZE sb_size = cpi->common.seq_params->sb_size;
515
0
  const int orig_rdmult = cpi->rd.RDMULT;
516
517
0
  assert(IMPLIES(cpi->ppi->gf_group.size > 0,
518
0
                 cpi->gf_frame_index < cpi->ppi->gf_group.size));
519
0
  const int gf_group_index = cpi->gf_frame_index;
520
0
  if (cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
521
0
      cpi->oxcf.q_cfg.deltaq_mode == NO_DELTA_Q && gf_group_index > 0 &&
522
0
      cpi->ppi->gf_group.update_type[gf_group_index] == ARF_UPDATE) {
523
0
    const int dr =
524
0
        av1_get_rdmult_delta(cpi, sb_size, mi_row, mi_col, orig_rdmult);
525
0
    x->rdmult = dr;
526
0
  }
527
0
}
528
#endif  // !CONFIG_REALTIME_ONLY
529
530
#if CONFIG_RT_ML_PARTITIONING
531
// Get a prediction(stored in x->est_pred) for the whole superblock.
532
static void get_estimated_pred(AV1_COMP *cpi, const TileInfo *const tile,
533
                               MACROBLOCK *x, int mi_row, int mi_col) {
534
  AV1_COMMON *const cm = &cpi->common;
535
  const int is_key_frame = frame_is_intra_only(cm);
536
  MACROBLOCKD *xd = &x->e_mbd;
537
538
  // TODO(kyslov) Extend to 128x128
539
  assert(cm->seq_params->sb_size == BLOCK_64X64);
540
541
  av1_set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
542
543
  if (!is_key_frame) {
544
    MB_MODE_INFO *mi = xd->mi[0];
545
    const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, LAST_FRAME);
546
547
    assert(yv12 != NULL);
548
549
    av1_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
550
                         get_ref_scale_factors(cm, LAST_FRAME), 1);
551
    mi->ref_frame[0] = LAST_FRAME;
552
    mi->ref_frame[1] = NONE;
553
    mi->bsize = BLOCK_64X64;
554
    mi->mv[0].as_int = 0;
555
    mi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
556
557
    set_ref_ptrs(cm, xd, mi->ref_frame[0], mi->ref_frame[1]);
558
559
    xd->plane[0].dst.buf = x->est_pred;
560
    xd->plane[0].dst.stride = 64;
561
    av1_enc_build_inter_predictor_y(xd, mi_row, mi_col);
562
  } else {
563
#if CONFIG_AV1_HIGHBITDEPTH
564
    switch (xd->bd) {
565
      case 8: memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0])); break;
566
      case 10:
567
        memset(x->est_pred, 128 * 4, 64 * 64 * sizeof(x->est_pred[0]));
568
        break;
569
      case 12:
570
        memset(x->est_pred, 128 * 16, 64 * 64 * sizeof(x->est_pred[0]));
571
        break;
572
    }
573
#else
574
    memset(x->est_pred, 128, 64 * 64 * sizeof(x->est_pred[0]));
575
#endif  // CONFIG_VP9_HIGHBITDEPTH
576
  }
577
}
578
#endif  // CONFIG_RT_ML_PARTITIONING
579
580
0
#define AVG_CDF_WEIGHT_LEFT 3
581
0
#define AVG_CDF_WEIGHT_TOP_RIGHT 1
582
583
/*!\brief Encode a superblock (minimal RD search involved)
584
 *
585
 * \ingroup partition_search
586
 * Encodes the superblock by a pre-determined partition pattern, only minor
587
 * rd-based searches are allowed to adjust the initial pattern. It is only used
588
 * by realtime encoding.
589
 */
590
static inline void encode_nonrd_sb(AV1_COMP *cpi, ThreadData *td,
591
                                   TileDataEnc *tile_data, TokenExtra **tp,
592
                                   const int mi_row, const int mi_col,
593
0
                                   const int seg_skip) {
594
0
  AV1_COMMON *const cm = &cpi->common;
595
0
  MACROBLOCK *const x = &td->mb;
596
0
  const SPEED_FEATURES *const sf = &cpi->sf;
597
0
  const TileInfo *const tile_info = &tile_data->tile_info;
598
0
  MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
599
0
                      get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
600
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
601
0
  PC_TREE *const pc_root = td->pc_root;
602
603
0
#if !CONFIG_REALTIME_ONLY
604
0
  if (cm->delta_q_info.delta_q_present_flag) {
605
0
    const int num_planes = av1_num_planes(cm);
606
607
0
    setup_delta_q_nonrd(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
608
0
  }
609
0
#endif
610
#if CONFIG_RT_ML_PARTITIONING
611
  if (sf->part_sf.partition_search_type == ML_BASED_PARTITION) {
612
    RD_STATS dummy_rdc;
613
    get_estimated_pred(cpi, tile_info, x, mi_row, mi_col);
614
    av1_nonrd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col,
615
                             BLOCK_64X64, &dummy_rdc, 1, INT64_MAX, pc_root);
616
    return;
617
  }
618
#endif
619
  // Set the partition
620
0
  if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip ||
621
0
      (sf->rt_sf.use_fast_fixed_part && x->sb_force_fixed_part == 1 &&
622
0
       (!frame_is_intra_only(cm) &&
623
0
        (!cpi->ppi->use_svc ||
624
0
         !cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)))) {
625
    // set a fixed-size partition
626
0
    av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
627
0
    BLOCK_SIZE bsize_select = sf->part_sf.fixed_partition_size;
628
0
    if (sf->rt_sf.use_fast_fixed_part &&
629
0
        x->content_state_sb.source_sad_nonrd < kLowSad) {
630
0
      bsize_select = cm->seq_params->sb_size;
631
0
    }
632
0
    if (cpi->sf.rt_sf.skip_encoding_non_reference_slide_change &&
633
0
        cpi->rc.high_source_sad && cpi->ppi->rtc_ref.non_reference_frame) {
634
0
      bsize_select = cm->seq_params->sb_size;
635
0
      x->force_zeromv_skip_for_sb = 1;
636
0
    }
637
0
    const BLOCK_SIZE bsize = seg_skip ? sb_size : bsize_select;
638
0
    if (x->content_state_sb.source_sad_nonrd > kZeroSad)
639
0
      x->force_color_check_block_level = 1;
640
0
    av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
641
0
  } else if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
642
    // set a variance-based partition
643
0
    av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
644
0
    av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
645
0
  }
646
0
  assert(sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip ||
647
0
         sf->part_sf.partition_search_type == VAR_BASED_PARTITION);
648
0
  set_cb_offsets(td->mb.cb_offset, 0, 0);
649
650
  // Initialize the flag to skip cdef to 1.
651
0
  if (sf->rt_sf.skip_cdef_sb) {
652
0
    const int block64_in_sb = (sb_size == BLOCK_128X128) ? 2 : 1;
653
    // If 128x128 block is used, we need to set the flag for all 4 64x64 sub
654
    // "blocks".
655
0
    for (int r = 0; r < block64_in_sb; ++r) {
656
0
      for (int c = 0; c < block64_in_sb; ++c) {
657
0
        const int idx_in_sb =
658
0
            r * MI_SIZE_64X64 * cm->mi_params.mi_stride + c * MI_SIZE_64X64;
659
0
        if (mi[idx_in_sb]) mi[idx_in_sb]->cdef_strength = 1;
660
0
      }
661
0
    }
662
0
  }
663
664
#if CONFIG_COLLECT_COMPONENT_TIMING
665
  start_timing(cpi, nonrd_use_partition_time);
666
#endif
667
0
  av1_nonrd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
668
0
                          pc_root);
669
#if CONFIG_COLLECT_COMPONENT_TIMING
670
  end_timing(cpi, nonrd_use_partition_time);
671
#endif
672
0
}
673
674
// This function initializes the stats for encode_rd_sb.
675
static inline void init_encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
676
                                     const TileDataEnc *tile_data,
677
                                     SIMPLE_MOTION_DATA_TREE *sms_root,
678
                                     RD_STATS *rd_cost, int mi_row, int mi_col,
679
                                     int gather_tpl_data) {
680
  const AV1_COMMON *cm = &cpi->common;
681
  const TileInfo *tile_info = &tile_data->tile_info;
682
  MACROBLOCK *x = &td->mb;
683
684
  const SPEED_FEATURES *sf = &cpi->sf;
685
  const int use_simple_motion_search =
686
      (sf->part_sf.simple_motion_search_split ||
687
       sf->part_sf.simple_motion_search_prune_rect ||
688
       sf->part_sf.simple_motion_search_early_term_none ||
689
       sf->part_sf.ml_early_term_after_part_split_level) &&
690
      !frame_is_intra_only(cm);
691
  if (use_simple_motion_search) {
692
    av1_init_simple_motion_search_mvs_for_sb(cpi, tile_info, x, sms_root,
693
                                             mi_row, mi_col);
694
  }
695
696
#if !CONFIG_REALTIME_ONLY
697
  if (!(has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
698
        cpi->oxcf.gf_cfg.lag_in_frames == 0)) {
699
    init_ref_frame_space(cpi, td, mi_row, mi_col);
700
    x->sb_energy_level = 0;
701
    x->part_search_info.cnn_output_valid = 0;
702
    if (gather_tpl_data) {
703
      if (cpi->cb_delta_rdmult_enabled) {
704
        const int num_planes = av1_num_planes(cm);
705
        const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
706
        setup_delta_q(cpi, td, x, tile_info, mi_row, mi_col, num_planes);
707
        av1_tpl_rdmult_setup_sb(cpi, x, sb_size, mi_row, mi_col);
708
      }
709
710
      // TODO(jingning): revisit this function.
711
      if (cpi->oxcf.algo_cfg.enable_tpl_model && (0)) {
712
        adjust_rdmult_tpl_model(cpi, x, mi_row, mi_col);
713
      }
714
    }
715
  }
716
#else
717
  (void)tile_info;
718
  (void)mi_row;
719
  (void)mi_col;
720
  (void)gather_tpl_data;
721
#endif
722
723
  x->reuse_inter_pred = false;
724
  x->txfm_search_params.mode_eval_type = DEFAULT_EVAL;
725
  reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
726
  av1_zero(x->picked_ref_frames_mask);
727
  av1_invalid_rd_stats(rd_cost);
728
}
729
730
#if !CONFIG_REALTIME_ONLY
731
static void sb_qp_sweep_init_quantizers(AV1_COMP *cpi, ThreadData *td,
732
                                        const TileDataEnc *tile_data,
733
                                        SIMPLE_MOTION_DATA_TREE *sms_tree,
734
                                        RD_STATS *rd_cost, int mi_row,
735
0
                                        int mi_col, int delta_qp_ofs) {
736
0
  AV1_COMMON *const cm = &cpi->common;
737
0
  MACROBLOCK *const x = &td->mb;
738
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
739
0
  const TileInfo *tile_info = &tile_data->tile_info;
740
0
  const CommonModeInfoParams *const mi_params = &cm->mi_params;
741
0
  const DeltaQInfo *const delta_q_info = &cm->delta_q_info;
742
0
  assert(delta_q_info->delta_q_present_flag);
743
0
  const int delta_q_res = delta_q_info->delta_q_res;
744
745
0
  const SPEED_FEATURES *sf = &cpi->sf;
746
0
  const int use_simple_motion_search =
747
0
      (sf->part_sf.simple_motion_search_split ||
748
0
       sf->part_sf.simple_motion_search_prune_rect ||
749
0
       sf->part_sf.simple_motion_search_early_term_none ||
750
0
       sf->part_sf.ml_early_term_after_part_split_level) &&
751
0
      !frame_is_intra_only(cm);
752
0
  if (use_simple_motion_search) {
753
0
    av1_init_simple_motion_search_mvs_for_sb(cpi, tile_info, x, sms_tree,
754
0
                                             mi_row, mi_col);
755
0
  }
756
757
0
  int current_qindex = x->rdmult_cur_qindex + delta_qp_ofs;
758
759
0
  MACROBLOCKD *const xd = &x->e_mbd;
760
0
  current_qindex = av1_adjust_q_from_delta_q_res(
761
0
      delta_q_res, xd->current_base_qindex, current_qindex);
762
763
0
  x->delta_qindex = current_qindex - cm->quant_params.base_qindex;
764
765
0
  av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
766
0
  xd->mi[0]->current_qindex = current_qindex;
767
0
  av1_init_plane_quantizers(cpi, x, xd->mi[0]->segment_id, 0);
768
769
  // keep track of any non-zero delta-q used
770
0
  td->deltaq_used |= (x->delta_qindex != 0);
771
772
0
  if (cpi->oxcf.tool_cfg.enable_deltalf_mode) {
773
0
    const int delta_lf_res = delta_q_info->delta_lf_res;
774
0
    const int lfmask = ~(delta_lf_res - 1);
775
0
    const int delta_lf_from_base =
776
0
        ((x->delta_qindex / 4 + delta_lf_res / 2) & lfmask);
777
0
    const int8_t delta_lf =
778
0
        (int8_t)clamp(delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
779
0
    const int frame_lf_count =
780
0
        av1_num_planes(cm) > 1 ? FRAME_LF_COUNT : FRAME_LF_COUNT - 2;
781
0
    const int mib_size = cm->seq_params->mib_size;
782
783
    // pre-set the delta lf for loop filter. Note that this value is set
784
    // before mi is assigned for each block in current superblock
785
0
    for (int j = 0; j < AOMMIN(mib_size, mi_params->mi_rows - mi_row); j++) {
786
0
      for (int k = 0; k < AOMMIN(mib_size, mi_params->mi_cols - mi_col); k++) {
787
0
        const int grid_idx = get_mi_grid_idx(mi_params, mi_row + j, mi_col + k);
788
0
        mi_params->mi_alloc[grid_idx].delta_lf_from_base = delta_lf;
789
0
        for (int lf_id = 0; lf_id < frame_lf_count; ++lf_id) {
790
0
          mi_params->mi_alloc[grid_idx].delta_lf[lf_id] = delta_lf;
791
0
        }
792
0
      }
793
0
    }
794
0
  }
795
796
0
  x->reuse_inter_pred = false;
797
0
  x->txfm_search_params.mode_eval_type = DEFAULT_EVAL;
798
0
  reset_mb_rd_record(x->txfm_search_info.mb_rd_record);
799
0
  av1_zero(x->picked_ref_frames_mask);
800
0
  av1_invalid_rd_stats(rd_cost);
801
0
}
802
803
static int sb_qp_sweep(AV1_COMP *const cpi, ThreadData *td,
804
                       TileDataEnc *tile_data, TokenExtra **tp, int mi_row,
805
                       int mi_col, BLOCK_SIZE bsize,
806
                       SIMPLE_MOTION_DATA_TREE *sms_tree,
807
0
                       SB_FIRST_PASS_STATS *sb_org_stats) {
808
0
  AV1_COMMON *const cm = &cpi->common;
809
0
  MACROBLOCK *const x = &td->mb;
810
0
  RD_STATS rdc_winner, cur_rdc;
811
0
  av1_invalid_rd_stats(&rdc_winner);
812
813
0
  int best_qindex = td->mb.rdmult_delta_qindex;
814
0
  const int start = cm->current_frame.frame_type == KEY_FRAME ? -20 : -12;
815
0
  const int end = cm->current_frame.frame_type == KEY_FRAME ? 20 : 12;
816
0
  const int step = cm->delta_q_info.delta_q_res;
817
818
0
  for (int sweep_qp_delta = start; sweep_qp_delta <= end;
819
0
       sweep_qp_delta += step) {
820
0
    sb_qp_sweep_init_quantizers(cpi, td, tile_data, sms_tree, &cur_rdc, mi_row,
821
0
                                mi_col, sweep_qp_delta);
822
823
0
    const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
824
0
    const int backup_current_qindex =
825
0
        cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
826
827
0
    av1_reset_mbmi(&cm->mi_params, bsize, mi_row, mi_col);
828
0
    av1_restore_sb_state(sb_org_stats, cpi, td, tile_data, mi_row, mi_col);
829
0
    cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex = backup_current_qindex;
830
831
0
    td->pc_root = av1_alloc_pc_tree_node(bsize);
832
0
    if (!td->pc_root)
833
0
      aom_internal_error(x->e_mbd.error_info, AOM_CODEC_MEM_ERROR,
834
0
                         "Failed to allocate PC_TREE");
835
0
    av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, bsize,
836
0
                          &cur_rdc, cur_rdc, td->pc_root, sms_tree, NULL,
837
0
                          SB_DRY_PASS, NULL);
838
839
0
    if ((rdc_winner.rdcost > cur_rdc.rdcost) ||
840
0
        (abs(sweep_qp_delta) < abs(best_qindex - x->rdmult_delta_qindex) &&
841
0
         rdc_winner.rdcost == cur_rdc.rdcost)) {
842
0
      rdc_winner = cur_rdc;
843
0
      best_qindex = x->rdmult_delta_qindex + sweep_qp_delta;
844
0
    }
845
0
  }
846
847
0
  return best_qindex;
848
0
}
849
#endif  //! CONFIG_REALTIME_ONLY
850
851
/*!\brief Encode a superblock (RD-search-based)
852
 *
853
 * \ingroup partition_search
854
 * Conducts partition search for a superblock, based on rate-distortion costs,
855
 * from scratch or adjusting from a pre-calculated partition pattern.
856
 */
857
static inline void encode_rd_sb(AV1_COMP *cpi, ThreadData *td,
858
                                TileDataEnc *tile_data, TokenExtra **tp,
859
                                const int mi_row, const int mi_col,
860
0
                                const int seg_skip) {
861
0
  AV1_COMMON *const cm = &cpi->common;
862
0
  MACROBLOCK *const x = &td->mb;
863
0
  MACROBLOCKD *const xd = &x->e_mbd;
864
0
  const SPEED_FEATURES *const sf = &cpi->sf;
865
0
  const TileInfo *const tile_info = &tile_data->tile_info;
866
0
  MB_MODE_INFO **mi = cm->mi_params.mi_grid_base +
867
0
                      get_mi_grid_idx(&cm->mi_params, mi_row, mi_col);
868
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
869
0
  const int num_planes = av1_num_planes(cm);
870
0
  int dummy_rate;
871
0
  int64_t dummy_dist;
872
0
  RD_STATS dummy_rdc;
873
0
  SIMPLE_MOTION_DATA_TREE *const sms_root = td->sms_root;
874
875
#if CONFIG_REALTIME_ONLY
876
  (void)seg_skip;
877
#endif  // CONFIG_REALTIME_ONLY
878
879
0
  init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row, mi_col,
880
0
                    1);
881
882
  // Encode the superblock
883
0
  if (sf->part_sf.partition_search_type == VAR_BASED_PARTITION) {
884
    // partition search starting from a variance-based partition
885
0
    av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
886
0
    av1_choose_var_based_partitioning(cpi, tile_info, td, x, mi_row, mi_col);
887
888
#if CONFIG_COLLECT_COMPONENT_TIMING
889
    start_timing(cpi, rd_use_partition_time);
890
#endif
891
0
    td->pc_root = av1_alloc_pc_tree_node(sb_size);
892
0
    if (!td->pc_root)
893
0
      aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
894
0
                         "Failed to allocate PC_TREE");
895
0
    av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
896
0
                         &dummy_rate, &dummy_dist, 1, td->pc_root);
897
0
    av1_free_pc_tree_recursive(td->pc_root, num_planes, 0, 0,
898
0
                               sf->part_sf.partition_search_type);
899
0
    td->pc_root = NULL;
900
#if CONFIG_COLLECT_COMPONENT_TIMING
901
    end_timing(cpi, rd_use_partition_time);
902
#endif
903
0
  }
904
0
#if !CONFIG_REALTIME_ONLY
905
0
  else if (sf->part_sf.partition_search_type == FIXED_PARTITION || seg_skip) {
906
    // partition search by adjusting a fixed-size partition
907
0
    av1_set_offsets(cpi, tile_info, x, mi_row, mi_col, sb_size);
908
0
    const BLOCK_SIZE bsize =
909
0
        seg_skip ? sb_size : sf->part_sf.fixed_partition_size;
910
0
    av1_set_fixed_partitioning(cpi, tile_info, mi, mi_row, mi_col, bsize);
911
0
    td->pc_root = av1_alloc_pc_tree_node(sb_size);
912
0
    if (!td->pc_root)
913
0
      aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
914
0
                         "Failed to allocate PC_TREE");
915
0
    av1_rd_use_partition(cpi, td, tile_data, mi, tp, mi_row, mi_col, sb_size,
916
0
                         &dummy_rate, &dummy_dist, 1, td->pc_root);
917
0
    av1_free_pc_tree_recursive(td->pc_root, num_planes, 0, 0,
918
0
                               sf->part_sf.partition_search_type);
919
0
    td->pc_root = NULL;
920
0
  } else {
921
    // The most exhaustive recursive partition search
922
0
    SuperBlockEnc *sb_enc = &x->sb_enc;
923
    // No stats for overlay frames. Exclude key frame.
924
0
    av1_get_tpl_stats_sb(cpi, sb_size, mi_row, mi_col, sb_enc);
925
926
    // Reset the tree for simple motion search data
927
0
    av1_reset_simple_motion_tree_partition(sms_root, sb_size);
928
929
#if CONFIG_COLLECT_COMPONENT_TIMING
930
    start_timing(cpi, rd_pick_partition_time);
931
#endif
932
933
    // Estimate the maximum square partition block size, which will be used
934
    // as the starting block size for partitioning the sb
935
0
    set_max_min_partition_size(sb_enc, cpi, x, sf, sb_size, mi_row, mi_col);
936
937
    // The superblock can be searched only once, or twice consecutively for
938
    // better quality. Note that the meaning of passes here is different from
939
    // the general concept of 1-pass/2-pass encoders.
940
0
    const int num_passes =
941
0
        cpi->oxcf.unit_test_cfg.sb_multipass_unit_test ? 2 : 1;
942
943
0
    if (cpi->oxcf.sb_qp_sweep &&
944
0
        !(has_no_stats_stage(cpi) && cpi->oxcf.mode == REALTIME &&
945
0
          cpi->oxcf.gf_cfg.lag_in_frames == 0) &&
946
0
        cm->delta_q_info.delta_q_present_flag) {
947
0
      AOM_CHECK_MEM_ERROR(
948
0
          x->e_mbd.error_info, td->mb.sb_stats_cache,
949
0
          (SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_stats_cache)));
950
0
      av1_backup_sb_state(td->mb.sb_stats_cache, cpi, td, tile_data, mi_row,
951
0
                          mi_col);
952
0
      assert(x->rdmult_delta_qindex == x->delta_qindex);
953
954
0
      const int best_qp_diff =
955
0
          sb_qp_sweep(cpi, td, tile_data, tp, mi_row, mi_col, sb_size, sms_root,
956
0
                      td->mb.sb_stats_cache) -
957
0
          x->rdmult_delta_qindex;
958
959
0
      sb_qp_sweep_init_quantizers(cpi, td, tile_data, sms_root, &dummy_rdc,
960
0
                                  mi_row, mi_col, best_qp_diff);
961
962
0
      const int alloc_mi_idx = get_alloc_mi_idx(&cm->mi_params, mi_row, mi_col);
963
0
      const int backup_current_qindex =
964
0
          cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex;
965
966
0
      av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
967
0
      av1_restore_sb_state(td->mb.sb_stats_cache, cpi, td, tile_data, mi_row,
968
0
                           mi_col);
969
970
0
      cm->mi_params.mi_alloc[alloc_mi_idx].current_qindex =
971
0
          backup_current_qindex;
972
0
      aom_free(td->mb.sb_stats_cache);
973
0
      td->mb.sb_stats_cache = NULL;
974
0
    }
975
0
    if (num_passes == 1) {
976
#if CONFIG_PARTITION_SEARCH_ORDER
977
      if (cpi->ext_part_controller.ready && !frame_is_intra_only(cm)) {
978
        av1_reset_part_sf(&cpi->sf.part_sf);
979
        av1_reset_sf_for_ext_part(cpi);
980
        RD_STATS this_rdc;
981
        av1_rd_partition_search(cpi, td, tile_data, tp, sms_root, mi_row,
982
                                mi_col, sb_size, &this_rdc);
983
      } else {
984
        td->pc_root = av1_alloc_pc_tree_node(sb_size);
985
        if (!td->pc_root)
986
          aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
987
                             "Failed to allocate PC_TREE");
988
        av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
989
                              &dummy_rdc, dummy_rdc, td->pc_root, sms_root,
990
                              NULL, SB_SINGLE_PASS, NULL);
991
      }
992
#else
993
0
      td->pc_root = av1_alloc_pc_tree_node(sb_size);
994
0
      if (!td->pc_root)
995
0
        aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
996
0
                           "Failed to allocate PC_TREE");
997
0
      av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
998
0
                            &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL,
999
0
                            SB_SINGLE_PASS, NULL);
1000
0
#endif  // CONFIG_PARTITION_SEARCH_ORDER
1001
0
    } else {
1002
      // First pass
1003
0
      AOM_CHECK_MEM_ERROR(
1004
0
          x->e_mbd.error_info, td->mb.sb_fp_stats,
1005
0
          (SB_FIRST_PASS_STATS *)aom_malloc(sizeof(*td->mb.sb_fp_stats)));
1006
0
      av1_backup_sb_state(td->mb.sb_fp_stats, cpi, td, tile_data, mi_row,
1007
0
                          mi_col);
1008
0
      td->pc_root = av1_alloc_pc_tree_node(sb_size);
1009
0
      if (!td->pc_root)
1010
0
        aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
1011
0
                           "Failed to allocate PC_TREE");
1012
0
      av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
1013
0
                            &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL,
1014
0
                            SB_DRY_PASS, NULL);
1015
1016
      // Second pass
1017
0
      init_encode_rd_sb(cpi, td, tile_data, sms_root, &dummy_rdc, mi_row,
1018
0
                        mi_col, 0);
1019
0
      av1_reset_mbmi(&cm->mi_params, sb_size, mi_row, mi_col);
1020
0
      av1_reset_simple_motion_tree_partition(sms_root, sb_size);
1021
1022
0
      av1_restore_sb_state(td->mb.sb_fp_stats, cpi, td, tile_data, mi_row,
1023
0
                           mi_col);
1024
1025
0
      td->pc_root = av1_alloc_pc_tree_node(sb_size);
1026
0
      if (!td->pc_root)
1027
0
        aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
1028
0
                           "Failed to allocate PC_TREE");
1029
0
      av1_rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
1030
0
                            &dummy_rdc, dummy_rdc, td->pc_root, sms_root, NULL,
1031
0
                            SB_WET_PASS, NULL);
1032
0
      aom_free(td->mb.sb_fp_stats);
1033
0
      td->mb.sb_fp_stats = NULL;
1034
0
    }
1035
1036
    // Reset to 0 so that it wouldn't be used elsewhere mistakenly.
1037
0
    sb_enc->tpl_data_count = 0;
1038
#if CONFIG_COLLECT_COMPONENT_TIMING
1039
    end_timing(cpi, rd_pick_partition_time);
1040
#endif
1041
0
  }
1042
0
#endif  // !CONFIG_REALTIME_ONLY
1043
1044
  // Update the inter rd model
1045
  // TODO(angiebird): Let inter_mode_rd_model_estimation support multi-tile.
1046
0
  if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1 &&
1047
0
      cm->tiles.cols == 1 && cm->tiles.rows == 1) {
1048
0
    av1_inter_mode_data_fit(tile_data, x->rdmult);
1049
0
  }
1050
0
}
1051
1052
// Check if the cost update of symbols mode, coeff and dv are tile or off.
1053
static inline int is_mode_coeff_dv_upd_freq_tile_or_off(
1054
0
    const AV1_COMP *const cpi) {
1055
0
  const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf;
1056
1057
0
  return (inter_sf->coeff_cost_upd_level <= INTERNAL_COST_UPD_TILE &&
1058
0
          inter_sf->mode_cost_upd_level <= INTERNAL_COST_UPD_TILE &&
1059
0
          cpi->sf.intra_sf.dv_cost_upd_level <= INTERNAL_COST_UPD_TILE);
1060
0
}
1061
1062
// When row-mt is enabled and cost update frequencies are set to off/tile,
1063
// processing of current SB can start even before processing of top-right SB
1064
// is finished. This function checks if it is sufficient to wait for top SB
1065
// to finish processing before current SB starts processing.
1066
0
static inline int delay_wait_for_top_right_sb(const AV1_COMP *const cpi) {
1067
0
  const MODE mode = cpi->oxcf.mode;
1068
0
  if (mode == GOOD) return 0;
1069
1070
0
  if (mode == ALLINTRA)
1071
0
    return is_mode_coeff_dv_upd_freq_tile_or_off(cpi);
1072
0
  else if (mode == REALTIME)
1073
0
    return (is_mode_coeff_dv_upd_freq_tile_or_off(cpi) &&
1074
0
            cpi->sf.inter_sf.mv_cost_upd_level <= INTERNAL_COST_UPD_TILE);
1075
0
  else
1076
0
    return 0;
1077
0
}
1078
1079
/*!\brief Calculate source SAD at superblock level using 64x64 block source SAD
1080
 *
1081
 * \ingroup partition_search
1082
 * \callgraph
1083
 * \callergraph
1084
 */
1085
static inline uint64_t get_sb_source_sad(const AV1_COMP *cpi, int mi_row,
1086
0
                                         int mi_col) {
1087
0
  if (cpi->src_sad_blk_64x64 == NULL) return UINT64_MAX;
1088
1089
0
  const AV1_COMMON *const cm = &cpi->common;
1090
0
  const int blk_64x64_in_mis = (cm->seq_params->sb_size == BLOCK_128X128)
1091
0
                                   ? (cm->seq_params->mib_size >> 1)
1092
0
                                   : cm->seq_params->mib_size;
1093
0
  const int num_blk_64x64_cols =
1094
0
      (cm->mi_params.mi_cols + blk_64x64_in_mis - 1) / blk_64x64_in_mis;
1095
0
  const int num_blk_64x64_rows =
1096
0
      (cm->mi_params.mi_rows + blk_64x64_in_mis - 1) / blk_64x64_in_mis;
1097
0
  const int blk_64x64_col_index = mi_col / blk_64x64_in_mis;
1098
0
  const int blk_64x64_row_index = mi_row / blk_64x64_in_mis;
1099
0
  uint64_t curr_sb_sad = UINT64_MAX;
1100
  // Avoid the border as sad_blk_64x64 may not be set for the border
1101
  // in the scene detection.
1102
0
  if ((blk_64x64_row_index >= num_blk_64x64_rows - 1) ||
1103
0
      (blk_64x64_col_index >= num_blk_64x64_cols - 1)) {
1104
0
    return curr_sb_sad;
1105
0
  }
1106
0
  const uint64_t *const src_sad_blk_64x64_data =
1107
0
      &cpi->src_sad_blk_64x64[blk_64x64_col_index +
1108
0
                              blk_64x64_row_index * num_blk_64x64_cols];
1109
0
  if (cm->seq_params->sb_size == BLOCK_128X128) {
1110
    // Calculate SB source SAD by accumulating source SAD of 64x64 blocks in the
1111
    // superblock
1112
0
    curr_sb_sad = src_sad_blk_64x64_data[0] + src_sad_blk_64x64_data[1] +
1113
0
                  src_sad_blk_64x64_data[num_blk_64x64_cols] +
1114
0
                  src_sad_blk_64x64_data[num_blk_64x64_cols + 1];
1115
0
  } else if (cm->seq_params->sb_size == BLOCK_64X64) {
1116
0
    curr_sb_sad = src_sad_blk_64x64_data[0];
1117
0
  }
1118
0
  return curr_sb_sad;
1119
0
}
1120
1121
/*!\brief Determine whether grading content can be skipped based on sad stat
1122
 *
1123
 * \ingroup partition_search
1124
 * \callgraph
1125
 * \callergraph
1126
 */
1127
static inline bool is_calc_src_content_needed(AV1_COMP *cpi,
1128
                                              MACROBLOCK *const x, int mi_row,
1129
0
                                              int mi_col) {
1130
0
  if (cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1)
1131
0
    return true;
1132
0
  const uint64_t curr_sb_sad = get_sb_source_sad(cpi, mi_row, mi_col);
1133
0
  if (curr_sb_sad == UINT64_MAX) return true;
1134
0
  if (curr_sb_sad == 0) {
1135
0
    x->content_state_sb.source_sad_nonrd = kZeroSad;
1136
0
    return false;
1137
0
  }
1138
0
  AV1_COMMON *const cm = &cpi->common;
1139
0
  bool do_calc_src_content = true;
1140
1141
0
  if (cpi->oxcf.speed < 9) return do_calc_src_content;
1142
1143
  // TODO(yunqing): Tune/validate the thresholds for 128x128 SB size.
1144
0
  if (AOMMIN(cm->width, cm->height) < 360) {
1145
    // Derive Average 64x64 block source SAD from SB source SAD
1146
0
    const uint64_t avg_64x64_blk_sad =
1147
0
        (cm->seq_params->sb_size == BLOCK_128X128) ? ((curr_sb_sad + 2) >> 2)
1148
0
                                                   : curr_sb_sad;
1149
1150
    // The threshold is determined based on kLowSad and kHighSad threshold and
1151
    // test results.
1152
0
    uint64_t thresh_low = 15000;
1153
0
    uint64_t thresh_high = 40000;
1154
1155
0
    if (cpi->sf.rt_sf.increase_source_sad_thresh) {
1156
0
      thresh_low = thresh_low << 1;
1157
0
      thresh_high = thresh_high << 1;
1158
0
    }
1159
1160
0
    if (avg_64x64_blk_sad > thresh_low && avg_64x64_blk_sad < thresh_high) {
1161
0
      do_calc_src_content = false;
1162
      // Note: set x->content_state_sb.source_sad_rd as well if this is extended
1163
      // to RTC rd path.
1164
0
      x->content_state_sb.source_sad_nonrd = kMedSad;
1165
0
    }
1166
0
  }
1167
1168
0
  return do_calc_src_content;
1169
0
}
1170
1171
/*!\brief Determine whether grading content is needed based on sf and frame stat
1172
 *
1173
 * \ingroup partition_search
1174
 * \callgraph
1175
 * \callergraph
1176
 */
1177
// TODO(any): consolidate sfs to make interface cleaner
1178
static inline void grade_source_content_sb(AV1_COMP *cpi, MACROBLOCK *const x,
1179
                                           TileDataEnc *tile_data, int mi_row,
1180
0
                                           int mi_col) {
1181
0
  AV1_COMMON *const cm = &cpi->common;
1182
0
  if (cm->current_frame.frame_type == KEY_FRAME ||
1183
0
      (cpi->ppi->use_svc &&
1184
0
       cpi->svc.layer_context[cpi->svc.temporal_layer_id].is_key_frame)) {
1185
0
    assert(x->content_state_sb.source_sad_nonrd == kMedSad);
1186
0
    assert(x->content_state_sb.source_sad_rd == kMedSad);
1187
0
    return;
1188
0
  }
1189
0
  bool calc_src_content = false;
1190
1191
0
  if (cpi->sf.rt_sf.source_metrics_sb_nonrd) {
1192
0
    if (!cpi->sf.rt_sf.check_scene_detection || cpi->rc.frame_source_sad > 0) {
1193
0
      calc_src_content = is_calc_src_content_needed(cpi, x, mi_row, mi_col);
1194
0
    } else {
1195
0
      x->content_state_sb.source_sad_nonrd = kZeroSad;
1196
0
    }
1197
0
  } else if ((cpi->sf.rt_sf.var_part_based_on_qidx >= 1) &&
1198
0
             (cm->width * cm->height <= 352 * 288)) {
1199
0
    if (cpi->rc.frame_source_sad > 0)
1200
0
      calc_src_content = true;
1201
0
    else
1202
0
      x->content_state_sb.source_sad_rd = kZeroSad;
1203
0
  }
1204
0
  if (calc_src_content)
1205
0
    av1_source_content_sb(cpi, x, tile_data, mi_row, mi_col);
1206
0
}
1207
1208
0
static uint8_t get_sb_segment_id(const AV1_COMP *cpi, int mi_row, int mi_col) {
1209
0
  const AV1_COMMON *const cm = &cpi->common;
1210
0
  const struct segmentation *const seg = &cm->seg;
1211
0
  const uint8_t *const map =
1212
0
      seg->update_map ? cpi->enc_seg.map : cm->last_frame_seg_map;
1213
0
  if (!map) return 0;
1214
0
  return get_segment_id(&cm->mi_params, map, cm->seq_params->sb_size, mi_row,
1215
0
                        mi_col);
1216
0
}
1217
1218
// Returns true when skip segment superblocks of this frame may be copied from
1219
// their reference before they are coded.
1220
0
static bool can_copy_skip_sbs(const AV1_COMP *cpi) {
1221
0
  const AV1_COMMON *const cm = &cpi->common;
1222
0
  if (!cm->seg.enabled || frame_is_intra_only(cm) ||
1223
0
      !cpi->sf.rt_sf.use_nonrd_pick_mode)
1224
0
    return false;
1225
1226
  // Segmentation without a skip segment, like cyclic refresh, has nothing to
1227
  // copy, so this saves the segment lookups of the whole frame.
1228
0
  for (int i = 0; i < MAX_SEGMENTS; ++i) {
1229
0
    if (segfeature_active(&cm->seg, i, SEG_LVL_SKIP)) return true;
1230
0
  }
1231
0
  return false;
1232
0
}
1233
1234
// Returns the reference that a superblock in this segment predicts from with
1235
// a plain copy, or NONE_FRAME when it needs the normal prediction build.
1236
static MV_REFERENCE_FRAME get_skip_sb_copy_ref(const AV1_COMMON *cm,
1237
0
                                               uint8_t segment_id) {
1238
0
  const struct segmentation *const seg = &cm->seg;
1239
0
  if (!segfeature_active(seg, segment_id, SEG_LVL_SKIP)) return NONE_FRAME;
1240
1241
  // Same reference as av1_nonrd_pick_inter_mode_sb_seg_skip().
1242
0
  const MV_REFERENCE_FRAME ref =
1243
0
      segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)
1244
0
          ? (MV_REFERENCE_FRAME)get_segdata(seg, segment_id, SEG_LVL_REF_FRAME)
1245
0
          : LAST_FRAME;
1246
0
  if (ref <= INTRA_FRAME || cm->global_motion[ref].wmtype != IDENTITY)
1247
0
    return NONE_FRAME;
1248
1249
0
  const YV12_BUFFER_CONFIG *const ref_buf = get_ref_frame_yv12_buf(cm, ref);
1250
0
  if (!ref_buf || (ref_buf->flags & YV12_FLAG_HIGHBITDEPTH) ||
1251
0
      av1_is_scaled(get_ref_scale_factors_const(cm, ref)))
1252
0
    return NONE_FRAME;
1253
0
  return ref;
1254
0
}
1255
1256
// Copies the reference into the superblocks from mi_col_start to mi_col_end
1257
// of one superblock row, inside the frame area.
1258
static void copy_sb_span(const AV1_COMMON *cm, MV_REFERENCE_FRAME ref,
1259
0
                         int mi_row, int mi_col_start, int mi_col_end) {
1260
0
  const YV12_BUFFER_CONFIG *const src = get_ref_frame_yv12_buf(cm, ref);
1261
0
  YV12_BUFFER_CONFIG *const dst = &cm->cur_frame->buf;
1262
0
  const int x0 = mi_col_start * MI_SIZE;
1263
0
  const int x1 = AOMMIN(mi_col_end, cm->mi_params.mi_cols) * MI_SIZE;
1264
0
  const int y0 = mi_row * MI_SIZE;
1265
0
  const int y1 =
1266
0
      AOMMIN(mi_row + cm->seq_params->mib_size, cm->mi_params.mi_rows) *
1267
0
      MI_SIZE;
1268
0
  aom_yv12_partial_coloc_copy_y(src, dst, x0, x1, y0, y1);
1269
0
  if (av1_num_planes(cm) == 1) return;
1270
1271
0
  const int ss_x = cm->seq_params->subsampling_x;
1272
0
  const int ss_y = cm->seq_params->subsampling_y;
1273
0
  aom_yv12_partial_coloc_copy_u(src, dst, x0 >> ss_x, x1 >> ss_x, y0 >> ss_y,
1274
0
                                y1 >> ss_y);
1275
0
  aom_yv12_partial_coloc_copy_v(src, dst, x0 >> ss_x, x1 >> ss_x, y0 >> ss_y,
1276
0
                                y1 >> ss_y);
1277
0
}
1278
1279
// Gets the segment id of each superblock of a tile row. The map of a
1280
// superblock only changes while it is coded, so the ids hold for the row.
1281
static void get_sb_segment_ids_of_row(const AV1_COMP *cpi,
1282
                                      const TileInfo *tile_info, int mi_row,
1283
0
                                      uint8_t *segment_ids) {
1284
0
  const int mib_size = cpi->common.seq_params->mib_size;
1285
0
  for (int mi_col = tile_info->mi_col_start; mi_col < tile_info->mi_col_end;
1286
0
       mi_col += mib_size) {
1287
0
    *segment_ids++ = get_sb_segment_id(cpi, mi_row, mi_col);
1288
0
  }
1289
0
}
1290
1291
// Fills the skip segment superblocks of a row from their reference before the
1292
// row is coded. Wide row copies are much faster than copying every 64x64 block
1293
// plane by plane, so encode_superblock() then skips their prediction.
1294
static void copy_skip_sbs_of_row(const AV1_COMP *cpi, const TileInfo *tile_info,
1295
0
                                 int mi_row, const uint8_t *segment_ids) {
1296
0
  if (!can_copy_skip_sbs(cpi)) return;
1297
1298
0
  const AV1_COMMON *const cm = &cpi->common;
1299
0
  const int mib_size = cm->seq_params->mib_size;
1300
0
  int span_start = -1;
1301
0
  MV_REFERENCE_FRAME span_ref = NONE_FRAME;
1302
1303
0
  for (int mi_col = tile_info->mi_col_start, sb_col = 0;;
1304
0
       mi_col += mib_size, ++sb_col) {
1305
0
    const int in_tile = mi_col < tile_info->mi_col_end;
1306
0
    const MV_REFERENCE_FRAME ref =
1307
0
        in_tile ? get_skip_sb_copy_ref(cm, segment_ids[sb_col]) : NONE_FRAME;
1308
0
    if (span_start >= 0 && ref != span_ref) {
1309
0
      copy_sb_span(cm, span_ref, mi_row, span_start, mi_col);
1310
0
      span_start = -1;
1311
0
    }
1312
0
    if (span_start < 0 && ref != NONE_FRAME) {
1313
0
      span_start = mi_col;
1314
0
      span_ref = ref;
1315
0
    }
1316
0
    if (!in_tile) break;
1317
0
  }
1318
0
}
1319
1320
/*!\brief Encode a superblock row by breaking it into superblocks
1321
 *
1322
 * \ingroup partition_search
1323
 * \callgraph
1324
 * \callergraph
1325
 * Do partition and mode search for an sb row: one row of superblocks filling up
1326
 * the width of the current tile.
1327
 */
1328
static inline void encode_sb_row(AV1_COMP *cpi, ThreadData *td,
1329
                                 TileDataEnc *tile_data, int mi_row,
1330
0
                                 TokenExtra **tp) {
1331
0
  AV1_COMMON *const cm = &cpi->common;
1332
0
  const TileInfo *const tile_info = &tile_data->tile_info;
1333
0
  MultiThreadInfo *const mt_info = &cpi->mt_info;
1334
0
  AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
1335
0
  AV1EncRowMultiThreadSync *const row_mt_sync = &tile_data->row_mt_sync;
1336
0
  bool row_mt_enabled = mt_info->row_mt_enabled;
1337
0
  MACROBLOCK *const x = &td->mb;
1338
0
  MACROBLOCKD *const xd = &x->e_mbd;
1339
0
  const int sb_cols_in_tile = av1_get_sb_cols_in_tile(cm, tile_info);
1340
0
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
1341
0
  const int mib_size = cm->seq_params->mib_size;
1342
0
  const int mib_size_log2 = cm->seq_params->mib_size_log2;
1343
0
  const int sb_row = (mi_row - tile_info->mi_row_start) >> mib_size_log2;
1344
0
  const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
1345
1346
#if CONFIG_COLLECT_COMPONENT_TIMING
1347
  start_timing(cpi, encode_sb_row_time);
1348
#endif
1349
1350
  // Initialize the left context for the new SB row
1351
0
  av1_zero_left_context(xd);
1352
1353
  // Reset delta for quantizer and loof filters at the beginning of every tile
1354
0
  if (mi_row == tile_info->mi_row_start || row_mt_enabled) {
1355
0
    if (cpi->cb_delta_rdmult_enabled)
1356
0
      xd->current_base_qindex = cm->quant_params.base_qindex;
1357
0
    if (cm->delta_q_info.delta_lf_present_flag) {
1358
0
      av1_reset_loop_filter_delta(xd, av1_num_planes(cm));
1359
0
    }
1360
0
  }
1361
1362
0
  reset_thresh_freq_fact(x);
1363
1364
0
  const struct segmentation *const seg = &cm->seg;
1365
0
  uint8_t sb_segment_ids[MAX_TILE_WIDTH >> MIN_SB_SIZE_LOG2] = { 0 };
1366
0
  assert(sb_cols_in_tile <= (int)sizeof(sb_segment_ids));
1367
0
  if (seg->enabled) {
1368
0
    get_sb_segment_ids_of_row(cpi, tile_info, mi_row, sb_segment_ids);
1369
0
    copy_skip_sbs_of_row(cpi, tile_info, mi_row, sb_segment_ids);
1370
0
  }
1371
1372
  // Code each SB in the row
1373
0
  for (int mi_col = tile_info->mi_col_start, sb_col_in_tile = 0;
1374
0
       mi_col < tile_info->mi_col_end; mi_col += mib_size, sb_col_in_tile++) {
1375
    // In realtime/allintra mode and when frequency of cost updates is off/tile,
1376
    // wait for the top superblock to finish encoding. Otherwise, wait for the
1377
    // top-right superblock to finish encoding.
1378
0
    enc_row_mt->sync_read_ptr(
1379
0
        row_mt_sync, sb_row, sb_col_in_tile - delay_wait_for_top_right_sb(cpi));
1380
1381
0
#if CONFIG_MULTITHREAD
1382
0
    if (row_mt_enabled) {
1383
0
      pthread_mutex_lock(enc_row_mt->mutex_);
1384
0
      const bool row_mt_exit = enc_row_mt->row_mt_exit;
1385
0
      pthread_mutex_unlock(enc_row_mt->mutex_);
1386
      // Exit in case any worker has encountered an error.
1387
0
      if (row_mt_exit) return;
1388
0
    }
1389
0
#endif
1390
1391
0
    const int update_cdf = tile_data->allow_update_cdf && row_mt_enabled;
1392
0
    if (update_cdf && (tile_info->mi_row_start != mi_row)) {
1393
0
      if ((tile_info->mi_col_start == mi_col)) {
1394
        // restore frame context at the 1st column sb
1395
0
        *xd->tile_ctx = *x->row_ctx;
1396
0
      } else {
1397
        // update context
1398
0
        int wt_left = AVG_CDF_WEIGHT_LEFT;
1399
0
        int wt_tr = AVG_CDF_WEIGHT_TOP_RIGHT;
1400
0
        if (tile_info->mi_col_end > (mi_col + mib_size))
1401
0
          av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile,
1402
0
                              wt_left, wt_tr);
1403
0
        else
1404
0
          av1_avg_cdf_symbols(xd->tile_ctx, x->row_ctx + sb_col_in_tile - 1,
1405
0
                              wt_left, wt_tr);
1406
0
      }
1407
0
    }
1408
1409
    // Update the rate cost tables for some symbols
1410
0
    av1_set_cost_upd_freq(cpi, td, tile_info, mi_row, mi_col);
1411
1412
    // Reset color coding related parameters
1413
0
    av1_zero(x->color_sensitivity_sb);
1414
0
    av1_zero(x->color_sensitivity_sb_g);
1415
0
    av1_zero(x->color_sensitivity_sb_alt);
1416
0
    av1_zero(x->color_sensitivity);
1417
0
    x->content_state_sb.source_sad_nonrd = kMedSad;
1418
0
    x->content_state_sb.source_sad_rd = kMedSad;
1419
0
    x->content_state_sb.lighting_change = 0;
1420
0
    x->content_state_sb.low_sumdiff = 0;
1421
0
    x->force_zeromv_skip_for_sb = 0;
1422
0
    x->sb_me_block = 0;
1423
0
    x->sb_me_partition = 0;
1424
0
    x->sb_me_mv.as_int = 0;
1425
0
    x->sb_force_fixed_part = 1;
1426
    // Superblocks coded without the variance partitioning must not use the
1427
    // low variance flags of an earlier superblock.
1428
0
    av1_zero(x->part_search_info.variance_low);
1429
0
    x->color_palette_thresh = 64;
1430
0
    x->force_color_check_block_level = 0;
1431
0
    x->nonrd_prune_ref_frame_search =
1432
0
        cpi->sf.rt_sf.nonrd_prune_ref_frame_search;
1433
1434
0
    if (cpi->oxcf.mode == ALLINTRA) {
1435
0
      x->intra_sb_rdmult_modifier = 128;
1436
0
    }
1437
1438
0
    xd->cur_frame_force_integer_mv = cm->features.cur_frame_force_integer_mv;
1439
0
    x->source_variance = UINT_MAX;
1440
0
    td->mb.cb_coef_buff = av1_get_cb_coeff_buffer(cpi, mi_row, mi_col);
1441
1442
    // Get segment id and skip flag
1443
0
    int seg_skip = 0;
1444
0
    x->sb_copied_ref = NONE_FRAME;
1445
0
    if (seg->enabled) {
1446
0
      const uint8_t segment_id = sb_segment_ids[sb_col_in_tile];
1447
0
      seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
1448
0
      if (seg_skip && !frame_is_intra_only(cm) && use_nonrd_mode)
1449
0
        x->sb_copied_ref = get_skip_sb_copy_ref(cm, segment_id);
1450
0
    }
1451
1452
0
    produce_gradients_for_sb(cpi, x, sb_size, mi_row, mi_col);
1453
1454
0
    init_src_var_info_of_4x4_sub_blocks(cpi, x->src_var_info_of_4x4_sub_blocks,
1455
0
                                        sb_size);
1456
1457
    // Grade the temporal variation of the sb, the grade will be used to decide
1458
    // fast mode search strategy for coding blocks
1459
0
    if (!seg_skip) grade_source_content_sb(cpi, x, tile_data, mi_row, mi_col);
1460
1461
    // encode the superblock
1462
0
    if (use_nonrd_mode) {
1463
0
      encode_nonrd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
1464
0
    } else {
1465
0
      encode_rd_sb(cpi, td, tile_data, tp, mi_row, mi_col, seg_skip);
1466
0
    }
1467
1468
    // Update the top-right context in row_mt coding
1469
0
    if (update_cdf && (tile_info->mi_row_end > (mi_row + mib_size))) {
1470
0
      if (sb_cols_in_tile == 1)
1471
0
        x->row_ctx[0] = *xd->tile_ctx;
1472
0
      else if (sb_col_in_tile >= 1)
1473
0
        x->row_ctx[sb_col_in_tile - 1] = *xd->tile_ctx;
1474
0
    }
1475
0
    enc_row_mt->sync_write_ptr(row_mt_sync, sb_row, sb_col_in_tile,
1476
0
                               sb_cols_in_tile);
1477
0
  }
1478
1479
#if CONFIG_COLLECT_COMPONENT_TIMING
1480
  end_timing(cpi, encode_sb_row_time);
1481
#endif
1482
0
}
1483
1484
0
static inline void init_encode_frame_mb_context(AV1_COMP *cpi) {
1485
0
  AV1_COMMON *const cm = &cpi->common;
1486
0
  const int num_planes = av1_num_planes(cm);
1487
0
  MACROBLOCK *const x = &cpi->td.mb;
1488
0
  MACROBLOCKD *const xd = &x->e_mbd;
1489
1490
  // Copy data over into macro block data structures.
1491
0
  av1_setup_src_planes(x, cpi->source, 0, 0, num_planes,
1492
0
                       cm->seq_params->sb_size);
1493
1494
0
  av1_setup_block_planes(xd, cm->seq_params->subsampling_x,
1495
0
                         cm->seq_params->subsampling_y, num_planes);
1496
0
}
1497
1498
0
void av1_alloc_tile_data(AV1_COMP *cpi) {
1499
0
  AV1_COMMON *const cm = &cpi->common;
1500
0
  const int tile_cols = cm->tiles.cols;
1501
0
  const int tile_rows = cm->tiles.rows;
1502
1503
0
  av1_row_mt_mem_dealloc(cpi);
1504
1505
0
  aom_free(cpi->tile_data);
1506
0
  cpi->allocated_tiles = 0;
1507
1508
0
  CHECK_MEM_ERROR(
1509
0
      cm, cpi->tile_data,
1510
0
      aom_memalign(32, tile_cols * tile_rows * sizeof(*cpi->tile_data)));
1511
1512
0
  cpi->allocated_tiles = tile_cols * tile_rows;
1513
0
  for (int tile_row = 0; tile_row < tile_rows; ++tile_row) {
1514
0
    for (int tile_col = 0; tile_col < tile_cols; ++tile_col) {
1515
0
      const int tile_index = tile_row * tile_cols + tile_col;
1516
0
      TileDataEnc *const this_tile = &cpi->tile_data[tile_index];
1517
0
      av1_zero(this_tile->row_mt_sync);
1518
0
      this_tile->row_ctx = NULL;
1519
0
    }
1520
0
  }
1521
0
}
1522
1523
0
void av1_init_tile_data(AV1_COMP *cpi) {
1524
0
  AV1_COMMON *const cm = &cpi->common;
1525
0
  const int num_planes = av1_num_planes(cm);
1526
0
  const int tile_cols = cm->tiles.cols;
1527
0
  const int tile_rows = cm->tiles.rows;
1528
0
  int tile_col, tile_row;
1529
0
  TokenInfo *const token_info = &cpi->token_info;
1530
0
  TokenExtra *pre_tok = token_info->tile_tok[0][0];
1531
0
  TokenList *tplist = token_info->tplist[0][0];
1532
0
  unsigned int tile_tok = 0;
1533
0
  int tplist_count = 0;
1534
1535
0
  if (!is_stat_generation_stage(cpi) &&
1536
0
      cm->features.allow_screen_content_tools) {
1537
    // Number of tokens for which token info needs to be allocated.
1538
0
    unsigned int tokens_required =
1539
0
        get_token_alloc(cm->mi_params.mb_rows, cm->mi_params.mb_cols,
1540
0
                        MAX_SB_SIZE_LOG2, num_planes);
1541
    // Allocate/reallocate memory for token related info if the number of tokens
1542
    // required is more than the number of tokens already allocated. This could
1543
    // occur in case of the following:
1544
    // 1) If the memory is not yet allocated
1545
    // 2) If the frame dimensions have changed
1546
0
    const bool realloc_tokens = tokens_required > token_info->tokens_allocated;
1547
0
    if (realloc_tokens) {
1548
0
      free_token_info(token_info);
1549
0
      alloc_token_info(cm, token_info, tokens_required);
1550
0
      pre_tok = token_info->tile_tok[0][0];
1551
0
      tplist = token_info->tplist[0][0];
1552
0
    }
1553
0
  }
1554
1555
0
  for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
1556
0
    for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
1557
0
      TileDataEnc *const tile_data =
1558
0
          &cpi->tile_data[tile_row * tile_cols + tile_col];
1559
0
      TileInfo *const tile_info = &tile_data->tile_info;
1560
0
      av1_tile_init(tile_info, cm, tile_row, tile_col);
1561
0
      tile_data->firstpass_top_mv = kZeroMv;
1562
0
      tile_data->abs_sum_level = 0;
1563
1564
0
      if (is_token_info_allocated(token_info)) {
1565
0
        token_info->tile_tok[tile_row][tile_col] = pre_tok + tile_tok;
1566
0
        pre_tok = token_info->tile_tok[tile_row][tile_col];
1567
0
        tile_tok = allocated_tokens(
1568
0
            tile_info, cm->seq_params->mib_size_log2 + MI_SIZE_LOG2,
1569
0
            num_planes);
1570
0
        token_info->tplist[tile_row][tile_col] = tplist + tplist_count;
1571
0
        tplist = token_info->tplist[tile_row][tile_col];
1572
0
        tplist_count = av1_get_sb_rows_in_tile(cm, tile_info);
1573
0
      }
1574
0
      tile_data->allow_update_cdf = !cm->tiles.large_scale;
1575
0
      tile_data->allow_update_cdf = tile_data->allow_update_cdf &&
1576
0
                                    !cm->features.disable_cdf_update &&
1577
0
                                    !delay_wait_for_top_right_sb(cpi);
1578
0
      tile_data->tctx = *cm->fc;
1579
0
    }
1580
0
  }
1581
0
}
1582
1583
// Populate the start palette token info prior to encoding an SB row.
1584
static inline void get_token_start(AV1_COMP *cpi, const TileInfo *tile_info,
1585
                                   int tile_row, int tile_col, int mi_row,
1586
0
                                   TokenExtra **tp) {
1587
0
  const TokenInfo *token_info = &cpi->token_info;
1588
0
  if (!is_token_info_allocated(token_info)) return;
1589
1590
0
  const AV1_COMMON *cm = &cpi->common;
1591
0
  const int num_planes = av1_num_planes(cm);
1592
0
  TokenList *const tplist = cpi->token_info.tplist[tile_row][tile_col];
1593
0
  const int sb_row_in_tile =
1594
0
      (mi_row - tile_info->mi_row_start) >> cm->seq_params->mib_size_log2;
1595
1596
0
  get_start_tok(cpi, tile_row, tile_col, mi_row, tp,
1597
0
                cm->seq_params->mib_size_log2 + MI_SIZE_LOG2, num_planes);
1598
0
  assert(tplist != NULL);
1599
0
  tplist[sb_row_in_tile].start = *tp;
1600
0
}
1601
1602
// Populate the token count after encoding an SB row.
1603
static inline void populate_token_count(AV1_COMP *cpi,
1604
                                        const TileInfo *tile_info, int tile_row,
1605
                                        int tile_col, int mi_row,
1606
0
                                        TokenExtra *tok) {
1607
0
  const TokenInfo *token_info = &cpi->token_info;
1608
0
  if (!is_token_info_allocated(token_info)) return;
1609
1610
0
  const AV1_COMMON *cm = &cpi->common;
1611
0
  const int num_planes = av1_num_planes(cm);
1612
0
  TokenList *const tplist = token_info->tplist[tile_row][tile_col];
1613
0
  const int sb_row_in_tile =
1614
0
      (mi_row - tile_info->mi_row_start) >> cm->seq_params->mib_size_log2;
1615
0
  const int tile_mb_cols =
1616
0
      (tile_info->mi_col_end - tile_info->mi_col_start + 2) >> 2;
1617
0
  const int num_mb_rows_in_sb =
1618
0
      ((1 << (cm->seq_params->mib_size_log2 + MI_SIZE_LOG2)) + 8) >> 4;
1619
0
  tplist[sb_row_in_tile].count =
1620
0
      (unsigned int)(tok - tplist[sb_row_in_tile].start);
1621
1622
0
  assert((unsigned int)(tok - tplist[sb_row_in_tile].start) <=
1623
0
         get_token_alloc(num_mb_rows_in_sb, tile_mb_cols,
1624
0
                         cm->seq_params->mib_size_log2 + MI_SIZE_LOG2,
1625
0
                         num_planes));
1626
1627
0
  (void)num_planes;
1628
0
  (void)tile_mb_cols;
1629
0
  (void)num_mb_rows_in_sb;
1630
0
}
1631
1632
/*!\brief Encode a superblock row
1633
 *
1634
 * \ingroup partition_search
1635
 */
1636
void av1_encode_sb_row(AV1_COMP *cpi, ThreadData *td, int tile_row,
1637
0
                       int tile_col, int mi_row) {
1638
0
  AV1_COMMON *const cm = &cpi->common;
1639
0
  const int tile_cols = cm->tiles.cols;
1640
0
  TileDataEnc *this_tile = &cpi->tile_data[tile_row * tile_cols + tile_col];
1641
0
  const TileInfo *const tile_info = &this_tile->tile_info;
1642
0
  TokenExtra *tok = NULL;
1643
1644
0
  get_token_start(cpi, tile_info, tile_row, tile_col, mi_row, &tok);
1645
1646
0
  encode_sb_row(cpi, td, this_tile, mi_row, &tok);
1647
1648
0
  populate_token_count(cpi, tile_info, tile_row, tile_col, mi_row, tok);
1649
0
}
1650
1651
/*!\brief Encode a tile
1652
 *
1653
 * \ingroup partition_search
1654
 */
1655
void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
1656
0
                     int tile_col) {
1657
0
  AV1_COMMON *const cm = &cpi->common;
1658
0
  TileDataEnc *const this_tile =
1659
0
      &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1660
0
  const TileInfo *const tile_info = &this_tile->tile_info;
1661
1662
0
  if (!cpi->sf.rt_sf.use_nonrd_pick_mode) av1_inter_mode_data_init(this_tile);
1663
1664
0
  av1_zero_above_context(cm, &td->mb.e_mbd, tile_info->mi_col_start,
1665
0
                         tile_info->mi_col_end, tile_row);
1666
0
  av1_init_above_context(&cm->above_contexts, av1_num_planes(cm), tile_row,
1667
0
                         &td->mb.e_mbd);
1668
1669
0
#if !CONFIG_REALTIME_ONLY
1670
0
  if (cpi->oxcf.intra_mode_cfg.enable_cfl_intra)
1671
0
    cfl_init(&td->mb.e_mbd.cfl, cm->seq_params);
1672
0
#endif
1673
1674
0
  if (td->mb.txfm_search_info.mb_rd_record != NULL) {
1675
0
    av1_crc32c_calculator_init(
1676
0
        &td->mb.txfm_search_info.mb_rd_record->crc_calculator);
1677
0
  }
1678
1679
0
  for (int mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
1680
0
       mi_row += cm->seq_params->mib_size) {
1681
0
    av1_encode_sb_row(cpi, td, tile_row, tile_col, mi_row);
1682
0
  }
1683
0
  this_tile->abs_sum_level = td->abs_sum_level;
1684
0
}
1685
1686
/*!\brief Break one frame into tiles and encode the tiles
1687
 *
1688
 * \ingroup partition_search
1689
 *
1690
 * \param[in]    cpi    Top-level encoder structure
1691
 */
1692
0
static inline void encode_tiles(AV1_COMP *cpi) {
1693
0
  AV1_COMMON *const cm = &cpi->common;
1694
0
  const int tile_cols = cm->tiles.cols;
1695
0
  const int tile_rows = cm->tiles.rows;
1696
0
  int tile_col, tile_row;
1697
1698
0
  MACROBLOCK *const mb = &cpi->td.mb;
1699
0
  assert(IMPLIES(cpi->tile_data == NULL, cpi->allocated_tiles == 0));
1700
0
  if (cpi->allocated_tiles != tile_cols * tile_rows) av1_alloc_tile_data(cpi);
1701
1702
0
  av1_init_tile_data(cpi);
1703
0
  av1_alloc_mb_data(cpi, mb);
1704
1705
0
  for (tile_row = 0; tile_row < tile_rows; ++tile_row) {
1706
0
    for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
1707
0
      TileDataEnc *const this_tile =
1708
0
          &cpi->tile_data[tile_row * cm->tiles.cols + tile_col];
1709
0
      cpi->td.intrabc_used = 0;
1710
0
      cpi->td.deltaq_used = 0;
1711
0
      cpi->td.abs_sum_level = 0;
1712
0
      cpi->td.mb.e_mbd.tile_ctx = &this_tile->tctx;
1713
0
      cpi->td.mb.tile_pb_ctx = &this_tile->tctx;
1714
0
      av1_init_rtc_counters(&cpi->td.mb);
1715
0
      cpi->td.mb.palette_pixels = 0;
1716
0
      av1_encode_tile(cpi, &cpi->td, tile_row, tile_col);
1717
0
      if (!frame_is_intra_only(&cpi->common))
1718
0
        av1_accumulate_rtc_counters(cpi, &cpi->td.mb);
1719
0
      cpi->palette_pixel_num += cpi->td.mb.palette_pixels;
1720
0
      cpi->intrabc_used |= cpi->td.intrabc_used;
1721
0
      cpi->deltaq_used |= cpi->td.deltaq_used;
1722
0
    }
1723
0
  }
1724
1725
0
  av1_dealloc_mb_data(mb, av1_num_planes(cm));
1726
0
}
1727
1728
// Set the relative distance of a reference frame w.r.t. current frame
1729
static inline void set_rel_frame_dist(
1730
    const AV1_COMMON *const cm, RefFrameDistanceInfo *const ref_frame_dist_info,
1731
0
    const int ref_frame_flags) {
1732
0
  MV_REFERENCE_FRAME ref_frame;
1733
0
  int min_past_dist = INT32_MAX, min_future_dist = INT32_MAX;
1734
0
  ref_frame_dist_info->nearest_past_ref = NONE_FRAME;
1735
0
  ref_frame_dist_info->nearest_future_ref = NONE_FRAME;
1736
0
  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
1737
0
    ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = 0;
1738
0
    if (ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
1739
0
      int dist = av1_encoder_get_relative_dist(
1740
0
          cm->cur_frame->ref_display_order_hint[ref_frame - LAST_FRAME],
1741
0
          cm->current_frame.display_order_hint);
1742
0
      ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] = dist;
1743
      // Get the nearest ref_frame in the past
1744
0
      if (abs(dist) < min_past_dist && dist < 0) {
1745
0
        ref_frame_dist_info->nearest_past_ref = ref_frame;
1746
0
        min_past_dist = abs(dist);
1747
0
      }
1748
      // Get the nearest ref_frame in the future
1749
0
      if (dist < min_future_dist && dist > 0) {
1750
0
        ref_frame_dist_info->nearest_future_ref = ref_frame;
1751
0
        min_future_dist = dist;
1752
0
      }
1753
0
    }
1754
0
  }
1755
0
}
1756
1757
0
static inline int refs_are_one_sided(const AV1_COMMON *cm) {
1758
0
  assert(!frame_is_intra_only(cm));
1759
1760
0
  int one_sided_refs = 1;
1761
0
  const int cur_display_order_hint = cm->current_frame.display_order_hint;
1762
0
  for (int ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref) {
1763
0
    const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref);
1764
0
    if (buf == NULL) continue;
1765
0
    if (av1_encoder_get_relative_dist(buf->display_order_hint,
1766
0
                                      cur_display_order_hint) > 0) {
1767
0
      one_sided_refs = 0;  // bwd reference
1768
0
      break;
1769
0
    }
1770
0
  }
1771
0
  return one_sided_refs;
1772
0
}
1773
1774
static inline void get_skip_mode_ref_offsets(const AV1_COMMON *cm,
1775
0
                                             int ref_order_hint[2]) {
1776
0
  const SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
1777
0
  ref_order_hint[0] = ref_order_hint[1] = 0;
1778
0
  if (!skip_mode_info->skip_mode_allowed) return;
1779
1780
0
  const RefCntBuffer *const buf_0 =
1781
0
      get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_0);
1782
0
  const RefCntBuffer *const buf_1 =
1783
0
      get_ref_frame_buf(cm, LAST_FRAME + skip_mode_info->ref_frame_idx_1);
1784
0
  assert(buf_0 != NULL && buf_1 != NULL);
1785
1786
0
  ref_order_hint[0] = buf_0->order_hint;
1787
0
  ref_order_hint[1] = buf_1->order_hint;
1788
0
}
1789
1790
0
static int check_skip_mode_enabled(AV1_COMP *const cpi) {
1791
0
  AV1_COMMON *const cm = &cpi->common;
1792
1793
0
  av1_setup_skip_mode_allowed(cm);
1794
0
  if (!cm->current_frame.skip_mode_info.skip_mode_allowed) return 0;
1795
1796
  // Turn off skip mode if the temporal distances of the reference pair to the
1797
  // current frame are different by more than 1 frame.
1798
0
  const int cur_offset = (int)cm->current_frame.order_hint;
1799
0
  int ref_offset[2];
1800
0
  get_skip_mode_ref_offsets(cm, ref_offset);
1801
0
  const int cur_to_ref0 = get_relative_dist(&cm->seq_params->order_hint_info,
1802
0
                                            cur_offset, ref_offset[0]);
1803
0
  const int cur_to_ref1 = abs(get_relative_dist(
1804
0
      &cm->seq_params->order_hint_info, cur_offset, ref_offset[1]));
1805
0
  if (abs(cur_to_ref0 - cur_to_ref1) > 1) return 0;
1806
1807
  // High Latency: Turn off skip mode if all refs are fwd.
1808
0
  if (cpi->all_one_sided_refs && cpi->oxcf.gf_cfg.lag_in_frames > 0) return 0;
1809
1810
0
  const int ref_frame[2] = {
1811
0
    cm->current_frame.skip_mode_info.ref_frame_idx_0 + LAST_FRAME,
1812
0
    cm->current_frame.skip_mode_info.ref_frame_idx_1 + LAST_FRAME
1813
0
  };
1814
0
  if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame[0]]) ||
1815
0
      !(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame[1]]))
1816
0
    return 0;
1817
1818
0
  return 1;
1819
0
}
1820
1821
static inline void set_default_interp_skip_flags(
1822
0
    const AV1_COMMON *cm, InterpSearchFlags *interp_search_flags) {
1823
0
  const int num_planes = av1_num_planes(cm);
1824
0
  interp_search_flags->default_interp_skip_flags =
1825
0
      (num_planes == 1) ? INTERP_SKIP_LUMA_EVAL_CHROMA
1826
0
                        : INTERP_SKIP_LUMA_SKIP_CHROMA;
1827
0
}
1828
1829
/*!\cond */
1830
typedef struct {
1831
  // Scoring function for usefulness of references (the lower score, the more
1832
  // useful)
1833
  int score;
1834
  // Index in the reference buffer
1835
  int index;
1836
} RefScoreData;
1837
/*!\endcond */
1838
1839
// Comparison function to sort reference frames in ascending score order.
1840
0
static int compare_score_data_asc(const void *a, const void *b) {
1841
0
  const RefScoreData *ra = (const RefScoreData *)a;
1842
0
  const RefScoreData *rb = (const RefScoreData *)b;
1843
1844
0
  const int score_diff = ra->score - rb->score;
1845
0
  if (score_diff != 0) return score_diff;
1846
1847
0
  return ra->index - rb->index;
1848
0
}
1849
1850
// Determines whether a given reference frame is "good" based on temporal
1851
// distance and base_qindex. The "good" reference frames are not allowed to be
1852
// pruned by the speed feature "prune_single_ref" and "prune_comp_ref_frames"
1853
// at block level.
1854
0
static inline void setup_keep_ref_frame_mask(AV1_COMP *cpi) {
1855
0
  const int prune_single_ref = cpi->sf.inter_sf.prune_single_ref;
1856
0
  const int prune_comp_ref_frames = cpi->sf.inter_sf.prune_comp_ref_frames;
1857
0
  const AV1_COMMON *const cm = &cpi->common;
1858
0
  cpi->keep_single_ref_frame_mask = 0;
1859
0
  cpi->keep_comp_ref_frame_mask = 0;
1860
0
  if (frame_is_intra_only(cm)) return;
1861
1862
0
  RefScoreData ref_score_data[INTER_REFS_PER_FRAME];
1863
0
  for (int i = 0; i < INTER_REFS_PER_FRAME; ++i) {
1864
0
    ref_score_data[i].score = INT_MAX;
1865
0
    ref_score_data[i].index = i;
1866
0
  }
1867
1868
  // Calculate score for each reference frame based on relative distance to
1869
  // the current frame and its base_qindex. A lower score means that the
1870
  // reference is potentially more useful.
1871
0
  for (MV_REFERENCE_FRAME ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME;
1872
0
       ++ref_frame) {
1873
0
    if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
1874
0
      const RefFrameDistanceInfo *const ref_frame_dist_info =
1875
0
          &cpi->ref_frame_dist_info;
1876
0
      const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
1877
0
      ref_score_data[ref_frame - LAST_FRAME].score =
1878
0
          abs(ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME]) +
1879
0
          buf->base_qindex;
1880
0
    }
1881
0
  }
1882
1883
0
  qsort(ref_score_data, INTER_REFS_PER_FRAME, sizeof(ref_score_data[0]),
1884
0
        compare_score_data_asc);
1885
1886
  // Decide the number of reference frames for which pruning via the speed
1887
  // feature prune_single_ref is disallowed.
1888
  // prune_single_ref = 0 => None of the 7 reference frames are pruned.
1889
  // prune_single_ref = 1 => The best 5 reference frames are not pruned.
1890
  // prune_single_ref = 2 => The best 3 reference frames are not pruned.
1891
  // prune_single_ref = 3, 4 => All the 7 references are allowed to be pruned.
1892
0
  static const int num_single_ref_to_keep_lookup[5] = { INTER_REFS_PER_FRAME, 5,
1893
0
                                                        3, 0, 0 };
1894
0
  assert(prune_single_ref >= 0 && prune_single_ref <= 4);
1895
0
  const int num_single_ref_to_keep =
1896
0
      num_single_ref_to_keep_lookup[prune_single_ref];
1897
0
  for (int i = 0; i < num_single_ref_to_keep; ++i) {
1898
0
    const int idx = ref_score_data[i].index;
1899
0
    cpi->keep_single_ref_frame_mask |= 1 << idx;
1900
0
  }
1901
1902
  // Decide the number of reference frame pairs for which pruning via the speed
1903
  // feature "prune_comp_ref_frames" is disallowed.
1904
  // prune_comp_ref_frames = 0    => None of the allowed reference frame pairs
1905
  //                                 are pruned.
1906
  // prune_comp_ref_frames = 1    => The best 3 reference frame pairs are not
1907
  //                                 allowed to be pruned, i.e, reference frame
1908
  //                                 pairs with rank (1, 2), (1, 3), (2, 3) are
1909
  //                                 not  pruned.
1910
  // prune_comp_ref_frames = 2, 3 => All the reference frame pairs are allowed
1911
  //                                 to be pruned.
1912
0
  static const int num_comp_ref_to_keep_lookup[4] = { INTER_REFS_PER_FRAME, 3,
1913
0
                                                      0, 0 };
1914
0
  assert(prune_comp_ref_frames >= 0 && prune_comp_ref_frames <= 3);
1915
0
  const int num_comp_ref_to_keep =
1916
0
      num_comp_ref_to_keep_lookup[prune_comp_ref_frames];
1917
0
  for (int i = 0; i < num_comp_ref_to_keep; ++i) {
1918
0
    const int idx = ref_score_data[i].index;
1919
0
    cpi->keep_comp_ref_frame_mask |= 1 << idx;
1920
0
  }
1921
0
}
1922
1923
0
static inline void setup_prune_ref_frame_mask(AV1_COMP *cpi) {
1924
0
  if ((!cpi->oxcf.ref_frm_cfg.enable_onesided_comp ||
1925
0
       cpi->sf.inter_sf.disable_onesided_comp) &&
1926
0
      cpi->all_one_sided_refs) {
1927
    // Disable all compound references
1928
0
    cpi->prune_ref_frame_mask = (1 << MODE_CTX_REF_FRAMES) - (1 << REF_FRAMES);
1929
0
  } else if (!cpi->sf.rt_sf.use_nonrd_pick_mode &&
1930
0
             cpi->sf.inter_sf.selective_ref_frame >= 1) {
1931
0
    AV1_COMMON *const cm = &cpi->common;
1932
0
    const int cur_frame_display_order_hint =
1933
0
        cm->current_frame.display_order_hint;
1934
0
    unsigned int *ref_display_order_hint =
1935
0
        cm->cur_frame->ref_display_order_hint;
1936
0
    const int arf2_dist = av1_encoder_get_relative_dist(
1937
0
        ref_display_order_hint[ALTREF2_FRAME - LAST_FRAME],
1938
0
        cur_frame_display_order_hint);
1939
0
    const int bwd_dist = av1_encoder_get_relative_dist(
1940
0
        ref_display_order_hint[BWDREF_FRAME - LAST_FRAME],
1941
0
        cur_frame_display_order_hint);
1942
1943
0
    for (int ref_idx = REF_FRAMES; ref_idx < MODE_CTX_REF_FRAMES; ++ref_idx) {
1944
0
      MV_REFERENCE_FRAME rf[2];
1945
0
      av1_set_ref_frame(rf, ref_idx);
1946
0
      if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[0]]) ||
1947
0
          !(cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[1]])) {
1948
0
        continue;
1949
0
      }
1950
1951
0
      if (!cpi->all_one_sided_refs) {
1952
0
        int ref_dist[2];
1953
0
        for (int i = 0; i < 2; ++i) {
1954
0
          ref_dist[i] = av1_encoder_get_relative_dist(
1955
0
              ref_display_order_hint[rf[i] - LAST_FRAME],
1956
0
              cur_frame_display_order_hint);
1957
0
        }
1958
1959
        // One-sided compound is used only when all reference frames are
1960
        // one-sided.
1961
0
        if ((ref_dist[0] > 0) == (ref_dist[1] > 0)) {
1962
0
          cpi->prune_ref_frame_mask |= 1 << ref_idx;
1963
0
        }
1964
0
      }
1965
1966
0
      if (cpi->sf.inter_sf.selective_ref_frame >= 4 &&
1967
0
          (rf[0] == ALTREF2_FRAME || rf[1] == ALTREF2_FRAME) &&
1968
0
          (cpi->ref_frame_flags & av1_ref_frame_flag_list[BWDREF_FRAME])) {
1969
        // Check if both ALTREF2_FRAME and BWDREF_FRAME are future references.
1970
0
        if (arf2_dist > 0 && bwd_dist > 0 && bwd_dist <= arf2_dist) {
1971
          // Drop ALTREF2_FRAME as a reference if BWDREF_FRAME is a closer
1972
          // reference to the current frame than ALTREF2_FRAME
1973
0
          cpi->prune_ref_frame_mask |= 1 << ref_idx;
1974
0
        }
1975
0
      }
1976
0
    }
1977
0
  }
1978
0
}
1979
1980
0
static int allow_deltaq_mode(AV1_COMP *cpi) {
1981
0
#if !CONFIG_REALTIME_ONLY
1982
0
  AV1_COMMON *const cm = &cpi->common;
1983
0
  BLOCK_SIZE sb_size = cm->seq_params->sb_size;
1984
0
  int sbs_wide = mi_size_wide[sb_size];
1985
0
  int sbs_high = mi_size_high[sb_size];
1986
1987
0
  int64_t delta_rdcost = 0;
1988
0
  for (int mi_row = 0; mi_row < cm->mi_params.mi_rows; mi_row += sbs_high) {
1989
0
    for (int mi_col = 0; mi_col < cm->mi_params.mi_cols; mi_col += sbs_wide) {
1990
0
      int64_t this_delta_rdcost = 0;
1991
0
      av1_get_q_for_deltaq_objective(cpi, &cpi->td, &this_delta_rdcost, sb_size,
1992
0
                                     mi_row, mi_col);
1993
0
      delta_rdcost += this_delta_rdcost;
1994
0
    }
1995
0
  }
1996
0
  return delta_rdcost < 0;
1997
#else
1998
  (void)cpi;
1999
  return 1;
2000
#endif  // !CONFIG_REALTIME_ONLY
2001
0
}
2002
2003
0
static inline int disable_deltaq_for_intl_arfs(const AV1_COMP *cpi) {
2004
0
  if (cpi->oxcf.mode == GOOD && is_stat_consumption_stage_twopass(cpi) &&
2005
0
      cpi->oxcf.q_cfg.deltaq_mode == DELTA_Q_OBJECTIVE &&
2006
0
      cpi->oxcf.algo_cfg.enable_tpl_model && cpi->oxcf.q_cfg.aq_mode == NO_AQ &&
2007
0
      !cpi->common.seg.enabled && !cpi->roi.enabled && !cpi->oxcf.sb_qp_sweep &&
2008
0
      !cpi->use_ducky_encode) {
2009
0
    return 1;
2010
0
  }
2011
0
  return 0;
2012
0
}
2013
2014
0
static inline int enable_delta_rdmult(const AV1_COMP *cpi) {
2015
0
  if (!disable_deltaq_for_intl_arfs(cpi))
2016
0
    return cpi->common.delta_q_info.delta_q_present_flag;
2017
2018
0
  const GF_GROUP *gf_group = &cpi->ppi->gf_group;
2019
0
  return gf_group->update_type[cpi->gf_frame_index] != LF_UPDATE;
2020
0
}
2021
2022
0
static inline int enable_delta_q(const AV1_COMP *cpi) {
2023
0
  const GF_GROUP *gf_group = &cpi->ppi->gf_group;
2024
0
  if (!disable_deltaq_for_intl_arfs(cpi))
2025
0
    return gf_group->update_type[cpi->gf_frame_index] != LF_UPDATE;
2026
2027
0
  return cpi->common.current_frame.pyramid_level <= 1;
2028
0
}
2029
2030
0
#define FORCE_ZMV_SKIP_128X128_BLK_DIFF 10000
2031
#define FORCE_ZMV_SKIP_MAX_PER_PIXEL_DIFF 4
2032
2033
// Populates block level thresholds for force zeromv-skip decision
2034
0
static void populate_thresh_to_force_zeromv_skip(AV1_COMP *cpi) {
2035
0
  if (cpi->sf.rt_sf.part_early_exit_zeromv == 0) return;
2036
2037
  // Threshold for forcing zeromv-skip decision is as below:
2038
  // For 128x128 blocks, threshold is 10000 and per pixel threshold is 0.6103.
2039
  // For 64x64 blocks, threshold is 5000 and per pixel threshold is 1.221
2040
  // allowing slightly higher error for smaller blocks.
2041
  // Per Pixel Threshold of 64x64 block        Area of 64x64 block         1  1
2042
  // ------------------------------------=sqrt(---------------------)=sqrt(-)=-
2043
  // Per Pixel Threshold of 128x128 block      Area of 128x128 block       4  2
2044
  // Thus, per pixel thresholds for blocks of size 32x32, 16x16,...  can be
2045
  // chosen as 2.442, 4.884,.... As the per pixel error tends to be higher for
2046
  // small blocks, the same is clipped to 4.
2047
0
  const unsigned int thresh_exit_128x128_part = FORCE_ZMV_SKIP_128X128_BLK_DIFF;
2048
0
  const int num_128x128_pix =
2049
0
      block_size_wide[BLOCK_128X128] * block_size_high[BLOCK_128X128];
2050
2051
0
  for (BLOCK_SIZE bsize = BLOCK_4X4; bsize < BLOCK_SIZES_ALL; bsize++) {
2052
0
    const int num_block_pix = block_size_wide[bsize] * block_size_high[bsize];
2053
2054
    // Calculate the threshold for zeromv-skip decision based on area of the
2055
    // partition
2056
0
    unsigned int thresh_exit_part_blk =
2057
0
        (unsigned int)(thresh_exit_128x128_part *
2058
0
                           sqrt((double)num_block_pix / num_128x128_pix) +
2059
0
                       0.5);
2060
0
    thresh_exit_part_blk = AOMMIN(
2061
0
        thresh_exit_part_blk,
2062
0
        (unsigned int)(FORCE_ZMV_SKIP_MAX_PER_PIXEL_DIFF * num_block_pix));
2063
0
    cpi->zeromv_skip_thresh_exit_part[bsize] = thresh_exit_part_blk;
2064
0
  }
2065
0
}
2066
2067
0
static void free_block_hash_buffers(IntraBCHashInfo *intrabc_hash_info) {
2068
0
  for (int j = 0; j < 2; ++j) {
2069
0
    aom_free(intrabc_hash_info->frame_hash_buffer[j]);
2070
0
    intrabc_hash_info->frame_hash_buffer[j] = NULL;
2071
0
  }
2072
0
  intrabc_hash_info->frame_hash_width = 0;
2073
0
  intrabc_hash_info->frame_hash_height = 0;
2074
0
}
2075
2076
// Returns the distance in values between rows of the frame hash buffers. The
2077
// table fill reads the buffers column by column, 2 or more rows at a time.
2078
// When the width has a large power of 2 factor, the reads of a column share
2079
// their low address bits and map to only a few cache sets. The lines a column
2080
// loads are then evicted before the next column reads them again. With an odd
2081
// multiple of 8 values, a step of 2 rows is an odd number of 64 byte cache
2082
// lines, so a column spreads over all the cache sets.
2083
0
static int get_intrabc_hash_stride(int width) {
2084
0
  return ALIGN_POWER_OF_TWO(width, 3) | 8;
2085
0
}
2086
2087
// Gets the region covered by the hash table with the given index. That is the
2088
// bounding rectangle of the tiles that share the table.
2089
static void get_intrabc_hash_region(const YV12_BUFFER_CONFIG *source,
2090
                                    const AV1_COMMON *cm,
2091
                                    const IntraBCHashInfo *intrabc_hash_info,
2092
0
                                    int table_idx, IntraBCHashRegion *region) {
2093
0
  const int tile_cols = intrabc_hash_info->tile_cols_per_table;
2094
0
  const int tile_rows = intrabc_hash_info->tile_rows_per_table;
2095
0
  const int first_row = table_idx / intrabc_hash_info->table_cols * tile_rows;
2096
0
  const int first_col = table_idx % intrabc_hash_info->table_cols * tile_cols;
2097
0
  const int last_row = AOMMIN(first_row + tile_rows, cm->tiles.rows) - 1;
2098
0
  const int last_col = AOMMIN(first_col + tile_cols, cm->tiles.cols) - 1;
2099
0
  TileInfo first_tile;
2100
0
  TileInfo last_tile;
2101
0
  av1_tile_init(&first_tile, cm, first_row, first_col);
2102
0
  av1_tile_init(&last_tile, cm, last_row, last_col);
2103
0
  region->x_start = first_tile.mi_col_start * MI_SIZE;
2104
0
  region->y_start = first_tile.mi_row_start * MI_SIZE;
2105
0
  region->x_end = AOMMIN(last_tile.mi_col_end * MI_SIZE, source->y_crop_width);
2106
0
  region->y_end = AOMMIN(last_tile.mi_row_end * MI_SIZE, source->y_crop_height);
2107
0
}
2108
2109
// Splits the tiles into at most MAX_INTRABC_HASH_TABLES rectangles of
2110
// neighboring tiles, one for each table. The side with more tables is halved
2111
// until they fit.
2112
static void set_intrabc_hash_table_grid(const CommonTileParams *tiles,
2113
0
                                        IntraBCHashInfo *intrabc_hash_info) {
2114
0
  int table_cols = tiles->cols;
2115
0
  int table_rows = tiles->rows;
2116
0
  while (table_cols * table_rows > MAX_INTRABC_HASH_TABLES) {
2117
0
    if (table_cols >= table_rows) {
2118
0
      table_cols = (table_cols + 1) / 2;
2119
0
    } else {
2120
0
      table_rows = (table_rows + 1) / 2;
2121
0
    }
2122
0
  }
2123
0
  const int tile_cols_per_table = (tiles->cols + table_cols - 1) / table_cols;
2124
0
  const int tile_rows_per_table = (tiles->rows + table_rows - 1) / table_rows;
2125
  // Rounding up may leave fewer tables than the halving gave.
2126
0
  intrabc_hash_info->tile_cols_per_table = tile_cols_per_table;
2127
0
  intrabc_hash_info->tile_rows_per_table = tile_rows_per_table;
2128
0
  intrabc_hash_info->table_cols =
2129
0
      (tiles->cols + tile_cols_per_table - 1) / tile_cols_per_table;
2130
0
  intrabc_hash_info->table_rows =
2131
0
      (tiles->rows + tile_rows_per_table - 1) / tile_rows_per_table;
2132
0
}
2133
2134
// Returns the largest block size that is hashed for intrabc.
2135
0
static int get_max_intrabc_hash_size(const AV1_COMP *cpi) {
2136
0
  const int sb_size =
2137
0
      1 << (cpi->common.seq_params->mib_size_log2 + MI_SIZE_LOG2);
2138
0
  return cpi->sf.mv_sf.hash_max_8x8_intrabc_blocks ? AOMMIN(8, sb_size)
2139
0
                                                   : sb_size;
2140
0
}
2141
2142
// Returns true if the 4x4 hashes go in a hash table.
2143
0
static bool has_intrabc_hash_table_4x4(const AV1_COMMON *cm) {
2144
0
  return block_size_wide[cm->mi_params.mi_alloc_bsize] <= 4;
2145
0
}
2146
2147
0
bool av1_build_intrabc_hash_table(AV1_COMP *cpi, int table_idx) {
2148
0
  const AV1_COMMON *const cm = &cpi->common;
2149
0
  IntraBCHashInfo *const intrabc_hash_info = &cpi->td.mb.intrabc_hash_info;
2150
  // The frame hash buffers are only used with cpi->source, which must have the
2151
  // frame size they were allocated for.
2152
0
  uint32_t **const block_hash_values = intrabc_hash_info->frame_hash_buffer;
2153
0
  const int pic_width = cpi->source->y_crop_width;
2154
0
  const int pic_height = cpi->source->y_crop_height;
2155
0
  if (pic_width != intrabc_hash_info->frame_hash_width ||
2156
0
      pic_height != intrabc_hash_info->frame_hash_height) {
2157
0
    return false;
2158
0
  }
2159
0
  const int hash_stride = get_intrabc_hash_stride(pic_width);
2160
0
  IntraBCHashRegion region;
2161
0
  get_intrabc_hash_region(cpi->source, cm, intrabc_hash_info, table_idx,
2162
0
                          &region);
2163
0
  hash_table *const table = &intrabc_hash_info->tile_tables[table_idx];
2164
2165
  // Hash data generated for screen contents is used for intraBC ME
2166
0
  uint32_t *const hash_4x4 =
2167
0
      has_intrabc_hash_table_4x4(cm) ? block_hash_values[1] : NULL;
2168
0
  if (!av1_generate_block_8x8_hash_value(intrabc_hash_info, cpi->source,
2169
0
                                         &region, hash_4x4,
2170
0
                                         block_hash_values[0], hash_stride)) {
2171
0
    return false;
2172
0
  }
2173
0
  if (hash_4x4 != NULL && !av1_add_to_hash_map_by_row_with_precal_data(
2174
0
                              table, hash_4x4, hash_stride, &region, 4)) {
2175
0
    return false;
2176
0
  }
2177
2178
0
  const int min_alloc_size = block_size_wide[cm->mi_params.mi_alloc_bsize];
2179
0
  const int max_size = get_max_intrabc_hash_size(cpi);
2180
0
  int src_idx = 0;
2181
0
  for (int size = 8; size <= max_size; size *= 2) {
2182
0
    if (size > 8) {
2183
0
      av1_generate_block_hash_value(intrabc_hash_info, &region, size,
2184
0
                                    block_hash_values[src_idx],
2185
0
                                    block_hash_values[!src_idx], hash_stride);
2186
0
      src_idx = !src_idx;
2187
0
    }
2188
0
    if (size >= min_alloc_size &&
2189
0
        !av1_add_to_hash_map_by_row_with_precal_data(
2190
0
            table, block_hash_values[src_idx], hash_stride, &region, size)) {
2191
0
      return false;
2192
0
    }
2193
0
  }
2194
0
  return true;
2195
0
}
2196
2197
// Builds the hash tables for intrabc. A block can only copy from its own tile,
2198
// so up to MAX_INTRABC_HASH_TABLES tiles each tile gets its own table with only
2199
// the blocks that lie inside it. With more tiles, neighboring tiles share a
2200
// table, which bounds the memory. The encoder threads build the tables before
2201
// the tiles are encoded, one table per job, and av1_intrabc_hash_search() uses
2202
// the table of the current tile.
2203
0
static void build_intrabc_hash_tables(AV1_COMP *cpi) {
2204
0
  AV1_COMMON *const cm = &cpi->common;
2205
0
  MultiThreadInfo *const mt_info = &cpi->mt_info;
2206
0
  IntraBCHashInfo *const intrabc_hash_info = &cpi->td.mb.intrabc_hash_info;
2207
0
  const int pic_width = cpi->source->y_crop_width;
2208
0
  const int pic_height = cpi->source->y_crop_height;
2209
0
  const int hash_stride = get_intrabc_hash_stride(pic_width);
2210
0
  set_intrabc_hash_table_grid(&cm->tiles, intrabc_hash_info);
2211
0
  const int num_tables =
2212
0
      intrabc_hash_info->table_cols * intrabc_hash_info->table_rows;
2213
0
  bool error = false;
2214
2215
  // The second buffer is only needed for the 4x4 hashes and the sizes above
2216
  // 8x8.
2217
0
  const bool needs_second_buffer =
2218
0
      has_intrabc_hash_table_4x4(cm) || get_max_intrabc_hash_size(cpi) > 8;
2219
0
  const int num_buffers = needs_second_buffer ? 2 : 1;
2220
2221
0
  free_block_hash_buffers(intrabc_hash_info);
2222
0
  for (int j = 0; j < num_buffers; ++j) {
2223
0
    intrabc_hash_info->frame_hash_buffer[j] = (uint32_t *)aom_malloc(
2224
0
        sizeof(*intrabc_hash_info->frame_hash_buffer[j]) * hash_stride *
2225
0
        pic_height);
2226
0
    if (!intrabc_hash_info->frame_hash_buffer[j]) {
2227
0
      error = true;
2228
0
      break;
2229
0
    }
2230
0
  }
2231
0
  if (!error) {
2232
0
    intrabc_hash_info->frame_hash_width = pic_width;
2233
0
    intrabc_hash_info->frame_hash_height = pic_height;
2234
0
  }
2235
2236
0
  av1_hash_table_init(intrabc_hash_info);
2237
0
  if (error || !av1_hash_tables_create(intrabc_hash_info, num_tables)) {
2238
0
    free_block_hash_buffers(intrabc_hash_info);
2239
0
    aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
2240
0
                       "Error allocating intrabc_hash_table and buffers");
2241
0
  }
2242
2243
0
  const int num_workers =
2244
0
      AOMMIN(AOMMIN(mt_info->num_mod_workers[MOD_ENC], mt_info->num_workers),
2245
0
             num_tables);
2246
0
  if (num_workers > 1) {
2247
0
    av1_build_intrabc_hash_tables_mt(cpi, num_workers);
2248
0
  } else {
2249
0
    for (int i = 0; i < num_tables && !error; i++) {
2250
0
      error = !av1_build_intrabc_hash_table(cpi, i);
2251
0
    }
2252
0
  }
2253
2254
0
  free_block_hash_buffers(intrabc_hash_info);
2255
2256
0
  if (error) {
2257
0
    aom_internal_error(cm->error, AOM_CODEC_MEM_ERROR,
2258
0
                       "Error adding data to intrabc_hash_table");
2259
0
  }
2260
0
}
2261
2262
/*!\brief Determines delta_q_res value for Variance Boost modulation.
2263
 */
2264
0
static int aom_get_variance_boost_delta_q_res(int qindex) {
2265
  // Signaling delta_q changes across superblocks comes with inherent syntax
2266
  // element overhead, which adds up to total payload size. This overhead
2267
  // becomes proportionally bigger the higher the base qindex (i.e. lower
2268
  // quality, smaller file size), so a balance needs to be struck.
2269
  // - Smaller delta_q_res: more granular delta_q control, more bits spent
2270
  // signaling deltas.
2271
  // - Larger delta_q_res: coarser delta_q control, less bits spent signaling
2272
  // deltas.
2273
  //
2274
  // At the same time, SB qindex fluctuations become larger the higher
2275
  // the base qindex (between lowest and highest-variance regions):
2276
  // - For QP 5: up to 8 qindexes
2277
  // - For QP 60: up to 52 qindexes
2278
  //
2279
  // With these factors in mind, it was found that the best strategy that
2280
  // maximizes quality per bitrate is by having very finely-grained delta_q
2281
  // values for the lowest picture qindexes (to preserve tiny qindex SB deltas),
2282
  // and progressively making them coarser as base qindex increases (to reduce
2283
  // total signaling overhead).
2284
0
  int delta_q_res = 1;
2285
2286
0
  if (qindex >= 160) {
2287
0
    delta_q_res = 8;
2288
0
  } else if (qindex >= 120) {
2289
0
    delta_q_res = 4;
2290
0
  } else if (qindex >= 80) {
2291
0
    delta_q_res = 2;
2292
0
  } else {
2293
0
    delta_q_res = 1;
2294
0
  }
2295
2296
0
  return delta_q_res;
2297
0
}
2298
2299
#if !CONFIG_REALTIME_ONLY
2300
0
static float get_thresh_based_on_q(int qindex, int speed) {
2301
0
  const float min_threshold_arr[3] = { 0.084f, 0.087f, 0.126f };
2302
0
  const float max_threshold_arr[3] = { 0.140f, 0.150f, 0.182f };
2303
0
  const int idx = (speed >= 3) ? 2 : (speed - 1);
2304
0
  const float min_thresh = min_threshold_arr[idx];
2305
0
  const float max_thresh = max_threshold_arr[idx];
2306
0
  const float thresh = min_thresh + (max_thresh - min_thresh) *
2307
0
                                        ((float)MAXQ - (float)qindex) /
2308
0
                                        (float)(MAXQ - MINQ);
2309
0
  return thresh;
2310
0
}
2311
2312
0
static int get_mv_err(MV cur_mv, MV ref_mv) {
2313
0
  const MV diff = { cur_mv.row - ref_mv.row, cur_mv.col - ref_mv.col };
2314
0
  const MV abs_diff = { abs(diff.row), abs(diff.col) };
2315
0
  const int mv_err = (abs_diff.row + abs_diff.col);
2316
0
  return mv_err;
2317
0
}
2318
2319
0
static void check_mv_err_and_update(MV cur_mv, MV ref_mv, int *best_mv_err) {
2320
0
  const int mv_err = get_mv_err(cur_mv, ref_mv);
2321
0
  *best_mv_err = AOMMIN(mv_err, *best_mv_err);
2322
0
}
2323
2324
static int is_inside_frame_border(int mi_row, int mi_col, int row_offset,
2325
                                  int col_offset, int num_mi_rows,
2326
0
                                  int num_mi_cols) {
2327
0
  if (mi_row + row_offset < 0 || mi_row + row_offset >= num_mi_rows ||
2328
0
      mi_col + col_offset < 0 || mi_col + col_offset >= num_mi_cols)
2329
0
    return 0;
2330
2331
0
  return 1;
2332
0
}
2333
2334
// Compute the minimum MV error between current MV and spatial MV predictors.
2335
static int get_spatial_mvpred_err(AV1_COMMON *cm, TplParams *const tpl_data,
2336
                                  int tpl_idx, int mi_row, int mi_col,
2337
                                  int ref_idx, int_mv cur_mv, int allow_hp,
2338
0
                                  int is_integer) {
2339
0
  const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
2340
0
  TplDepStats *tpl_ptr = tpl_frame->tpl_stats_ptr;
2341
0
  const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
2342
2343
0
  int mv_err = INT32_MAX;
2344
0
  const int step = 1 << block_mis_log2;
2345
0
  const int mv_pred_pos_in_mis[8][2] = {
2346
0
    { -step, 0 },     { 0, -step },     { -step, step },  { -step, -step },
2347
0
    { -2 * step, 0 }, { 0, -2 * step }, { -3 * step, 0 }, { 0, -3 * step },
2348
0
  };
2349
2350
0
  for (int i = 0; i < 8; i++) {
2351
0
    int row_offset = mv_pred_pos_in_mis[i][0];
2352
0
    int col_offset = mv_pred_pos_in_mis[i][1];
2353
0
    if (!is_inside_frame_border(mi_row, mi_col, row_offset, col_offset,
2354
0
                                tpl_frame->mi_rows, tpl_frame->mi_cols)) {
2355
0
      continue;
2356
0
    }
2357
2358
0
    const TplDepStats *tpl_stats =
2359
0
        &tpl_ptr[av1_tpl_ptr_pos(mi_row + row_offset, mi_col + col_offset,
2360
0
                                 tpl_frame->stride, block_mis_log2)];
2361
0
    int_mv this_refmv = tpl_stats->mv[ref_idx];
2362
0
    lower_mv_precision(&this_refmv.as_mv, allow_hp, is_integer);
2363
0
    check_mv_err_and_update(cur_mv.as_mv, this_refmv.as_mv, &mv_err);
2364
0
  }
2365
2366
  // Check MV error w.r.t. Global MV / Zero MV
2367
0
  int_mv gm_mv = { 0 };
2368
0
  if (cm->global_motion[ref_idx + LAST_FRAME].wmtype > TRANSLATION) {
2369
0
    const BLOCK_SIZE bsize = convert_length_to_bsize(tpl_data->tpl_bsize_1d);
2370
0
    gm_mv = gm_get_motion_vector(&cm->global_motion[ref_idx + LAST_FRAME],
2371
0
                                 allow_hp, bsize, mi_col, mi_row, is_integer);
2372
0
  }
2373
0
  check_mv_err_and_update(cur_mv.as_mv, gm_mv.as_mv, &mv_err);
2374
2375
0
  return mv_err;
2376
0
}
2377
2378
// Compute the minimum MV error between current MV and temporal MV predictors.
2379
static int get_temporal_mvpred_err(AV1_COMMON *cm, int mi_row, int mi_col,
2380
                                   int num_mi_rows, int num_mi_cols,
2381
                                   int ref_idx, int_mv cur_mv, int allow_hp,
2382
0
                                   int is_integer) {
2383
0
  const RefCntBuffer *ref_buf = get_ref_frame_buf(cm, ref_idx + LAST_FRAME);
2384
0
  if (ref_buf == NULL) return INT32_MAX;
2385
0
  int cur_to_ref_dist =
2386
0
      get_relative_dist(&cm->seq_params->order_hint_info,
2387
0
                        cm->cur_frame->order_hint, ref_buf->order_hint);
2388
2389
0
  int mv_err = INT32_MAX;
2390
0
  const int mv_pred_pos_in_mis[7][2] = {
2391
0
    { 0, 0 }, { 0, 2 }, { 2, 0 }, { 2, 2 }, { 4, -2 }, { 4, 4 }, { 2, 4 },
2392
0
  };
2393
2394
0
  for (int i = 0; i < 7; i++) {
2395
0
    int row_offset = mv_pred_pos_in_mis[i][0];
2396
0
    int col_offset = mv_pred_pos_in_mis[i][1];
2397
0
    if (!is_inside_frame_border(mi_row, mi_col, row_offset, col_offset,
2398
0
                                num_mi_rows, num_mi_cols)) {
2399
0
      continue;
2400
0
    }
2401
0
    const TPL_MV_REF *ref_mvs =
2402
0
        cm->tpl_mvs +
2403
0
        ((mi_row + row_offset) >> 1) * (cm->mi_params.mi_stride >> 1) +
2404
0
        ((mi_col + col_offset) >> 1);
2405
0
    if (ref_mvs->mfmv0.as_int == INVALID_MV) continue;
2406
2407
0
    int_mv this_refmv;
2408
0
    av1_get_mv_projection(&this_refmv.as_mv, ref_mvs->mfmv0.as_mv,
2409
0
                          cur_to_ref_dist, ref_mvs->ref_frame_offset);
2410
0
    lower_mv_precision(&this_refmv.as_mv, allow_hp, is_integer);
2411
0
    check_mv_err_and_update(cur_mv.as_mv, this_refmv.as_mv, &mv_err);
2412
0
  }
2413
2414
0
  return mv_err;
2415
0
}
2416
2417
// Determine whether to disable temporal MV prediction for the current frame
2418
// based on TPL and motion field data. Temporal MV prediction is disabled if the
2419
// reduction in MV error by including temporal MVs as MV predictors is small.
2420
0
static void check_to_disable_ref_frame_mvs(AV1_COMP *cpi) {
2421
0
  AV1_COMMON *cm = &cpi->common;
2422
0
  if (!cm->features.allow_ref_frame_mvs || cpi->sf.hl_sf.ref_frame_mvs_lvl != 1)
2423
0
    return;
2424
2425
0
  const int tpl_idx = cpi->gf_frame_index;
2426
0
  TplParams *const tpl_data = &cpi->ppi->tpl_data;
2427
0
  if (!av1_tpl_stats_ready(tpl_data, tpl_idx)) return;
2428
2429
0
  const SUBPEL_FORCE_STOP tpl_subpel_precision =
2430
0
      cpi->sf.tpl_sf.subpel_force_stop;
2431
0
  const int allow_high_precision_mv = tpl_subpel_precision == EIGHTH_PEL &&
2432
0
                                      cm->features.allow_high_precision_mv;
2433
0
  const int force_integer_mv = tpl_subpel_precision == FULL_PEL ||
2434
0
                               cm->features.cur_frame_force_integer_mv;
2435
2436
0
  const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
2437
0
  TplDepStats *tpl_ptr = tpl_frame->tpl_stats_ptr;
2438
0
  const uint8_t block_mis_log2 = tpl_data->tpl_stats_block_mis_log2;
2439
0
  const int step = 1 << block_mis_log2;
2440
2441
0
  uint64_t accum_spatial_mvpred_err = 0;
2442
0
  uint64_t accum_best_err = 0;
2443
2444
0
  for (int mi_row = 0; mi_row < tpl_frame->mi_rows; mi_row += step) {
2445
0
    for (int mi_col = 0; mi_col < tpl_frame->mi_cols; mi_col += step) {
2446
0
      TplDepStats *tpl_stats_ptr = &tpl_ptr[av1_tpl_ptr_pos(
2447
0
          mi_row, mi_col, tpl_frame->stride, block_mis_log2)];
2448
0
      const int cur_best_ref_idx = tpl_stats_ptr->ref_frame_index[0];
2449
0
      if (cur_best_ref_idx == NONE_FRAME) continue;
2450
2451
0
      int_mv cur_mv = tpl_stats_ptr->mv[cur_best_ref_idx];
2452
0
      lower_mv_precision(&cur_mv.as_mv, allow_high_precision_mv,
2453
0
                         force_integer_mv);
2454
2455
0
      const int cur_spatial_mvpred_err = get_spatial_mvpred_err(
2456
0
          cm, tpl_data, tpl_idx, mi_row, mi_col, cur_best_ref_idx, cur_mv,
2457
0
          allow_high_precision_mv, force_integer_mv);
2458
2459
0
      const int cur_temporal_mvpred_err = get_temporal_mvpred_err(
2460
0
          cm, mi_row, mi_col, tpl_frame->mi_rows, tpl_frame->mi_cols,
2461
0
          cur_best_ref_idx, cur_mv, allow_high_precision_mv, force_integer_mv);
2462
2463
0
      const int cur_best_err =
2464
0
          AOMMIN(cur_spatial_mvpred_err, cur_temporal_mvpred_err);
2465
0
      accum_spatial_mvpred_err += cur_spatial_mvpred_err;
2466
0
      accum_best_err += cur_best_err;
2467
0
    }
2468
0
  }
2469
2470
0
  const float threshold =
2471
0
      get_thresh_based_on_q(cm->quant_params.base_qindex, cpi->oxcf.speed);
2472
0
  const float mv_err_reduction =
2473
0
      (float)(accum_spatial_mvpred_err - accum_best_err);
2474
2475
0
  if (mv_err_reduction <= threshold * accum_spatial_mvpred_err)
2476
0
    cm->features.allow_ref_frame_mvs = 0;
2477
0
}
2478
#endif  // !CONFIG_REALTIME_ONLY
2479
2480
/*!\brief Encoder setup(only for the current frame), encoding, and recontruction
2481
 * for a single frame
2482
 *
2483
 * \ingroup high_level_algo
2484
 */
2485
0
static inline void encode_frame_internal(AV1_COMP *cpi) {
2486
0
  ThreadData *const td = &cpi->td;
2487
0
  MACROBLOCK *const x = &td->mb;
2488
0
  AV1_COMMON *const cm = &cpi->common;
2489
0
  CommonModeInfoParams *const mi_params = &cm->mi_params;
2490
0
  FeatureFlags *const features = &cm->features;
2491
0
  MACROBLOCKD *const xd = &x->e_mbd;
2492
0
  RD_COUNTS *const rdc = &cpi->td.rd_counts;
2493
#if CONFIG_FPMT_TEST
2494
  FrameProbInfo *const temp_frame_probs = &cpi->ppi->temp_frame_probs;
2495
  FrameProbInfo *const temp_frame_probs_simulation =
2496
      &cpi->ppi->temp_frame_probs_simulation;
2497
#endif
2498
0
  FrameProbInfo *const frame_probs = &cpi->ppi->frame_probs;
2499
0
  MultiThreadInfo *const mt_info = &cpi->mt_info;
2500
0
  AV1EncRowMultiThreadInfo *const enc_row_mt = &mt_info->enc_row_mt;
2501
0
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
2502
0
  const DELTAQ_MODE deltaq_mode = oxcf->q_cfg.deltaq_mode;
2503
0
  int i;
2504
2505
0
  if (!cpi->sf.rt_sf.use_nonrd_pick_mode) {
2506
0
    mi_params->setup_mi(mi_params);
2507
0
  }
2508
2509
0
  set_mi_offsets(mi_params, xd, 0, 0);
2510
2511
0
  av1_zero(*td->counts);
2512
0
  av1_zero(rdc->tx_type_used);
2513
0
  av1_zero(rdc->obmc_used);
2514
0
  av1_zero(rdc->warped_used);
2515
0
  av1_zero(rdc->seg_tmp_pred_cost);
2516
2517
  // Reset the flag.
2518
0
  cpi->intrabc_used = 0;
2519
  // Need to disable intrabc when superres is selected
2520
0
  if (av1_superres_scaled(cm)) {
2521
0
    features->allow_intrabc = 0;
2522
0
  }
2523
2524
0
  features->allow_intrabc &= (oxcf->kf_cfg.enable_intrabc);
2525
2526
0
  if (features->allow_warped_motion &&
2527
0
      cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
2528
0
    const FRAME_UPDATE_TYPE update_type =
2529
0
        get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2530
0
    int warped_probability =
2531
#if CONFIG_FPMT_TEST
2532
        cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE
2533
            ? temp_frame_probs->warped_probs[update_type]
2534
            :
2535
#endif  // CONFIG_FPMT_TEST
2536
0
            frame_probs->warped_probs[update_type];
2537
0
    if (warped_probability < cpi->sf.inter_sf.prune_warped_prob_thresh)
2538
0
      features->allow_warped_motion = 0;
2539
0
  }
2540
2541
0
  if (!is_stat_generation_stage(cpi) && av1_use_hash_me(cpi) &&
2542
0
      (!cpi->sf.rt_sf.use_nonrd_pick_mode || cpi->sf.rt_sf.rt_use_intrabc)) {
2543
    // TODO(any): move this outside of the recoding loop to avoid recalculating
2544
    // the hash table.
2545
0
    build_intrabc_hash_tables(cpi);
2546
0
  }
2547
2548
0
  const CommonQuantParams *quant_params = &cm->quant_params;
2549
0
  for (i = 0; i < MAX_SEGMENTS; ++i) {
2550
0
    const int qindex =
2551
0
        cm->seg.enabled ? av1_get_qindex(&cm->seg, i, quant_params->base_qindex)
2552
0
                        : quant_params->base_qindex;
2553
0
    xd->lossless[i] =
2554
0
        qindex == 0 && quant_params->y_dc_delta_q == 0 &&
2555
0
        quant_params->u_dc_delta_q == 0 && quant_params->u_ac_delta_q == 0 &&
2556
0
        quant_params->v_dc_delta_q == 0 && quant_params->v_ac_delta_q == 0;
2557
0
    if (xd->lossless[i]) cpi->enc_seg.has_lossless_segment = 1;
2558
0
    xd->qindex[i] = qindex;
2559
0
    if (xd->lossless[i]) {
2560
0
      cpi->optimize_seg_arr[i] = NO_TRELLIS_OPT;
2561
0
    } else {
2562
0
      cpi->optimize_seg_arr[i] = cpi->sf.rd_sf.optimize_coefficients;
2563
0
    }
2564
0
  }
2565
0
  features->coded_lossless = is_coded_lossless(cm, xd);
2566
0
  features->all_lossless = features->coded_lossless && !av1_superres_scaled(cm);
2567
2568
  // Fix delta q resolution for the moment
2569
2570
0
  cm->delta_q_info.delta_q_res = 0;
2571
0
  if (cpi->use_ducky_encode) {
2572
0
    cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_DUCKY_ENCODE;
2573
0
  } else if (cpi->oxcf.q_cfg.aq_mode != CYCLIC_REFRESH_AQ &&
2574
0
             !cpi->roi.enabled) {
2575
0
    if (deltaq_mode == DELTA_Q_OBJECTIVE)
2576
0
      cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_OBJECTIVE;
2577
0
    else if (deltaq_mode == DELTA_Q_PERCEPTUAL)
2578
0
      cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
2579
0
    else if (deltaq_mode == DELTA_Q_PERCEPTUAL_AI)
2580
0
      cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
2581
0
    else if (deltaq_mode == DELTA_Q_USER_RATING_BASED)
2582
0
      cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
2583
0
    else if (deltaq_mode == DELTA_Q_HDR)
2584
0
      cm->delta_q_info.delta_q_res = DEFAULT_DELTA_Q_RES_PERCEPTUAL;
2585
0
    else if (deltaq_mode == DELTA_Q_VARIANCE_BOOST)
2586
0
      cm->delta_q_info.delta_q_res =
2587
0
          aom_get_variance_boost_delta_q_res(quant_params->base_qindex);
2588
    // Set delta_q_present_flag before it is used for the first time
2589
0
    cm->delta_q_info.delta_lf_res = DEFAULT_DELTA_LF_RES;
2590
0
    cm->delta_q_info.delta_q_present_flag = deltaq_mode != NO_DELTA_Q;
2591
2592
    // Turn off cm->delta_q_info.delta_q_present_flag if objective delta_q
2593
    // is used for ineligible frames. That effectively will turn off row_mt
2594
    // usage. Note objective delta_q and tpl eligible frames are only altref
2595
    // frames currently.
2596
0
    if (cm->delta_q_info.delta_q_present_flag) {
2597
0
      if (deltaq_mode == DELTA_Q_OBJECTIVE && !enable_delta_q(cpi))
2598
0
        cm->delta_q_info.delta_q_present_flag = 0;
2599
2600
0
      if (deltaq_mode == DELTA_Q_OBJECTIVE &&
2601
0
          cm->delta_q_info.delta_q_present_flag) {
2602
0
        cm->delta_q_info.delta_q_present_flag &= allow_deltaq_mode(cpi);
2603
0
      }
2604
0
    }
2605
2606
    // Reset delta_q_used flag
2607
0
    cpi->deltaq_used = 0;
2608
2609
0
    cm->delta_q_info.delta_lf_present_flag =
2610
0
        cm->delta_q_info.delta_q_present_flag &&
2611
0
        oxcf->tool_cfg.enable_deltalf_mode;
2612
0
    cm->delta_q_info.delta_lf_multi = DEFAULT_DELTA_LF_MULTI;
2613
2614
    // update delta_q_present_flag and delta_lf_present_flag based on
2615
    // base_qindex
2616
0
    cm->delta_q_info.delta_q_present_flag &= quant_params->base_qindex > 0;
2617
0
    cm->delta_q_info.delta_lf_present_flag &= quant_params->base_qindex > 0;
2618
0
  } else if (cpi->cyclic_refresh->apply_cyclic_refresh ||
2619
0
             cpi->svc.number_temporal_layers == 1) {
2620
0
    cpi->cyclic_refresh->actual_num_seg1_blocks = 0;
2621
0
    cpi->cyclic_refresh->actual_num_seg2_blocks = 0;
2622
0
  }
2623
0
  cpi->rc.cnt_zeromv = 0;
2624
0
  cpi->cb_delta_rdmult_enabled = enable_delta_rdmult(cpi);
2625
2626
0
  av1_frame_init_quantizer(cpi);
2627
0
  init_encode_frame_mb_context(cpi);
2628
0
  set_default_interp_skip_flags(cm, &cpi->interp_search_flags);
2629
2630
  // Like the decoder, only use the previous segment map if it has the size of
2631
  // this frame.
2632
0
  if (cm->prev_frame && cm->prev_frame->seg.enabled &&
2633
0
      cpi->svc.number_spatial_layers == 1 &&
2634
0
      cm->prev_frame->mi_rows == cm->mi_params.mi_rows &&
2635
0
      cm->prev_frame->mi_cols == cm->mi_params.mi_cols)
2636
0
    cm->last_frame_seg_map = cm->prev_frame->seg_map;
2637
0
  else
2638
0
    cm->last_frame_seg_map = NULL;
2639
0
  if (features->allow_intrabc || features->coded_lossless) {
2640
0
    av1_set_default_ref_deltas(cm->lf.ref_deltas);
2641
0
    av1_set_default_mode_deltas(cm->lf.mode_deltas);
2642
0
  } else if (cm->prev_frame) {
2643
0
    memcpy(cm->lf.ref_deltas, cm->prev_frame->ref_deltas, REF_FRAMES);
2644
0
    memcpy(cm->lf.mode_deltas, cm->prev_frame->mode_deltas, MAX_MODE_LF_DELTAS);
2645
0
  }
2646
0
  cm->lf.mode_ref_delta_enabled = oxcf->algo_cfg.mode_ref_delta_enabled;
2647
0
  memcpy(cm->cur_frame->ref_deltas, cm->lf.ref_deltas, REF_FRAMES);
2648
0
  memcpy(cm->cur_frame->mode_deltas, cm->lf.mode_deltas, MAX_MODE_LF_DELTAS);
2649
2650
0
  cpi->all_one_sided_refs =
2651
0
      frame_is_intra_only(cm) ? 0 : refs_are_one_sided(cm);
2652
2653
0
  cpi->prune_ref_frame_mask = 0;
2654
  // Figure out which ref frames can be skipped at frame level.
2655
0
  setup_prune_ref_frame_mask(cpi);
2656
  // Disable certain reference frame pruning based on temporal distance and
2657
  // quality of that reference frame.
2658
0
  setup_keep_ref_frame_mask(cpi);
2659
2660
0
  x->txfm_search_info.txb_split_count = 0;
2661
#if CONFIG_SPEED_STATS
2662
  x->txfm_search_info.tx_search_count = 0;
2663
#endif  // CONFIG_SPEED_STATS
2664
2665
0
#if !CONFIG_REALTIME_ONLY
2666
#if CONFIG_COLLECT_COMPONENT_TIMING
2667
  start_timing(cpi, av1_compute_global_motion_time);
2668
#endif
2669
0
  av1_compute_global_motion_facade(cpi);
2670
#if CONFIG_COLLECT_COMPONENT_TIMING
2671
  end_timing(cpi, av1_compute_global_motion_time);
2672
#endif
2673
0
#endif  // !CONFIG_REALTIME_ONLY
2674
2675
#if CONFIG_COLLECT_COMPONENT_TIMING
2676
  start_timing(cpi, av1_setup_motion_field_time);
2677
#endif
2678
0
  av1_calculate_ref_frame_side(cm);
2679
2680
0
  features->allow_ref_frame_mvs &= !(cpi->sf.hl_sf.ref_frame_mvs_lvl == 2);
2681
0
  if (features->allow_ref_frame_mvs) av1_setup_motion_field(cm);
2682
0
#if !CONFIG_REALTIME_ONLY
2683
0
  check_to_disable_ref_frame_mvs(cpi);
2684
0
#endif  // !CONFIG_REALTIME_ONLY
2685
2686
#if CONFIG_COLLECT_COMPONENT_TIMING
2687
  end_timing(cpi, av1_setup_motion_field_time);
2688
#endif
2689
2690
0
  cm->current_frame.skip_mode_info.skip_mode_flag =
2691
0
      check_skip_mode_enabled(cpi);
2692
2693
  // Initialization of skip mode cost depends on the value of
2694
  // 'skip_mode_flag'. This initialization happens in the function
2695
  // av1_fill_mode_rates(), which is in turn called in
2696
  // av1_initialize_rd_consts(). Thus, av1_initialize_rd_consts()
2697
  // has to be called after 'skip_mode_flag' is initialized.
2698
0
  av1_initialize_rd_consts(cpi);
2699
0
  av1_set_sad_per_bit(cpi, &x->sadperbit, quant_params->base_qindex);
2700
0
  populate_thresh_to_force_zeromv_skip(cpi);
2701
2702
0
  enc_row_mt->sync_read_ptr = av1_row_mt_sync_read_dummy;
2703
0
  enc_row_mt->sync_write_ptr = av1_row_mt_sync_write_dummy;
2704
0
  mt_info->row_mt_enabled = 0;
2705
0
  mt_info->pack_bs_mt_enabled = AOMMIN(mt_info->num_mod_workers[MOD_PACK_BS],
2706
0
                                       cm->tiles.cols * cm->tiles.rows) > 1;
2707
2708
0
  if (oxcf->row_mt && (mt_info->num_mod_workers[MOD_ENC] > 1)) {
2709
0
    mt_info->row_mt_enabled = 1;
2710
0
    enc_row_mt->sync_read_ptr = av1_row_mt_sync_read;
2711
0
    enc_row_mt->sync_write_ptr = av1_row_mt_sync_write;
2712
0
    av1_encode_tiles_row_mt(cpi);
2713
0
  } else {
2714
0
    const int num_workers = AOMMIN(mt_info->num_mod_workers[MOD_ENC],
2715
0
                                   cm->tiles.cols * cm->tiles.rows);
2716
0
    if (num_workers > 1) {
2717
0
      av1_encode_tiles_mt(cpi);
2718
0
    } else {
2719
      // Preallocate the pc_tree for realtime coding to reduce the cost of
2720
      // memory allocation.
2721
0
      const int use_nonrd_mode = cpi->sf.rt_sf.use_nonrd_pick_mode;
2722
0
      if (use_nonrd_mode) {
2723
0
        td->pc_root = av1_alloc_pc_tree_node(cm->seq_params->sb_size);
2724
0
        if (!td->pc_root)
2725
0
          aom_internal_error(xd->error_info, AOM_CODEC_MEM_ERROR,
2726
0
                             "Failed to allocate PC_TREE");
2727
0
      } else {
2728
0
        td->pc_root = NULL;
2729
0
      }
2730
2731
0
      encode_tiles(cpi);
2732
0
      av1_free_pc_tree_recursive(td->pc_root, av1_num_planes(cm), 0, 0,
2733
0
                                 cpi->sf.part_sf.partition_search_type);
2734
0
      td->pc_root = NULL;
2735
0
    }
2736
0
  }
2737
2738
  // If intrabc is allowed but never selected, reset the allow_intrabc flag.
2739
0
  if (features->allow_intrabc && !cpi->intrabc_used) {
2740
0
    features->allow_intrabc = 0;
2741
0
  }
2742
0
  if (features->allow_intrabc) {
2743
0
    cm->delta_q_info.delta_lf_present_flag = 0;
2744
0
  }
2745
2746
0
  if (cm->delta_q_info.delta_q_present_flag && cpi->deltaq_used == 0) {
2747
0
    cm->delta_q_info.delta_q_present_flag = 0;
2748
0
  }
2749
2750
  // Set the transform size appropriately before bitstream creation
2751
0
  const MODE_EVAL_TYPE eval_type =
2752
0
      cpi->sf.winner_mode_sf.enable_winner_mode_for_tx_size_srch
2753
0
          ? WINNER_MODE_EVAL
2754
0
          : DEFAULT_EVAL;
2755
0
  const TX_SIZE_SEARCH_METHOD tx_search_type =
2756
0
      cpi->winner_mode_params.tx_size_search_methods[eval_type];
2757
0
  assert(oxcf->txfm_cfg.enable_tx64 || tx_search_type != USE_LARGESTALL);
2758
0
  features->tx_mode = select_tx_mode(cm, tx_search_type);
2759
2760
  // Retain the frame level probability update conditions for parallel frames.
2761
  // These conditions will be consumed during postencode stage to update the
2762
  // probability.
2763
0
  if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2764
0
    cpi->do_update_frame_probs_txtype[cpi->num_frame_recode] =
2765
0
        cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats;
2766
0
    cpi->do_update_frame_probs_obmc[cpi->num_frame_recode] =
2767
0
        (cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
2768
0
         cpi->sf.inter_sf.prune_obmc_prob_thresh < INT_MAX);
2769
0
    cpi->do_update_frame_probs_warp[cpi->num_frame_recode] =
2770
0
        (features->allow_warped_motion &&
2771
0
         cpi->sf.inter_sf.prune_warped_prob_thresh > 0);
2772
0
    cpi->do_update_frame_probs_interpfilter[cpi->num_frame_recode] =
2773
0
        (cm->current_frame.frame_type != KEY_FRAME &&
2774
0
         cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
2775
0
         features->interp_filter == SWITCHABLE);
2776
0
  }
2777
2778
0
  if (cpi->sf.tx_sf.tx_type_search.prune_tx_type_using_stats ||
2779
0
      ((cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh !=
2780
0
        INT_MAX) &&
2781
0
       (cpi->sf.tx_sf.tx_type_search.fast_inter_tx_type_prob_thresh != 0))) {
2782
0
    const FRAME_UPDATE_TYPE update_type =
2783
0
        get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2784
0
    for (i = 0; i < TX_SIZES_ALL; i++) {
2785
0
      int sum = 0;
2786
0
      int j;
2787
0
      int left = MAX_TX_TYPE_PROB;
2788
2789
0
      for (j = 0; j < TX_TYPES; j++)
2790
0
        sum += cpi->td.rd_counts.tx_type_used[i][j];
2791
2792
0
      for (j = TX_TYPES - 1; j >= 0; j--) {
2793
0
        int update_txtype_frameprobs = 1;
2794
0
        const int new_prob =
2795
0
            sum ? (int)((int64_t)MAX_TX_TYPE_PROB *
2796
0
                        cpi->td.rd_counts.tx_type_used[i][j] / sum)
2797
0
                : (j ? 0 : MAX_TX_TYPE_PROB);
2798
#if CONFIG_FPMT_TEST
2799
        if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2800
          if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
2801
              0) {
2802
            int prob =
2803
                (temp_frame_probs_simulation->tx_type_probs[update_type][i][j] +
2804
                 new_prob) >>
2805
                1;
2806
            left -= prob;
2807
            if (j == 0) prob += left;
2808
            temp_frame_probs_simulation->tx_type_probs[update_type][i][j] =
2809
                prob;
2810
            // Copy temp_frame_probs_simulation to temp_frame_probs
2811
            for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2812
                 update_type_idx++) {
2813
              temp_frame_probs->tx_type_probs[update_type_idx][i][j] =
2814
                  temp_frame_probs_simulation
2815
                      ->tx_type_probs[update_type_idx][i][j];
2816
            }
2817
          }
2818
          update_txtype_frameprobs = 0;
2819
        }
2820
#endif  // CONFIG_FPMT_TEST
2821
        // Track the frame probabilities of parallel encode frames to update
2822
        // during postencode stage.
2823
0
        if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2824
0
          update_txtype_frameprobs = 0;
2825
0
          cpi->frame_new_probs[cpi->num_frame_recode]
2826
0
              .tx_type_probs[update_type][i][j] = new_prob;
2827
0
        }
2828
0
        if (update_txtype_frameprobs) {
2829
0
          int prob =
2830
0
              (frame_probs->tx_type_probs[update_type][i][j] + new_prob) >> 1;
2831
0
          left -= prob;
2832
0
          if (j == 0) prob += left;
2833
0
          frame_probs->tx_type_probs[update_type][i][j] = prob;
2834
0
        }
2835
0
      }
2836
0
    }
2837
0
  }
2838
2839
0
  if (cm->seg.enabled) {
2840
0
    cm->seg.temporal_update = 1;
2841
0
    if (rdc->seg_tmp_pred_cost[0] < rdc->seg_tmp_pred_cost[1])
2842
0
      cm->seg.temporal_update = 0;
2843
0
  }
2844
2845
0
  if (cpi->sf.inter_sf.prune_obmc_prob_thresh > 0 &&
2846
0
      cpi->sf.inter_sf.prune_obmc_prob_thresh < INT_MAX) {
2847
0
    const FRAME_UPDATE_TYPE update_type =
2848
0
        get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2849
2850
0
    for (i = 0; i < BLOCK_SIZES_ALL; i++) {
2851
0
      int sum = 0;
2852
0
      int update_obmc_frameprobs = 1;
2853
0
      for (int j = 0; j < 2; j++) sum += cpi->td.rd_counts.obmc_used[i][j];
2854
2855
0
      const int new_prob =
2856
0
          sum ? 128 * cpi->td.rd_counts.obmc_used[i][1] / sum : 0;
2857
#if CONFIG_FPMT_TEST
2858
      if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2859
        if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2860
          temp_frame_probs_simulation->obmc_probs[update_type][i] =
2861
              (temp_frame_probs_simulation->obmc_probs[update_type][i] +
2862
               new_prob) >>
2863
              1;
2864
          // Copy temp_frame_probs_simulation to temp_frame_probs
2865
          for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2866
               update_type_idx++) {
2867
            temp_frame_probs->obmc_probs[update_type_idx][i] =
2868
                temp_frame_probs_simulation->obmc_probs[update_type_idx][i];
2869
          }
2870
        }
2871
        update_obmc_frameprobs = 0;
2872
      }
2873
#endif  // CONFIG_FPMT_TEST
2874
      // Track the frame probabilities of parallel encode frames to update
2875
      // during postencode stage.
2876
0
      if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2877
0
        update_obmc_frameprobs = 0;
2878
0
        cpi->frame_new_probs[cpi->num_frame_recode].obmc_probs[update_type][i] =
2879
0
            new_prob;
2880
0
      }
2881
0
      if (update_obmc_frameprobs) {
2882
0
        frame_probs->obmc_probs[update_type][i] =
2883
0
            (frame_probs->obmc_probs[update_type][i] + new_prob) >> 1;
2884
0
      }
2885
0
    }
2886
0
  }
2887
2888
0
  if (features->allow_warped_motion &&
2889
0
      cpi->sf.inter_sf.prune_warped_prob_thresh > 0) {
2890
0
    const FRAME_UPDATE_TYPE update_type =
2891
0
        get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2892
0
    int update_warp_frameprobs = 1;
2893
0
    int sum = 0;
2894
0
    for (i = 0; i < 2; i++) sum += cpi->td.rd_counts.warped_used[i];
2895
0
    const int new_prob = sum ? 128 * cpi->td.rd_counts.warped_used[1] / sum : 0;
2896
#if CONFIG_FPMT_TEST
2897
    if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2898
      if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] == 0) {
2899
        temp_frame_probs_simulation->warped_probs[update_type] =
2900
            (temp_frame_probs_simulation->warped_probs[update_type] +
2901
             new_prob) >>
2902
            1;
2903
        // Copy temp_frame_probs_simulation to temp_frame_probs
2904
        for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2905
             update_type_idx++) {
2906
          temp_frame_probs->warped_probs[update_type_idx] =
2907
              temp_frame_probs_simulation->warped_probs[update_type_idx];
2908
        }
2909
      }
2910
      update_warp_frameprobs = 0;
2911
    }
2912
#endif  // CONFIG_FPMT_TEST
2913
    // Track the frame probabilities of parallel encode frames to update
2914
    // during postencode stage.
2915
0
    if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2916
0
      update_warp_frameprobs = 0;
2917
0
      cpi->frame_new_probs[cpi->num_frame_recode].warped_probs[update_type] =
2918
0
          new_prob;
2919
0
    }
2920
0
    if (update_warp_frameprobs) {
2921
0
      frame_probs->warped_probs[update_type] =
2922
0
          (frame_probs->warped_probs[update_type] + new_prob) >> 1;
2923
0
    }
2924
0
  }
2925
2926
0
  if (cm->current_frame.frame_type != KEY_FRAME &&
2927
0
      cpi->sf.interp_sf.adaptive_interp_filter_search == 2 &&
2928
0
      features->interp_filter == SWITCHABLE) {
2929
0
    const FRAME_UPDATE_TYPE update_type =
2930
0
        get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
2931
2932
0
    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) {
2933
0
      int sum = 0;
2934
0
      int j;
2935
0
      int left = 1536;
2936
2937
0
      for (j = 0; j < SWITCHABLE_FILTERS; j++) {
2938
0
        sum += cpi->td.counts->switchable_interp[i][j];
2939
0
      }
2940
2941
0
      for (j = SWITCHABLE_FILTERS - 1; j >= 0; j--) {
2942
0
        int update_interpfilter_frameprobs = 1;
2943
0
        const int new_prob =
2944
0
            sum ? 1536 * cpi->td.counts->switchable_interp[i][j] / sum
2945
0
                : (j ? 0 : 1536);
2946
#if CONFIG_FPMT_TEST
2947
        if (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) {
2948
          if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] ==
2949
              0) {
2950
            int prob = (temp_frame_probs_simulation
2951
                            ->switchable_interp_probs[update_type][i][j] +
2952
                        new_prob) >>
2953
                       1;
2954
            left -= prob;
2955
            if (j == 0) prob += left;
2956
            temp_frame_probs_simulation
2957
                ->switchable_interp_probs[update_type][i][j] = prob;
2958
            // Copy temp_frame_probs_simulation to temp_frame_probs
2959
            for (int update_type_idx = 0; update_type_idx < FRAME_UPDATE_TYPES;
2960
                 update_type_idx++) {
2961
              temp_frame_probs->switchable_interp_probs[update_type_idx][i][j] =
2962
                  temp_frame_probs_simulation
2963
                      ->switchable_interp_probs[update_type_idx][i][j];
2964
            }
2965
          }
2966
          update_interpfilter_frameprobs = 0;
2967
        }
2968
#endif  // CONFIG_FPMT_TEST
2969
        // Track the frame probabilities of parallel encode frames to update
2970
        // during postencode stage.
2971
0
        if (cpi->ppi->gf_group.frame_parallel_level[cpi->gf_frame_index] > 0) {
2972
0
          update_interpfilter_frameprobs = 0;
2973
0
          cpi->frame_new_probs[cpi->num_frame_recode]
2974
0
              .switchable_interp_probs[update_type][i][j] = new_prob;
2975
0
        }
2976
0
        if (update_interpfilter_frameprobs) {
2977
0
          int prob = (frame_probs->switchable_interp_probs[update_type][i][j] +
2978
0
                      new_prob) >>
2979
0
                     1;
2980
0
          left -= prob;
2981
0
          if (j == 0) prob += left;
2982
0
          frame_probs->switchable_interp_probs[update_type][i][j] = prob;
2983
0
        }
2984
0
      }
2985
0
    }
2986
0
  }
2987
0
}
2988
2989
/*!\brief Setup reference frame buffers and encode a frame
2990
 *
2991
 * \ingroup high_level_algo
2992
 * \callgraph
2993
 * \callergraph
2994
 *
2995
 * \param[in]    cpi    Top-level encoder structure
2996
 */
2997
0
void av1_encode_frame(AV1_COMP *cpi) {
2998
0
  AV1_COMMON *const cm = &cpi->common;
2999
0
  CurrentFrame *const current_frame = &cm->current_frame;
3000
0
  FeatureFlags *const features = &cm->features;
3001
0
  RD_COUNTS *const rdc = &cpi->td.rd_counts;
3002
0
  const AV1EncoderConfig *const oxcf = &cpi->oxcf;
3003
  // Indicates whether or not to use a default reduced set for ext-tx
3004
  // rather than the potential full set of 16 transforms
3005
0
  features->reduced_tx_set_used = oxcf->txfm_cfg.reduced_tx_type_set;
3006
3007
  // Make sure segment_id is no larger than last_active_segid.
3008
0
  if (cm->seg.enabled && cm->seg.update_map) {
3009
0
    const int mi_rows = cm->mi_params.mi_rows;
3010
0
    const int mi_cols = cm->mi_params.mi_cols;
3011
0
    const int last_active_segid = cm->seg.last_active_segid;
3012
0
    uint8_t *map = cpi->enc_seg.map;
3013
0
    for (int mi_row = 0; mi_row < mi_rows; ++mi_row) {
3014
0
      for (int mi_col = 0; mi_col < mi_cols; ++mi_col) {
3015
0
        map[mi_col] = AOMMIN(map[mi_col], last_active_segid);
3016
0
      }
3017
0
      map += mi_cols;
3018
0
    }
3019
0
  }
3020
3021
0
  av1_setup_frame_buf_refs(cm);
3022
0
  enforce_max_ref_frames(cpi, &cpi->ref_frame_flags,
3023
0
                         cm->cur_frame->ref_display_order_hint,
3024
0
                         cm->current_frame.display_order_hint);
3025
0
  set_rel_frame_dist(&cpi->common, &cpi->ref_frame_dist_info,
3026
0
                     cpi->ref_frame_flags);
3027
0
  av1_setup_frame_sign_bias(cm);
3028
3029
  // If global motion is enabled, then every buffer which is used as either
3030
  // a source or a ref frame should have an image pyramid allocated.
3031
  // Check here so that issues can be caught early in debug mode
3032
0
#if !defined(NDEBUG) && !CONFIG_REALTIME_ONLY
3033
0
  if (cpi->alloc_pyramid) {
3034
0
    assert(cpi->source->y_pyramid);
3035
0
    for (int ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3036
0
      const RefCntBuffer *const buf = get_ref_frame_buf(cm, ref_frame);
3037
0
      if (buf != NULL) {
3038
0
        assert(buf->buf.y_pyramid);
3039
0
      }
3040
0
    }
3041
0
  }
3042
0
#endif  // !defined(NDEBUG) && !CONFIG_REALTIME_ONLY
3043
3044
#if CONFIG_MISMATCH_DEBUG
3045
  mismatch_reset_frame(av1_num_planes(cm));
3046
#endif
3047
3048
0
  rdc->newmv_or_intra_blocks = 0;
3049
0
  cpi->palette_pixel_num = 0;
3050
3051
0
  if (cpi->sf.hl_sf.frame_parameter_update ||
3052
0
      cpi->sf.rt_sf.use_comp_ref_nonrd) {
3053
0
    if (frame_is_intra_only(cm))
3054
0
      current_frame->reference_mode = SINGLE_REFERENCE;
3055
0
    else
3056
0
      current_frame->reference_mode = REFERENCE_MODE_SELECT;
3057
3058
0
    features->interp_filter = SWITCHABLE;
3059
0
    if (cm->tiles.large_scale) features->interp_filter = EIGHTTAP_REGULAR;
3060
3061
0
    features->switchable_motion_mode = is_switchable_motion_mode_allowed(
3062
0
        features->allow_warped_motion, oxcf->motion_mode_cfg.enable_obmc);
3063
3064
0
    rdc->compound_ref_used_flag = 0;
3065
0
    rdc->skip_mode_used_flag = 0;
3066
3067
0
    encode_frame_internal(cpi);
3068
3069
0
    if (current_frame->reference_mode == REFERENCE_MODE_SELECT) {
3070
      // Use a flag that includes 4x4 blocks
3071
0
      if (rdc->compound_ref_used_flag == 0) {
3072
0
        current_frame->reference_mode = SINGLE_REFERENCE;
3073
#if CONFIG_ENTROPY_STATS
3074
        av1_zero(cpi->td.counts->comp_inter);
3075
#endif  // CONFIG_ENTROPY_STATS
3076
0
      }
3077
0
    }
3078
    // Re-check on the skip mode status as reference mode may have been
3079
    // changed.
3080
0
    SkipModeInfo *const skip_mode_info = &current_frame->skip_mode_info;
3081
0
    if (frame_is_intra_only(cm) ||
3082
0
        current_frame->reference_mode == SINGLE_REFERENCE) {
3083
0
      skip_mode_info->skip_mode_allowed = 0;
3084
0
      skip_mode_info->skip_mode_flag = 0;
3085
0
    }
3086
0
    if (skip_mode_info->skip_mode_flag && rdc->skip_mode_used_flag == 0)
3087
0
      skip_mode_info->skip_mode_flag = 0;
3088
3089
0
    if (!cm->tiles.large_scale) {
3090
0
      if (features->tx_mode == TX_MODE_SELECT &&
3091
0
          cpi->td.mb.txfm_search_info.txb_split_count == 0)
3092
0
        features->tx_mode = TX_MODE_LARGEST;
3093
0
    }
3094
0
  } else {
3095
    // This is needed if real-time speed setting is changed on the fly
3096
    // from one using compound prediction to one using single reference.
3097
0
    if (current_frame->reference_mode == REFERENCE_MODE_SELECT)
3098
0
      current_frame->reference_mode = SINGLE_REFERENCE;
3099
0
    encode_frame_internal(cpi);
3100
0
  }
3101
0
}