Coverage Report

Created: 2026-04-01 07:49

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