Coverage Report

Created: 2026-09-11 06:36

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavif/ext/aom/av1/encoder/rdopt.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 <assert.h>
13
#include <math.h>
14
#include <stdbool.h>
15
#include <stdint.h>
16
#include <string.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/blend.h"
24
#include "aom_mem/aom_mem.h"
25
#include "aom_ports/aom_timer.h"
26
#include "aom_ports/mem.h"
27
28
#include "av1/common/av1_common_int.h"
29
#include "av1/common/cfl.h"
30
#include "av1/common/blockd.h"
31
#include "av1/common/common.h"
32
#include "av1/common/common_data.h"
33
#include "av1/common/entropy.h"
34
#include "av1/common/entropymode.h"
35
#include "av1/common/enums.h"
36
#include "av1/common/idct.h"
37
#include "av1/common/mvref_common.h"
38
#include "av1/common/obmc.h"
39
#include "av1/common/pred_common.h"
40
#include "av1/common/quant_common.h"
41
#include "av1/common/reconinter.h"
42
#include "av1/common/reconintra.h"
43
#include "av1/common/scan.h"
44
#include "av1/common/seg_common.h"
45
#include "av1/common/txb_common.h"
46
#include "av1/common/warped_motion.h"
47
48
#include "av1/encoder/aq_variance.h"
49
#include "av1/encoder/av1_quantize.h"
50
#include "av1/encoder/block.h"
51
#include "av1/encoder/cost.h"
52
#include "av1/encoder/compound_type.h"
53
#include "av1/encoder/encodemb.h"
54
#include "av1/encoder/encodemv.h"
55
#include "av1/encoder/encoder.h"
56
#include "av1/encoder/encodetxb.h"
57
#include "av1/encoder/hybrid_fwd_txfm.h"
58
#include "av1/encoder/interp_search.h"
59
#include "av1/encoder/intra_mode_search.h"
60
#include "av1/encoder/intra_mode_search_utils.h"
61
#include "av1/encoder/mcomp.h"
62
#include "av1/encoder/ml.h"
63
#include "av1/encoder/mode_prune_model_weights.h"
64
#include "av1/encoder/model_rd.h"
65
#include "av1/encoder/motion_search_facade.h"
66
#include "av1/encoder/palette.h"
67
#include "av1/encoder/pustats.h"
68
#include "av1/encoder/random.h"
69
#include "av1/encoder/ratectrl.h"
70
#include "av1/encoder/rd.h"
71
#include "av1/encoder/rdopt.h"
72
#include "av1/encoder/reconinter_enc.h"
73
#include "av1/encoder/tokenize.h"
74
#include "av1/encoder/tpl_model.h"
75
#include "av1/encoder/tx_search.h"
76
#include "av1/encoder/var_based_part.h"
77
78
8.12M
#define LAST_NEW_MV_INDEX 6
79
80
// Mode_threshold multiplication factor table for prune_inter_modes_if_skippable
81
// The values are kept in Q12 format and equation used to derive is
82
// (2.5 - ((float)x->qindex / MAXQ) * 1.5)
83
11.5M
#define MODE_THRESH_QBITS 12
84
static const int mode_threshold_mul_factor[QINDEX_RANGE] = {
85
  10240, 10216, 10192, 10168, 10144, 10120, 10095, 10071, 10047, 10023, 9999,
86
  9975,  9951,  9927,  9903,  9879,  9854,  9830,  9806,  9782,  9758,  9734,
87
  9710,  9686,  9662,  9638,  9614,  9589,  9565,  9541,  9517,  9493,  9469,
88
  9445,  9421,  9397,  9373,  9349,  9324,  9300,  9276,  9252,  9228,  9204,
89
  9180,  9156,  9132,  9108,  9083,  9059,  9035,  9011,  8987,  8963,  8939,
90
  8915,  8891,  8867,  8843,  8818,  8794,  8770,  8746,  8722,  8698,  8674,
91
  8650,  8626,  8602,  8578,  8553,  8529,  8505,  8481,  8457,  8433,  8409,
92
  8385,  8361,  8337,  8312,  8288,  8264,  8240,  8216,  8192,  8168,  8144,
93
  8120,  8096,  8072,  8047,  8023,  7999,  7975,  7951,  7927,  7903,  7879,
94
  7855,  7831,  7806,  7782,  7758,  7734,  7710,  7686,  7662,  7638,  7614,
95
  7590,  7566,  7541,  7517,  7493,  7469,  7445,  7421,  7397,  7373,  7349,
96
  7325,  7301,  7276,  7252,  7228,  7204,  7180,  7156,  7132,  7108,  7084,
97
  7060,  7035,  7011,  6987,  6963,  6939,  6915,  6891,  6867,  6843,  6819,
98
  6795,  6770,  6746,  6722,  6698,  6674,  6650,  6626,  6602,  6578,  6554,
99
  6530,  6505,  6481,  6457,  6433,  6409,  6385,  6361,  6337,  6313,  6289,
100
  6264,  6240,  6216,  6192,  6168,  6144,  6120,  6096,  6072,  6048,  6024,
101
  5999,  5975,  5951,  5927,  5903,  5879,  5855,  5831,  5807,  5783,  5758,
102
  5734,  5710,  5686,  5662,  5638,  5614,  5590,  5566,  5542,  5518,  5493,
103
  5469,  5445,  5421,  5397,  5373,  5349,  5325,  5301,  5277,  5253,  5228,
104
  5204,  5180,  5156,  5132,  5108,  5084,  5060,  5036,  5012,  4987,  4963,
105
  4939,  4915,  4891,  4867,  4843,  4819,  4795,  4771,  4747,  4722,  4698,
106
  4674,  4650,  4626,  4602,  4578,  4554,  4530,  4506,  4482,  4457,  4433,
107
  4409,  4385,  4361,  4337,  4313,  4289,  4265,  4241,  4216,  4192,  4168,
108
  4144,  4120,  4096
109
};
110
111
static const THR_MODES av1_default_mode_order[MAX_MODES] = {
112
  THR_NEARESTMV,
113
  THR_NEARESTL2,
114
  THR_NEARESTL3,
115
  THR_NEARESTB,
116
  THR_NEARESTA2,
117
  THR_NEARESTA,
118
  THR_NEARESTG,
119
120
  THR_NEWMV,
121
  THR_NEWL2,
122
  THR_NEWL3,
123
  THR_NEWB,
124
  THR_NEWA2,
125
  THR_NEWA,
126
  THR_NEWG,
127
128
  THR_NEARMV,
129
  THR_NEARL2,
130
  THR_NEARL3,
131
  THR_NEARB,
132
  THR_NEARA2,
133
  THR_NEARA,
134
  THR_NEARG,
135
136
  THR_GLOBALMV,
137
  THR_GLOBALL2,
138
  THR_GLOBALL3,
139
  THR_GLOBALB,
140
  THR_GLOBALA2,
141
  THR_GLOBALA,
142
  THR_GLOBALG,
143
144
  THR_COMP_NEAREST_NEARESTLA,
145
  THR_COMP_NEAREST_NEARESTL2A,
146
  THR_COMP_NEAREST_NEARESTL3A,
147
  THR_COMP_NEAREST_NEARESTGA,
148
  THR_COMP_NEAREST_NEARESTLB,
149
  THR_COMP_NEAREST_NEARESTL2B,
150
  THR_COMP_NEAREST_NEARESTL3B,
151
  THR_COMP_NEAREST_NEARESTGB,
152
  THR_COMP_NEAREST_NEARESTLA2,
153
  THR_COMP_NEAREST_NEARESTL2A2,
154
  THR_COMP_NEAREST_NEARESTL3A2,
155
  THR_COMP_NEAREST_NEARESTGA2,
156
  THR_COMP_NEAREST_NEARESTLL2,
157
  THR_COMP_NEAREST_NEARESTLL3,
158
  THR_COMP_NEAREST_NEARESTLG,
159
  THR_COMP_NEAREST_NEARESTBA,
160
161
  THR_COMP_NEAR_NEARLB,
162
  THR_COMP_NEW_NEWLB,
163
  THR_COMP_NEW_NEARESTLB,
164
  THR_COMP_NEAREST_NEWLB,
165
  THR_COMP_NEW_NEARLB,
166
  THR_COMP_NEAR_NEWLB,
167
  THR_COMP_GLOBAL_GLOBALLB,
168
169
  THR_COMP_NEAR_NEARLA,
170
  THR_COMP_NEW_NEWLA,
171
  THR_COMP_NEW_NEARESTLA,
172
  THR_COMP_NEAREST_NEWLA,
173
  THR_COMP_NEW_NEARLA,
174
  THR_COMP_NEAR_NEWLA,
175
  THR_COMP_GLOBAL_GLOBALLA,
176
177
  THR_COMP_NEAR_NEARL2A,
178
  THR_COMP_NEW_NEWL2A,
179
  THR_COMP_NEW_NEARESTL2A,
180
  THR_COMP_NEAREST_NEWL2A,
181
  THR_COMP_NEW_NEARL2A,
182
  THR_COMP_NEAR_NEWL2A,
183
  THR_COMP_GLOBAL_GLOBALL2A,
184
185
  THR_COMP_NEAR_NEARL3A,
186
  THR_COMP_NEW_NEWL3A,
187
  THR_COMP_NEW_NEARESTL3A,
188
  THR_COMP_NEAREST_NEWL3A,
189
  THR_COMP_NEW_NEARL3A,
190
  THR_COMP_NEAR_NEWL3A,
191
  THR_COMP_GLOBAL_GLOBALL3A,
192
193
  THR_COMP_NEAR_NEARGA,
194
  THR_COMP_NEW_NEWGA,
195
  THR_COMP_NEW_NEARESTGA,
196
  THR_COMP_NEAREST_NEWGA,
197
  THR_COMP_NEW_NEARGA,
198
  THR_COMP_NEAR_NEWGA,
199
  THR_COMP_GLOBAL_GLOBALGA,
200
201
  THR_COMP_NEAR_NEARL2B,
202
  THR_COMP_NEW_NEWL2B,
203
  THR_COMP_NEW_NEARESTL2B,
204
  THR_COMP_NEAREST_NEWL2B,
205
  THR_COMP_NEW_NEARL2B,
206
  THR_COMP_NEAR_NEWL2B,
207
  THR_COMP_GLOBAL_GLOBALL2B,
208
209
  THR_COMP_NEAR_NEARL3B,
210
  THR_COMP_NEW_NEWL3B,
211
  THR_COMP_NEW_NEARESTL3B,
212
  THR_COMP_NEAREST_NEWL3B,
213
  THR_COMP_NEW_NEARL3B,
214
  THR_COMP_NEAR_NEWL3B,
215
  THR_COMP_GLOBAL_GLOBALL3B,
216
217
  THR_COMP_NEAR_NEARGB,
218
  THR_COMP_NEW_NEWGB,
219
  THR_COMP_NEW_NEARESTGB,
220
  THR_COMP_NEAREST_NEWGB,
221
  THR_COMP_NEW_NEARGB,
222
  THR_COMP_NEAR_NEWGB,
223
  THR_COMP_GLOBAL_GLOBALGB,
224
225
  THR_COMP_NEAR_NEARLA2,
226
  THR_COMP_NEW_NEWLA2,
227
  THR_COMP_NEW_NEARESTLA2,
228
  THR_COMP_NEAREST_NEWLA2,
229
  THR_COMP_NEW_NEARLA2,
230
  THR_COMP_NEAR_NEWLA2,
231
  THR_COMP_GLOBAL_GLOBALLA2,
232
233
  THR_COMP_NEAR_NEARL2A2,
234
  THR_COMP_NEW_NEWL2A2,
235
  THR_COMP_NEW_NEARESTL2A2,
236
  THR_COMP_NEAREST_NEWL2A2,
237
  THR_COMP_NEW_NEARL2A2,
238
  THR_COMP_NEAR_NEWL2A2,
239
  THR_COMP_GLOBAL_GLOBALL2A2,
240
241
  THR_COMP_NEAR_NEARL3A2,
242
  THR_COMP_NEW_NEWL3A2,
243
  THR_COMP_NEW_NEARESTL3A2,
244
  THR_COMP_NEAREST_NEWL3A2,
245
  THR_COMP_NEW_NEARL3A2,
246
  THR_COMP_NEAR_NEWL3A2,
247
  THR_COMP_GLOBAL_GLOBALL3A2,
248
249
  THR_COMP_NEAR_NEARGA2,
250
  THR_COMP_NEW_NEWGA2,
251
  THR_COMP_NEW_NEARESTGA2,
252
  THR_COMP_NEAREST_NEWGA2,
253
  THR_COMP_NEW_NEARGA2,
254
  THR_COMP_NEAR_NEWGA2,
255
  THR_COMP_GLOBAL_GLOBALGA2,
256
257
  THR_COMP_NEAR_NEARLL2,
258
  THR_COMP_NEW_NEWLL2,
259
  THR_COMP_NEW_NEARESTLL2,
260
  THR_COMP_NEAREST_NEWLL2,
261
  THR_COMP_NEW_NEARLL2,
262
  THR_COMP_NEAR_NEWLL2,
263
  THR_COMP_GLOBAL_GLOBALLL2,
264
265
  THR_COMP_NEAR_NEARLL3,
266
  THR_COMP_NEW_NEWLL3,
267
  THR_COMP_NEW_NEARESTLL3,
268
  THR_COMP_NEAREST_NEWLL3,
269
  THR_COMP_NEW_NEARLL3,
270
  THR_COMP_NEAR_NEWLL3,
271
  THR_COMP_GLOBAL_GLOBALLL3,
272
273
  THR_COMP_NEAR_NEARLG,
274
  THR_COMP_NEW_NEWLG,
275
  THR_COMP_NEW_NEARESTLG,
276
  THR_COMP_NEAREST_NEWLG,
277
  THR_COMP_NEW_NEARLG,
278
  THR_COMP_NEAR_NEWLG,
279
  THR_COMP_GLOBAL_GLOBALLG,
280
281
  THR_COMP_NEAR_NEARBA,
282
  THR_COMP_NEW_NEWBA,
283
  THR_COMP_NEW_NEARESTBA,
284
  THR_COMP_NEAREST_NEWBA,
285
  THR_COMP_NEW_NEARBA,
286
  THR_COMP_NEAR_NEWBA,
287
  THR_COMP_GLOBAL_GLOBALBA,
288
289
  THR_DC,
290
  THR_PAETH,
291
  THR_SMOOTH,
292
  THR_SMOOTH_V,
293
  THR_SMOOTH_H,
294
  THR_H_PRED,
295
  THR_V_PRED,
296
  THR_D135_PRED,
297
  THR_D203_PRED,
298
  THR_D157_PRED,
299
  THR_D67_PRED,
300
  THR_D113_PRED,
301
  THR_D45_PRED,
302
};
303
304
/*!\cond */
305
typedef struct SingleInterModeState {
306
  int64_t rd;
307
  MV_REFERENCE_FRAME ref_frame;
308
  int valid;
309
} SingleInterModeState;
310
311
typedef struct InterModeSearchState {
312
  int64_t best_rd;
313
  int64_t best_skip_rd[2];
314
  MB_MODE_INFO best_mbmode;
315
  int best_rate_y;
316
  int best_rate_uv;
317
  int best_mode_skippable;
318
  int best_skip2;
319
  THR_MODES best_mode_index;
320
  int num_available_refs;
321
  int64_t dist_refs[REF_FRAMES];
322
  int dist_order_refs[REF_FRAMES];
323
  int64_t mode_threshold[MAX_MODES];
324
  int64_t best_intra_rd;
325
  unsigned int best_pred_sse;
326
327
  /*!
328
   * \brief Keep track of best intra rd for use in compound mode.
329
   */
330
  int64_t best_pred_rd[REFERENCE_MODES];
331
  // Save a set of single_newmv for each checked ref_mv.
332
  int_mv single_newmv[MAX_REF_MV_SEARCH][REF_FRAMES];
333
  int single_newmv_rate[MAX_REF_MV_SEARCH][REF_FRAMES];
334
  int single_newmv_valid[MAX_REF_MV_SEARCH][REF_FRAMES];
335
  int64_t modelled_rd[MB_MODE_COUNT][MAX_REF_MV_SEARCH][REF_FRAMES];
336
  // The rd of simple translation in single inter modes
337
  int64_t simple_rd[MB_MODE_COUNT][MAX_REF_MV_SEARCH][REF_FRAMES];
338
  int64_t best_single_rd[REF_FRAMES];
339
  PREDICTION_MODE best_single_mode[REF_FRAMES];
340
341
  // Single search results by [directions][modes][reference frames]
342
  SingleInterModeState single_state[2][SINGLE_INTER_MODE_NUM][FWD_REFS];
343
  int single_state_cnt[2][SINGLE_INTER_MODE_NUM];
344
  SingleInterModeState single_state_modelled[2][SINGLE_INTER_MODE_NUM]
345
                                            [FWD_REFS];
346
  int single_state_modelled_cnt[2][SINGLE_INTER_MODE_NUM];
347
  MV_REFERENCE_FRAME single_rd_order[2][SINGLE_INTER_MODE_NUM][FWD_REFS];
348
  IntraModeSearchState intra_search_state;
349
  RD_STATS best_y_rdcost;
350
} InterModeSearchState;
351
/*!\endcond */
352
353
319k
void av1_inter_mode_data_init(TileDataEnc *tile_data) {
354
7.34M
  for (int i = 0; i < BLOCK_SIZES_ALL; ++i) {
355
7.02M
    InterModeRdModel *md = &tile_data->inter_mode_rd_models[i];
356
7.02M
    md->ready = 0;
357
7.02M
    md->num = 0;
358
7.02M
    md->dist_sum = 0;
359
7.02M
    md->ld_sum = 0;
360
7.02M
    md->sse_sum = 0;
361
7.02M
    md->sse_sse_sum = 0;
362
7.02M
    md->sse_ld_sum = 0;
363
7.02M
  }
364
319k
}
365
366
static int get_est_rate_dist(const TileDataEnc *tile_data, BLOCK_SIZE bsize,
367
                             int64_t sse, int *est_residue_cost,
368
87.7k
                             int64_t *est_dist) {
369
87.7k
  const InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize];
370
87.7k
  if (md->ready) {
371
87.7k
    if (sse < md->dist_mean) {
372
17
      *est_residue_cost = 0;
373
17
      *est_dist = sse;
374
87.7k
    } else {
375
87.7k
      *est_dist = (int64_t)round(md->dist_mean);
376
87.7k
      const double est_ld = md->a * sse + md->b;
377
      // Clamp estimated rate cost by INT_MAX / 2.
378
      // TODO(angiebird@google.com): find better solution than clamping.
379
87.7k
      if (fabs(est_ld) < 1e-2) {
380
0
        *est_residue_cost = INT_MAX / 2;
381
87.7k
      } else {
382
87.7k
        double est_residue_cost_dbl = ((sse - md->dist_mean) / est_ld);
383
87.7k
        if (est_residue_cost_dbl < 0) {
384
0
          *est_residue_cost = 0;
385
87.7k
        } else {
386
87.7k
          *est_residue_cost =
387
87.7k
              (int)AOMMIN((int64_t)round(est_residue_cost_dbl), INT_MAX / 2);
388
87.7k
        }
389
87.7k
      }
390
87.7k
      if (*est_residue_cost <= 0) {
391
0
        *est_residue_cost = 0;
392
0
        *est_dist = sse;
393
0
      }
394
87.7k
    }
395
87.7k
    return 1;
396
87.7k
  }
397
0
  return 0;
398
87.7k
}
399
400
17.5k
void av1_inter_mode_data_fit(TileDataEnc *tile_data, int rdmult) {
401
403k
  for (int bsize = 0; bsize < BLOCK_SIZES_ALL; ++bsize) {
402
385k
    const int block_idx = inter_mode_data_block_idx(bsize);
403
385k
    InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize];
404
385k
    if (block_idx == -1) continue;
405
297k
    if ((md->ready == 0 && md->num < 200) || (md->ready == 1 && md->num < 64)) {
406
297k
      continue;
407
297k
    } else {
408
458
      if (md->ready == 0) {
409
114
        md->dist_mean = md->dist_sum / md->num;
410
114
        md->ld_mean = md->ld_sum / md->num;
411
114
        md->sse_mean = md->sse_sum / md->num;
412
114
        md->sse_sse_mean = md->sse_sse_sum / md->num;
413
114
        md->sse_ld_mean = md->sse_ld_sum / md->num;
414
344
      } else {
415
344
        const double factor = 3;
416
344
        md->dist_mean =
417
344
            (md->dist_mean * factor + (md->dist_sum / md->num)) / (factor + 1);
418
344
        md->ld_mean =
419
344
            (md->ld_mean * factor + (md->ld_sum / md->num)) / (factor + 1);
420
344
        md->sse_mean =
421
344
            (md->sse_mean * factor + (md->sse_sum / md->num)) / (factor + 1);
422
344
        md->sse_sse_mean =
423
344
            (md->sse_sse_mean * factor + (md->sse_sse_sum / md->num)) /
424
344
            (factor + 1);
425
344
        md->sse_ld_mean =
426
344
            (md->sse_ld_mean * factor + (md->sse_ld_sum / md->num)) /
427
344
            (factor + 1);
428
344
      }
429
430
458
      const double my = md->ld_mean;
431
458
      const double mx = md->sse_mean;
432
458
      const double dx = sqrt(md->sse_sse_mean);
433
458
      const double dxy = md->sse_ld_mean;
434
435
458
      md->a = (dxy - mx * my) / (dx * dx - mx * mx);
436
458
      md->b = my - md->a * mx;
437
458
      md->ready = 1;
438
439
458
      md->num = 0;
440
458
      md->dist_sum = 0;
441
458
      md->ld_sum = 0;
442
458
      md->sse_sum = 0;
443
458
      md->sse_sse_sum = 0;
444
458
      md->sse_ld_sum = 0;
445
458
    }
446
458
    (void)rdmult;
447
458
  }
448
17.5k
}
449
450
static inline void inter_mode_data_push(TileDataEnc *tile_data,
451
                                        BLOCK_SIZE bsize, int64_t sse,
452
468k
                                        int64_t dist, int residue_cost) {
453
468k
  if (residue_cost == 0 || sse == dist) return;
454
363k
  const int block_idx = inter_mode_data_block_idx(bsize);
455
363k
  if (block_idx == -1) return;
456
363k
  InterModeRdModel *rd_model = &tile_data->inter_mode_rd_models[bsize];
457
363k
  if (rd_model->num < INTER_MODE_RD_DATA_OVERALL_SIZE) {
458
363k
    const double ld = (sse - dist) * 1. / residue_cost;
459
363k
    ++rd_model->num;
460
363k
    rd_model->dist_sum += dist;
461
363k
    rd_model->ld_sum += ld;
462
363k
    rd_model->sse_sum += sse;
463
363k
    rd_model->sse_sse_sum += (double)sse * (double)sse;
464
363k
    rd_model->sse_ld_sum += sse * ld;
465
363k
  }
466
363k
}
467
468
static inline void inter_modes_info_push(InterModesInfo *inter_modes_info,
469
                                         int mode_rate, int64_t sse, int64_t rd,
470
                                         RD_STATS *rd_cost, RD_STATS *rd_cost_y,
471
                                         RD_STATS *rd_cost_uv,
472
144k
                                         const MB_MODE_INFO *mbmi) {
473
144k
  const int num = inter_modes_info->num;
474
144k
  assert(num < MAX_INTER_MODES);
475
144k
  inter_modes_info->mbmi_arr[num] = *mbmi;
476
144k
  inter_modes_info->mode_rate_arr[num] = mode_rate;
477
144k
  inter_modes_info->sse_arr[num] = sse;
478
144k
  inter_modes_info->est_rd_arr[num] = rd;
479
144k
  inter_modes_info->rd_cost_arr[num] = *rd_cost;
480
144k
  inter_modes_info->rd_cost_y_arr[num] = *rd_cost_y;
481
144k
  inter_modes_info->rd_cost_uv_arr[num] = *rd_cost_uv;
482
144k
  ++inter_modes_info->num;
483
144k
}
484
485
180k
static int compare_rd_idx_pair(const void *a, const void *b) {
486
180k
  if (((RdIdxPair *)a)->rd == ((RdIdxPair *)b)->rd) {
487
    // To avoid inconsistency in qsort() ordering when two elements are equal,
488
    // using idx as tie breaker. Refer aomedia:2928
489
5
    if (((RdIdxPair *)a)->idx == ((RdIdxPair *)b)->idx)
490
0
      return 0;
491
5
    else if (((RdIdxPair *)a)->idx > ((RdIdxPair *)b)->idx)
492
0
      return 1;
493
5
    else
494
5
      return -1;
495
180k
  } else if (((const RdIdxPair *)a)->rd > ((const RdIdxPair *)b)->rd) {
496
97.1k
    return 1;
497
97.1k
  } else {
498
83.6k
    return -1;
499
83.6k
  }
500
180k
}
501
502
static inline void inter_modes_info_sort(const InterModesInfo *inter_modes_info,
503
37.4k
                                         RdIdxPair *rd_idx_pair_arr) {
504
37.4k
  if (inter_modes_info->num == 0) {
505
1
    return;
506
1
  }
507
181k
  for (int i = 0; i < inter_modes_info->num; ++i) {
508
143k
    rd_idx_pair_arr[i].idx = i;
509
143k
    rd_idx_pair_arr[i].rd = inter_modes_info->est_rd_arr[i];
510
143k
  }
511
37.4k
  qsort(rd_idx_pair_arr, inter_modes_info->num, sizeof(rd_idx_pair_arr[0]),
512
37.4k
        compare_rd_idx_pair);
513
37.4k
}
514
515
// Initialize estimated RD Cost records of compound average.
516
static inline void init_comp_avg_est_rd(
517
902k
    struct macroblock *x, int skip_cmp_using_top_cmp_avg_est_rd_lvl) {
518
902k
  if (!skip_cmp_using_top_cmp_avg_est_rd_lvl) return;
519
520
5.41M
  for (int j = 0; j < TOP_COMP_AVG_EST_RD_COUNT; j++) {
521
4.51M
    x->top_comp_avg_est_rd[j] = INT64_MAX;
522
4.51M
  }
523
902k
}
524
525
// Similar to get_horver_correlation, but also takes into account first
526
// row/column, when computing horizontal/vertical correlation.
527
void av1_get_horver_correlation_full_c(const int16_t *diff, int stride,
528
                                       int width, int height, float *hcorr,
529
0
                                       float *vcorr) {
530
  // The following notation is used:
531
  // x - current pixel
532
  // y - left neighbor pixel
533
  // z - top neighbor pixel
534
0
  int64_t x_sum = 0, x2_sum = 0, xy_sum = 0, xz_sum = 0;
535
0
  int64_t x_firstrow = 0, x_finalrow = 0, x_firstcol = 0, x_finalcol = 0;
536
0
  int64_t x2_firstrow = 0, x2_finalrow = 0, x2_firstcol = 0, x2_finalcol = 0;
537
538
  // First, process horizontal correlation on just the first row
539
0
  x_sum += diff[0];
540
0
  x2_sum += diff[0] * diff[0];
541
0
  x_firstrow += diff[0];
542
0
  x2_firstrow += diff[0] * diff[0];
543
0
  for (int j = 1; j < width; ++j) {
544
0
    const int16_t x = diff[j];
545
0
    const int16_t y = diff[j - 1];
546
0
    x_sum += x;
547
0
    x_firstrow += x;
548
0
    x2_sum += x * x;
549
0
    x2_firstrow += x * x;
550
0
    xy_sum += x * y;
551
0
  }
552
553
  // Process vertical correlation in the first column
554
0
  x_firstcol += diff[0];
555
0
  x2_firstcol += diff[0] * diff[0];
556
0
  for (int i = 1; i < height; ++i) {
557
0
    const int16_t x = diff[i * stride];
558
0
    const int16_t z = diff[(i - 1) * stride];
559
0
    x_sum += x;
560
0
    x_firstcol += x;
561
0
    x2_sum += x * x;
562
0
    x2_firstcol += x * x;
563
0
    xz_sum += x * z;
564
0
  }
565
566
  // Now process horiz and vert correlation through the rest unit
567
0
  for (int i = 1; i < height; ++i) {
568
0
    for (int j = 1; j < width; ++j) {
569
0
      const int16_t x = diff[i * stride + j];
570
0
      const int16_t y = diff[i * stride + j - 1];
571
0
      const int16_t z = diff[(i - 1) * stride + j];
572
0
      x_sum += x;
573
0
      x2_sum += x * x;
574
0
      xy_sum += x * y;
575
0
      xz_sum += x * z;
576
0
    }
577
0
  }
578
579
0
  for (int j = 0; j < width; ++j) {
580
0
    x_finalrow += diff[(height - 1) * stride + j];
581
0
    x2_finalrow +=
582
0
        diff[(height - 1) * stride + j] * diff[(height - 1) * stride + j];
583
0
  }
584
0
  for (int i = 0; i < height; ++i) {
585
0
    x_finalcol += diff[i * stride + width - 1];
586
0
    x2_finalcol += diff[i * stride + width - 1] * diff[i * stride + width - 1];
587
0
  }
588
589
0
  int64_t xhor_sum = x_sum - x_finalcol;
590
0
  int64_t xver_sum = x_sum - x_finalrow;
591
0
  int64_t y_sum = x_sum - x_firstcol;
592
0
  int64_t z_sum = x_sum - x_firstrow;
593
0
  int64_t x2hor_sum = x2_sum - x2_finalcol;
594
0
  int64_t x2ver_sum = x2_sum - x2_finalrow;
595
0
  int64_t y2_sum = x2_sum - x2_firstcol;
596
0
  int64_t z2_sum = x2_sum - x2_firstrow;
597
598
0
  const float num_hor = (float)(height * (width - 1));
599
0
  const float num_ver = (float)((height - 1) * width);
600
601
0
  const float xhor_var_n = x2hor_sum - (xhor_sum * xhor_sum) / num_hor;
602
0
  const float xver_var_n = x2ver_sum - (xver_sum * xver_sum) / num_ver;
603
604
0
  const float y_var_n = y2_sum - (y_sum * y_sum) / num_hor;
605
0
  const float z_var_n = z2_sum - (z_sum * z_sum) / num_ver;
606
607
0
  const float xy_var_n = xy_sum - (xhor_sum * y_sum) / num_hor;
608
0
  const float xz_var_n = xz_sum - (xver_sum * z_sum) / num_ver;
609
610
0
  if (xhor_var_n > 0 && y_var_n > 0) {
611
0
    *hcorr = xy_var_n / sqrtf(xhor_var_n * y_var_n);
612
0
    *hcorr = *hcorr < 0 ? 0 : *hcorr;
613
0
  } else {
614
0
    *hcorr = 1.0;
615
0
  }
616
0
  if (xver_var_n > 0 && z_var_n > 0) {
617
0
    *vcorr = xz_var_n / sqrtf(xver_var_n * z_var_n);
618
0
    *vcorr = *vcorr < 0 ? 0 : *vcorr;
619
0
  } else {
620
0
    *vcorr = 1.0;
621
0
  }
622
0
}
623
624
#if CONFIG_AV1_HIGHBITDEPTH
625
static void get_variance_stats_hbd(const MACROBLOCK *x, int64_t *src_var,
626
0
                                   int64_t *rec_var) {
627
0
  const MACROBLOCKD *xd = &x->e_mbd;
628
0
  const MB_MODE_INFO *mbmi = xd->mi[0];
629
0
  const struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_Y];
630
0
  const struct macroblock_plane *const p = &x->plane[AOM_PLANE_Y];
631
632
0
  BLOCK_SIZE bsize = mbmi->bsize;
633
0
  int bw = block_size_wide[bsize];
634
0
  int bh = block_size_high[bsize];
635
0
  const int shift = 2 * (xd->bd - 8);
636
637
0
  *rec_var = aom_highbd_calc_variance_stat(CONVERT_TO_SHORTPTR(pd->dst.buf),
638
0
                                           pd->dst.stride, bw, bh);
639
0
  *src_var = aom_highbd_calc_variance_stat(CONVERT_TO_SHORTPTR(p->src.buf),
640
0
                                           p->src.stride, bw, bh);
641
642
0
  *rec_var = ROUND_POWER_OF_TWO(*rec_var, shift);
643
0
  *src_var = ROUND_POWER_OF_TWO(*src_var, shift);
644
0
}
645
#endif  // CONFIG_AV1_HIGHBITDEPTH
646
647
static void get_variance_stats(const MACROBLOCK *x, int64_t *src_var,
648
0
                               int64_t *rec_var) {
649
0
#if CONFIG_AV1_HIGHBITDEPTH
650
0
  if (is_cur_buf_hbd(&x->e_mbd)) {
651
0
    get_variance_stats_hbd(x, src_var, rec_var);
652
0
    return;
653
0
  }
654
0
#endif  // CONFIG_AV1_HIGHBITDEPTH
655
0
  const MACROBLOCKD *xd = &x->e_mbd;
656
0
  const MB_MODE_INFO *mbmi = xd->mi[0];
657
0
  const struct macroblockd_plane *const pd = &xd->plane[AOM_PLANE_Y];
658
0
  const struct macroblock_plane *const p = &x->plane[AOM_PLANE_Y];
659
660
0
  BLOCK_SIZE bsize = mbmi->bsize;
661
0
  int bw = block_size_wide[bsize];
662
0
  int bh = block_size_high[bsize];
663
664
0
  *rec_var = aom_calc_variance_stat(pd->dst.buf, pd->dst.stride, bw, bh);
665
0
  *src_var = aom_calc_variance_stat(p->src.buf, p->src.stride, bw, bh);
666
0
}
667
668
static void adjust_rdcost(const AV1_COMP *cpi, const MACROBLOCK *x,
669
6.42M
                          RD_STATS *rd_cost, bool is_inter_pred) {
670
6.42M
  if ((cpi->oxcf.tune_cfg.tuning == AOM_TUNE_IQ ||
671
6.42M
       cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2) &&
672
0
      is_inter_pred) {
673
    // Tune IQ and SSIMULACRA2 can be used to encode layered images, where
674
    // keyframes could be encoded at a lower or similar quality (i.e. higher
675
    // QP) than inter-coded frames.
676
    // In this case, libaom tends to underestimate the true RD cost of inter
677
    // prediction candidates, causing encoded file size to increase without a
678
    // corresponding increase in quality.
679
    // When both intra and inter encoded block candidates are available (with
680
    // rdcosts close to each other), the intra-coded candidate was subjectively
681
    // observed to be a bit less blurry, with a corresponding increase in
682
    // SSIMULACRA 2 scores.
683
    // Apply a 1.125x inter block bias to increase overall perceptual
684
    // compression efficiency, while still allowing the encoder to pick inter
685
    // prediction when it's beneficial.
686
0
    rd_cost->dist += rd_cost->dist >> 3;
687
0
    rd_cost->rdcost += rd_cost->rdcost >> 3;
688
0
    return;
689
0
  }
690
691
6.42M
  if (cpi->oxcf.algo_cfg.sharpness != 3) return;
692
693
18.4E
  if (frame_is_kf_gf_arf(cpi)) return;
694
695
18.4E
  int64_t src_var, rec_var;
696
18.4E
  get_variance_stats(x, &src_var, &rec_var);
697
698
18.4E
  if (src_var <= rec_var) return;
699
700
18.4E
  int64_t var_offset = src_var - rec_var;
701
702
18.4E
  rd_cost->dist += var_offset;
703
704
18.4E
  rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
705
18.4E
}
706
707
static void adjust_cost(const AV1_COMP *cpi, const MACROBLOCK *x,
708
4.80M
                        int64_t *rd_cost, bool is_inter_pred) {
709
4.80M
  if ((cpi->oxcf.tune_cfg.tuning == AOM_TUNE_IQ ||
710
4.80M
       cpi->oxcf.tune_cfg.tuning == AOM_TUNE_SSIMULACRA2) &&
711
0
      is_inter_pred) {
712
0
    *rd_cost += *rd_cost >> 3;
713
0
    return;
714
0
  }
715
716
4.80M
  if (cpi->oxcf.algo_cfg.sharpness != 3) return;
717
718
25
  if (frame_is_kf_gf_arf(cpi)) return;
719
720
25
  int64_t src_var, rec_var;
721
25
  get_variance_stats(x, &src_var, &rec_var);
722
723
25
  if (src_var <= rec_var) return;
724
725
25
  int64_t var_offset = src_var - rec_var;
726
727
25
  *rd_cost += RDCOST(x->rdmult, 0, var_offset);
728
25
}
729
730
static int64_t get_sse(const AV1_COMP *cpi, const MACROBLOCK *x,
731
3.65M
                       int64_t *sse_y) {
732
3.65M
  const AV1_COMMON *cm = &cpi->common;
733
3.65M
  const int num_planes = av1_num_planes(cm);
734
3.65M
  const MACROBLOCKD *xd = &x->e_mbd;
735
3.65M
  const MB_MODE_INFO *mbmi = xd->mi[0];
736
3.65M
  int64_t total_sse = 0;
737
10.4M
  for (int plane = 0; plane < num_planes; ++plane) {
738
6.82M
    if (plane && !xd->is_chroma_ref) break;
739
6.82M
    const struct macroblock_plane *const p = &x->plane[plane];
740
6.82M
    const struct macroblockd_plane *const pd = &xd->plane[plane];
741
6.82M
    const BLOCK_SIZE bs =
742
6.82M
        get_plane_block_size(mbmi->bsize, pd->subsampling_x, pd->subsampling_y);
743
6.82M
    unsigned int sse;
744
6.82M
    int bw, bh;
745
6.82M
    const int block_width = block_size_wide[bs];
746
6.82M
    const int block_height = block_size_high[bs];
747
748
6.82M
    get_visible_dimensions(x, plane, bs, 0, 0, block_width, block_height,
749
6.82M
                           cpi->do_border_pad, &bw, &bh);
750
751
6.82M
    sse = pixel_dist_visible_only(cpi, x, p->src.buf, p->src.stride,
752
6.82M
                                  pd->dst.buf, pd->dst.stride, bs, block_height,
753
6.82M
                                  block_width, bh, bw);
754
6.82M
    total_sse += sse;
755
6.82M
    if (!plane && sse_y) *sse_y = sse;
756
6.82M
  }
757
3.65M
  total_sse <<= 4;
758
3.65M
  return total_sse;
759
3.65M
}
760
761
int64_t av1_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff,
762
0
                          intptr_t block_size, int64_t *ssz) {
763
0
  int i;
764
0
  int64_t error = 0, sqcoeff = 0;
765
766
0
  for (i = 0; i < block_size; i++) {
767
0
    const int diff = coeff[i] - dqcoeff[i];
768
0
    error += diff * diff;
769
0
    sqcoeff += coeff[i] * coeff[i];
770
0
  }
771
772
0
  *ssz = sqcoeff;
773
0
  return error;
774
0
}
775
776
int64_t av1_block_error_lp_c(const int16_t *coeff, const int16_t *dqcoeff,
777
0
                             intptr_t block_size) {
778
0
  int64_t error = 0;
779
780
0
  for (int i = 0; i < block_size; i++) {
781
0
    const int diff = coeff[i] - dqcoeff[i];
782
0
    error += diff * diff;
783
0
  }
784
785
0
  return error;
786
0
}
787
788
#if CONFIG_AV1_HIGHBITDEPTH
789
int64_t av1_highbd_block_error_c(const tran_low_t *coeff,
790
                                 const tran_low_t *dqcoeff, intptr_t block_size,
791
0
                                 int64_t *ssz, int bd) {
792
0
  int i;
793
0
  int64_t error = 0, sqcoeff = 0;
794
0
  int shift = 2 * (bd - 8);
795
0
  int rounding = (1 << shift) >> 1;
796
797
0
  for (i = 0; i < block_size; i++) {
798
0
    const int64_t diff = coeff[i] - dqcoeff[i];
799
0
    error += diff * diff;
800
0
    sqcoeff += (int64_t)coeff[i] * (int64_t)coeff[i];
801
0
  }
802
0
  error = (error + rounding) >> shift;
803
0
  sqcoeff = (sqcoeff + rounding) >> shift;
804
805
0
  *ssz = sqcoeff;
806
0
  return error;
807
0
}
808
#endif
809
810
static int conditional_skipintra(PREDICTION_MODE mode,
811
0
                                 PREDICTION_MODE best_intra_mode) {
812
0
  if (mode == D113_PRED && best_intra_mode != V_PRED &&
813
0
      best_intra_mode != D135_PRED)
814
0
    return 1;
815
0
  if (mode == D67_PRED && best_intra_mode != V_PRED &&
816
0
      best_intra_mode != D45_PRED)
817
0
    return 1;
818
0
  if (mode == D203_PRED && best_intra_mode != H_PRED &&
819
0
      best_intra_mode != D45_PRED)
820
0
    return 1;
821
0
  if (mode == D157_PRED && best_intra_mode != H_PRED &&
822
0
      best_intra_mode != D135_PRED)
823
0
    return 1;
824
0
  return 0;
825
0
}
826
827
static int cost_mv_ref(const ModeCosts *const mode_costs, PREDICTION_MODE mode,
828
5.01M
                       int16_t mode_context) {
829
5.01M
  if (is_inter_compound_mode(mode)) {
830
480k
    return mode_costs
831
480k
        ->inter_compound_mode_cost[mode_context][INTER_COMPOUND_OFFSET(mode)];
832
480k
  }
833
834
4.53M
  int mode_cost = 0;
835
4.53M
  int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
836
837
4.53M
  assert(is_inter_mode(mode));
838
839
4.53M
  if (mode == NEWMV) {
840
1.28M
    mode_cost = mode_costs->newmv_mode_cost[mode_ctx][0];
841
1.28M
    return mode_cost;
842
3.24M
  } else {
843
3.24M
    mode_cost = mode_costs->newmv_mode_cost[mode_ctx][1];
844
3.24M
    mode_ctx = (mode_context >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
845
846
3.24M
    if (mode == GLOBALMV) {
847
1.27M
      mode_cost += mode_costs->zeromv_mode_cost[mode_ctx][0];
848
1.27M
      return mode_cost;
849
1.97M
    } else {
850
1.97M
      mode_cost += mode_costs->zeromv_mode_cost[mode_ctx][1];
851
1.97M
      mode_ctx = (mode_context >> REFMV_OFFSET) & REFMV_CTX_MASK;
852
1.97M
      mode_cost += mode_costs->refmv_mode_cost[mode_ctx][mode != NEARESTMV];
853
1.97M
      return mode_cost;
854
1.97M
    }
855
3.24M
  }
856
4.53M
}
857
858
static inline PREDICTION_MODE get_single_mode(PREDICTION_MODE this_mode,
859
12.5M
                                              int ref_idx) {
860
12.5M
  return ref_idx ? compound_ref1_mode(this_mode)
861
12.5M
                 : compound_ref0_mode(this_mode);
862
12.5M
}
863
864
static inline void estimate_ref_frame_costs(
865
    const AV1_COMMON *cm, const MACROBLOCKD *xd, const ModeCosts *mode_costs,
866
    int segment_id, unsigned int *ref_costs_single,
867
903k
    unsigned int (*ref_costs_comp)[REF_FRAMES]) {
868
903k
  int seg_ref_active =
869
903k
      segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
870
903k
  if (seg_ref_active) {
871
0
    memset(ref_costs_single, 0, REF_FRAMES * sizeof(*ref_costs_single));
872
0
    int ref_frame;
873
0
    for (ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame)
874
0
      memset(ref_costs_comp[ref_frame], 0,
875
0
             REF_FRAMES * sizeof((*ref_costs_comp)[0]));
876
903k
  } else {
877
903k
    int intra_inter_ctx = av1_get_intra_inter_context(xd);
878
903k
    ref_costs_single[INTRA_FRAME] =
879
903k
        mode_costs->intra_inter_cost[intra_inter_ctx][0];
880
903k
    unsigned int base_cost = mode_costs->intra_inter_cost[intra_inter_ctx][1];
881
882
7.22M
    for (int i = LAST_FRAME; i <= ALTREF_FRAME; ++i)
883
6.31M
      ref_costs_single[i] = base_cost;
884
885
903k
    const int ctx_p1 = av1_get_pred_context_single_ref_p1(xd);
886
903k
    const int ctx_p2 = av1_get_pred_context_single_ref_p2(xd);
887
903k
    const int ctx_p3 = av1_get_pred_context_single_ref_p3(xd);
888
903k
    const int ctx_p4 = av1_get_pred_context_single_ref_p4(xd);
889
903k
    const int ctx_p5 = av1_get_pred_context_single_ref_p5(xd);
890
903k
    const int ctx_p6 = av1_get_pred_context_single_ref_p6(xd);
891
892
    // Determine cost of a single ref frame, where frame types are represented
893
    // by a tree:
894
    // Level 0: add cost whether this ref is a forward or backward ref
895
903k
    ref_costs_single[LAST_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
896
903k
    ref_costs_single[LAST2_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
897
903k
    ref_costs_single[LAST3_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
898
903k
    ref_costs_single[GOLDEN_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][0];
899
903k
    ref_costs_single[BWDREF_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][1];
900
903k
    ref_costs_single[ALTREF2_FRAME] +=
901
903k
        mode_costs->single_ref_cost[ctx_p1][0][1];
902
903k
    ref_costs_single[ALTREF_FRAME] += mode_costs->single_ref_cost[ctx_p1][0][1];
903
904
    // Level 1: if this ref is forward ref,
905
    // add cost whether it is last/last2 or last3/golden
906
903k
    ref_costs_single[LAST_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][0];
907
903k
    ref_costs_single[LAST2_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][0];
908
903k
    ref_costs_single[LAST3_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][1];
909
903k
    ref_costs_single[GOLDEN_FRAME] += mode_costs->single_ref_cost[ctx_p3][2][1];
910
911
    // Level 1: if this ref is backward ref
912
    // then add cost whether this ref is altref or backward ref
913
903k
    ref_costs_single[BWDREF_FRAME] += mode_costs->single_ref_cost[ctx_p2][1][0];
914
903k
    ref_costs_single[ALTREF2_FRAME] +=
915
903k
        mode_costs->single_ref_cost[ctx_p2][1][0];
916
903k
    ref_costs_single[ALTREF_FRAME] += mode_costs->single_ref_cost[ctx_p2][1][1];
917
918
    // Level 2: further add cost whether this ref is last or last2
919
903k
    ref_costs_single[LAST_FRAME] += mode_costs->single_ref_cost[ctx_p4][3][0];
920
903k
    ref_costs_single[LAST2_FRAME] += mode_costs->single_ref_cost[ctx_p4][3][1];
921
922
    // Level 2: last3 or golden
923
903k
    ref_costs_single[LAST3_FRAME] += mode_costs->single_ref_cost[ctx_p5][4][0];
924
903k
    ref_costs_single[GOLDEN_FRAME] += mode_costs->single_ref_cost[ctx_p5][4][1];
925
926
    // Level 2: bwdref or altref2
927
903k
    ref_costs_single[BWDREF_FRAME] += mode_costs->single_ref_cost[ctx_p6][5][0];
928
903k
    ref_costs_single[ALTREF2_FRAME] +=
929
903k
        mode_costs->single_ref_cost[ctx_p6][5][1];
930
931
903k
    if (cm->current_frame.reference_mode != SINGLE_REFERENCE) {
932
      // Similar to single ref, determine cost of compound ref frames.
933
      // cost_compound_refs = cost_first_ref + cost_second_ref
934
903k
      const int bwdref_comp_ctx_p = av1_get_pred_context_comp_bwdref_p(xd);
935
903k
      const int bwdref_comp_ctx_p1 = av1_get_pred_context_comp_bwdref_p1(xd);
936
903k
      const int ref_comp_ctx_p = av1_get_pred_context_comp_ref_p(xd);
937
903k
      const int ref_comp_ctx_p1 = av1_get_pred_context_comp_ref_p1(xd);
938
903k
      const int ref_comp_ctx_p2 = av1_get_pred_context_comp_ref_p2(xd);
939
940
903k
      const int comp_ref_type_ctx = av1_get_comp_reference_type_context(xd);
941
903k
      unsigned int ref_bicomp_costs[REF_FRAMES] = { 0 };
942
943
903k
      ref_bicomp_costs[LAST_FRAME] = ref_bicomp_costs[LAST2_FRAME] =
944
903k
          ref_bicomp_costs[LAST3_FRAME] = ref_bicomp_costs[GOLDEN_FRAME] =
945
903k
              base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][1];
946
903k
      ref_bicomp_costs[BWDREF_FRAME] = ref_bicomp_costs[ALTREF2_FRAME] = 0;
947
903k
      ref_bicomp_costs[ALTREF_FRAME] = 0;
948
949
      // cost of first ref frame
950
903k
      ref_bicomp_costs[LAST_FRAME] +=
951
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p][0][0];
952
903k
      ref_bicomp_costs[LAST2_FRAME] +=
953
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p][0][0];
954
903k
      ref_bicomp_costs[LAST3_FRAME] +=
955
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p][0][1];
956
903k
      ref_bicomp_costs[GOLDEN_FRAME] +=
957
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p][0][1];
958
959
903k
      ref_bicomp_costs[LAST_FRAME] +=
960
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p1][1][0];
961
903k
      ref_bicomp_costs[LAST2_FRAME] +=
962
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p1][1][1];
963
964
903k
      ref_bicomp_costs[LAST3_FRAME] +=
965
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p2][2][0];
966
903k
      ref_bicomp_costs[GOLDEN_FRAME] +=
967
903k
          mode_costs->comp_ref_cost[ref_comp_ctx_p2][2][1];
968
969
      // cost of second ref frame
970
903k
      ref_bicomp_costs[BWDREF_FRAME] +=
971
903k
          mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p][0][0];
972
903k
      ref_bicomp_costs[ALTREF2_FRAME] +=
973
903k
          mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p][0][0];
974
903k
      ref_bicomp_costs[ALTREF_FRAME] +=
975
903k
          mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p][0][1];
976
977
903k
      ref_bicomp_costs[BWDREF_FRAME] +=
978
903k
          mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p1][1][0];
979
903k
      ref_bicomp_costs[ALTREF2_FRAME] +=
980
903k
          mode_costs->comp_bwdref_cost[bwdref_comp_ctx_p1][1][1];
981
982
      // cost: if one ref frame is forward ref, the other ref is backward ref
983
903k
      int ref0, ref1;
984
4.51M
      for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
985
14.4M
        for (ref1 = BWDREF_FRAME; ref1 <= ALTREF_FRAME; ++ref1) {
986
10.8M
          ref_costs_comp[ref0][ref1] =
987
10.8M
              ref_bicomp_costs[ref0] + ref_bicomp_costs[ref1];
988
10.8M
        }
989
3.61M
      }
990
991
      // cost: if both ref frames are the same side.
992
903k
      const int uni_comp_ref_ctx_p = av1_get_pred_context_uni_comp_ref_p(xd);
993
903k
      const int uni_comp_ref_ctx_p1 = av1_get_pred_context_uni_comp_ref_p1(xd);
994
903k
      const int uni_comp_ref_ctx_p2 = av1_get_pred_context_uni_comp_ref_p2(xd);
995
903k
      ref_costs_comp[LAST_FRAME][LAST2_FRAME] =
996
903k
          base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
997
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][0] +
998
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p1][1][0];
999
903k
      ref_costs_comp[LAST_FRAME][LAST3_FRAME] =
1000
903k
          base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1001
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][0] +
1002
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p1][1][1] +
1003
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p2][2][0];
1004
903k
      ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] =
1005
903k
          base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1006
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][0] +
1007
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p1][1][1] +
1008
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p2][2][1];
1009
903k
      ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] =
1010
903k
          base_cost + mode_costs->comp_ref_type_cost[comp_ref_type_ctx][0] +
1011
903k
          mode_costs->uni_comp_ref_cost[uni_comp_ref_ctx_p][0][1];
1012
18.4E
    } else {
1013
18.4E
      int ref0, ref1;
1014
18.4E
      for (ref0 = LAST_FRAME; ref0 <= GOLDEN_FRAME; ++ref0) {
1015
0
        for (ref1 = BWDREF_FRAME; ref1 <= ALTREF_FRAME; ++ref1)
1016
0
          ref_costs_comp[ref0][ref1] = 512;
1017
0
      }
1018
18.4E
      ref_costs_comp[LAST_FRAME][LAST2_FRAME] = 512;
1019
18.4E
      ref_costs_comp[LAST_FRAME][LAST3_FRAME] = 512;
1020
18.4E
      ref_costs_comp[LAST_FRAME][GOLDEN_FRAME] = 512;
1021
18.4E
      ref_costs_comp[BWDREF_FRAME][ALTREF_FRAME] = 512;
1022
18.4E
    }
1023
903k
  }
1024
903k
}
1025
1026
static inline void store_coding_context(
1027
#if CONFIG_INTERNAL_STATS
1028
    MACROBLOCK *x, PICK_MODE_CONTEXT *ctx, int mode_index,
1029
#else
1030
    MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
1031
#endif  // CONFIG_INTERNAL_STATS
1032
891k
    int skippable) {
1033
891k
  MACROBLOCKD *const xd = &x->e_mbd;
1034
1035
  // Take a snapshot of the coding context so it can be
1036
  // restored if we decide to encode this way
1037
891k
  ctx->rd_stats.skip_txfm = x->txfm_search_info.skip_txfm;
1038
891k
  ctx->skippable = skippable;
1039
#if CONFIG_INTERNAL_STATS
1040
  ctx->best_mode_index = mode_index;
1041
#endif  // CONFIG_INTERNAL_STATS
1042
891k
  ctx->mic = *xd->mi[0];
1043
891k
  av1_copy_mbmi_ext_to_mbmi_ext_frame(&ctx->mbmi_ext_best, &x->mbmi_ext,
1044
891k
                                      av1_ref_frame_type(xd->mi[0]->ref_frame));
1045
891k
}
1046
1047
static inline void setup_buffer_ref_mvs_inter(
1048
    const AV1_COMP *const cpi, MACROBLOCK *x, MV_REFERENCE_FRAME ref_frame,
1049
1.59M
    BLOCK_SIZE block_size, struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE]) {
1050
1.59M
  const AV1_COMMON *cm = &cpi->common;
1051
1.59M
  const int num_planes = av1_num_planes(cm);
1052
1.59M
  const YV12_BUFFER_CONFIG *scaled_ref_frame =
1053
1.59M
      av1_get_scaled_ref_frame(cpi, ref_frame);
1054
1.59M
  MACROBLOCKD *const xd = &x->e_mbd;
1055
1.59M
  MB_MODE_INFO *const mbmi = xd->mi[0];
1056
1.59M
  MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
1057
1.59M
  const struct scale_factors *const sf =
1058
1.59M
      get_ref_scale_factors_const(cm, ref_frame);
1059
1.59M
  const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_yv12_buf(cm, ref_frame);
1060
1.59M
  assert(yv12 != NULL);
1061
1062
1.59M
  if (scaled_ref_frame) {
1063
    // Setup pred block based on scaled reference, because av1_mv_pred() doesn't
1064
    // support scaling.
1065
0
    av1_setup_pred_block(xd, yv12_mb[ref_frame], scaled_ref_frame, NULL, NULL,
1066
0
                         num_planes);
1067
1.59M
  } else {
1068
1.59M
    av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, sf, sf, num_planes);
1069
1.59M
  }
1070
1071
  // Gets an initial list of candidate vectors from neighbours and orders them
1072
1.59M
  av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
1073
1.59M
                   xd->ref_mv_stack, xd->weight, NULL, mbmi_ext->global_mvs,
1074
1.59M
                   mbmi_ext->mode_context);
1075
  // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
1076
  // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
1077
1.59M
  av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
1078
  // Further refinement that is encode side only to test the top few candidates
1079
  // in full and choose the best as the center point for subsequent searches.
1080
  // The current implementation doesn't support scaling.
1081
1.59M
  av1_mv_pred(cpi, x, yv12_mb[ref_frame][0].buf, yv12_mb[ref_frame][0].stride,
1082
1.59M
              ref_frame, block_size);
1083
1084
  // Go back to unscaled reference.
1085
1.59M
  if (scaled_ref_frame) {
1086
    // We had temporarily setup pred block based on scaled reference above. Go
1087
    // back to unscaled reference now, for subsequent use.
1088
0
    av1_setup_pred_block(xd, yv12_mb[ref_frame], yv12, sf, sf, num_planes);
1089
0
  }
1090
1.59M
}
1091
1092
8.11M
#define LEFT_TOP_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
1093
8.11M
#define RIGHT_BOTTOM_MARGIN ((AOM_BORDER_IN_PIXELS - AOM_INTERP_EXTEND) << 3)
1094
1095
// TODO(jingning): this mv clamping function should be block size dependent.
1096
4.05M
static inline void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
1097
4.05M
  const SubpelMvLimits mv_limits = { xd->mb_to_left_edge - LEFT_TOP_MARGIN,
1098
4.05M
                                     xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
1099
4.05M
                                     xd->mb_to_top_edge - LEFT_TOP_MARGIN,
1100
4.05M
                                     xd->mb_to_bottom_edge +
1101
4.05M
                                         RIGHT_BOTTOM_MARGIN };
1102
4.05M
  clamp_mv(mv, &mv_limits);
1103
4.05M
}
1104
1105
/* If the current mode shares the same mv with other modes with higher cost,
1106
 * skip this mode. */
1107
static AOM_FORCE_INLINE int skip_repeated_mv(
1108
    const AV1_COMMON *const cm, const MACROBLOCK *const x,
1109
    PREDICTION_MODE this_mode, const MV_REFERENCE_FRAME ref_frames[2],
1110
6.28M
    InterModeSearchState *search_state) {
1111
6.28M
  const int is_comp_pred = ref_frames[1] > INTRA_FRAME;
1112
6.28M
  const uint8_t ref_frame_type = av1_ref_frame_type(ref_frames);
1113
6.28M
  const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
1114
6.28M
  const int ref_mv_count = mbmi_ext->ref_mv_count[ref_frame_type];
1115
6.28M
  PREDICTION_MODE compare_mode = MB_MODE_COUNT;
1116
6.28M
  if (!is_comp_pred) {
1117
5.18M
    if (this_mode == NEARMV) {
1118
1.29M
      if (ref_mv_count == 0) {
1119
        // NEARMV has the same motion vector as NEARESTMV
1120
596k
        compare_mode = NEARESTMV;
1121
596k
      }
1122
1.29M
      if (ref_mv_count == 1 &&
1123
365k
          cm->global_motion[ref_frames[0]].wmtype <= TRANSLATION) {
1124
        // NEARMV has the same motion vector as GLOBALMV
1125
365k
        compare_mode = GLOBALMV;
1126
365k
      }
1127
1.29M
    }
1128
5.18M
    if (this_mode == GLOBALMV) {
1129
1.29M
      if (ref_mv_count == 0 &&
1130
596k
          cm->global_motion[ref_frames[0]].wmtype <= TRANSLATION) {
1131
        // GLOBALMV has the same motion vector as NEARESTMV
1132
596k
        compare_mode = NEARESTMV;
1133
596k
      }
1134
1.29M
      if (ref_mv_count == 1) {
1135
        // GLOBALMV has the same motion vector as NEARMV
1136
365k
        compare_mode = NEARMV;
1137
365k
      }
1138
1.29M
    }
1139
1140
5.18M
    if (compare_mode != MB_MODE_COUNT) {
1141
      // Use modelled_rd to check whether compare mode was searched
1142
1.92M
      if (search_state->modelled_rd[compare_mode][0][ref_frames[0]] !=
1143
1.92M
          INT64_MAX) {
1144
72.3k
        const int16_t mode_ctx =
1145
72.3k
            av1_mode_context_analyzer(mbmi_ext->mode_context, ref_frames);
1146
72.3k
        const int compare_cost =
1147
72.3k
            cost_mv_ref(&x->mode_costs, compare_mode, mode_ctx);
1148
72.3k
        const int this_cost = cost_mv_ref(&x->mode_costs, this_mode, mode_ctx);
1149
1150
        // Only skip if the mode cost is larger than compare mode cost
1151
72.3k
        if (this_cost > compare_cost) {
1152
72.3k
          search_state->modelled_rd[this_mode][0][ref_frames[0]] =
1153
72.3k
              search_state->modelled_rd[compare_mode][0][ref_frames[0]];
1154
72.3k
          return 1;
1155
72.3k
        }
1156
72.3k
      }
1157
1.92M
    }
1158
5.18M
  }
1159
6.21M
  return 0;
1160
6.28M
}
1161
1162
static inline int clamp_and_check_mv(int_mv *out_mv, int_mv in_mv,
1163
                                     const AV1_COMMON *cm,
1164
4.05M
                                     const MACROBLOCK *x) {
1165
4.05M
  const MACROBLOCKD *const xd = &x->e_mbd;
1166
4.05M
  *out_mv = in_mv;
1167
4.05M
  lower_mv_precision(&out_mv->as_mv, cm->features.allow_high_precision_mv,
1168
4.05M
                     cm->features.cur_frame_force_integer_mv);
1169
4.05M
  clamp_mv2(&out_mv->as_mv, xd);
1170
4.05M
  return av1_is_fullmv_in_range(&x->mv_limits,
1171
4.05M
                                get_fullmv_from_mv(&out_mv->as_mv));
1172
4.05M
}
1173
1174
// To use single newmv directly for compound modes, need to clamp the mv to the
1175
// valid mv range. Without this, encoder would generate out of range mv, and
1176
// this is seen in 8k encoding.
1177
static inline void clamp_mv_in_range(MACROBLOCK *const x, int_mv *mv,
1178
286k
                                     int ref_idx) {
1179
286k
  const int_mv ref_mv = av1_get_ref_mv(x, ref_idx);
1180
286k
  SubpelMvLimits mv_limits;
1181
1182
286k
  av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, &ref_mv.as_mv);
1183
286k
  clamp_mv(&mv->as_mv, &mv_limits);
1184
286k
}
1185
1186
static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
1187
                            const BLOCK_SIZE bsize, int_mv *cur_mv,
1188
                            int *const rate_mv, HandleInterModeArgs *const args,
1189
1.84M
                            inter_mode_info *mode_info) {
1190
1.84M
  MACROBLOCKD *const xd = &x->e_mbd;
1191
1.84M
  MB_MODE_INFO *const mbmi = xd->mi[0];
1192
1.84M
  const int is_comp_pred = has_second_ref(mbmi);
1193
1.84M
  const PREDICTION_MODE this_mode = mbmi->mode;
1194
1.84M
  const int refs[2] = { mbmi->ref_frame[0],
1195
1.84M
                        mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
1196
1.84M
  const int ref_mv_idx = mbmi->ref_mv_idx;
1197
1198
1.84M
  if (is_comp_pred) {
1199
143k
    const int valid_mv0 = args->single_newmv_valid[ref_mv_idx][refs[0]];
1200
143k
    const int valid_mv1 = args->single_newmv_valid[ref_mv_idx][refs[1]];
1201
143k
    if (this_mode == NEW_NEWMV) {
1202
143k
      if (valid_mv0) {
1203
143k
        cur_mv[0].as_int = args->single_newmv[ref_mv_idx][refs[0]].as_int;
1204
143k
        clamp_mv_in_range(x, &cur_mv[0], 0);
1205
143k
      }
1206
143k
      if (valid_mv1) {
1207
143k
        cur_mv[1].as_int = args->single_newmv[ref_mv_idx][refs[1]].as_int;
1208
143k
        clamp_mv_in_range(x, &cur_mv[1], 1);
1209
143k
      }
1210
143k
      *rate_mv = 0;
1211
429k
      for (int i = 0; i < 2; ++i) {
1212
286k
        const int_mv ref_mv = av1_get_ref_mv(x, i);
1213
286k
        *rate_mv += av1_mv_bit_cost(&cur_mv[i].as_mv, &ref_mv.as_mv,
1214
286k
                                    x->mv_costs->nmv_joint_cost,
1215
286k
                                    x->mv_costs->mv_cost_stack, MV_COST_WEIGHT);
1216
286k
      }
1217
18.4E
    } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
1218
0
      if (valid_mv1) {
1219
0
        cur_mv[1].as_int = args->single_newmv[ref_mv_idx][refs[1]].as_int;
1220
0
        clamp_mv_in_range(x, &cur_mv[1], 1);
1221
0
      }
1222
0
      const int_mv ref_mv = av1_get_ref_mv(x, 1);
1223
0
      *rate_mv = av1_mv_bit_cost(&cur_mv[1].as_mv, &ref_mv.as_mv,
1224
0
                                 x->mv_costs->nmv_joint_cost,
1225
0
                                 x->mv_costs->mv_cost_stack, MV_COST_WEIGHT);
1226
18.4E
    } else {
1227
18.4E
      assert(this_mode == NEW_NEARESTMV || this_mode == NEW_NEARMV);
1228
18.4E
      if (valid_mv0) {
1229
0
        cur_mv[0].as_int = args->single_newmv[ref_mv_idx][refs[0]].as_int;
1230
0
        clamp_mv_in_range(x, &cur_mv[0], 0);
1231
0
      }
1232
18.4E
      const int_mv ref_mv = av1_get_ref_mv(x, 0);
1233
18.4E
      *rate_mv = av1_mv_bit_cost(&cur_mv[0].as_mv, &ref_mv.as_mv,
1234
18.4E
                                 x->mv_costs->nmv_joint_cost,
1235
18.4E
                                 x->mv_costs->mv_cost_stack, MV_COST_WEIGHT);
1236
18.4E
    }
1237
1.69M
  } else {
1238
    // Single ref case.
1239
1.69M
    const int ref_idx = 0;
1240
1.69M
    int search_range = INT_MAX;
1241
1242
1.69M
    if (cpi->sf.mv_sf.reduce_search_range && mbmi->ref_mv_idx > 0) {
1243
412k
      const MV ref_mv = av1_get_ref_mv(x, ref_idx).as_mv;
1244
412k
      int min_mv_diff = INT_MAX;
1245
412k
      int best_match = -1;
1246
412k
      MV prev_ref_mv[2] = { { 0 } };
1247
955k
      for (int idx = 0; idx < mbmi->ref_mv_idx; ++idx) {
1248
542k
        prev_ref_mv[idx] = av1_get_ref_mv_from_stack(ref_idx, mbmi->ref_frame,
1249
542k
                                                     idx, &x->mbmi_ext)
1250
542k
                               .as_mv;
1251
542k
        const int ref_mv_diff = AOMMAX(abs(ref_mv.row - prev_ref_mv[idx].row),
1252
542k
                                       abs(ref_mv.col - prev_ref_mv[idx].col));
1253
1254
542k
        if (min_mv_diff > ref_mv_diff) {
1255
475k
          min_mv_diff = ref_mv_diff;
1256
475k
          best_match = idx;
1257
475k
        }
1258
542k
      }
1259
1260
412k
      if (min_mv_diff < (16 << 3)) {
1261
289k
        if (args->single_newmv_valid[best_match][refs[0]]) {
1262
264k
          search_range = min_mv_diff;
1263
264k
          search_range +=
1264
264k
              AOMMAX(abs(args->single_newmv[best_match][refs[0]].as_mv.row -
1265
264k
                         prev_ref_mv[best_match].row),
1266
264k
                     abs(args->single_newmv[best_match][refs[0]].as_mv.col -
1267
264k
                         prev_ref_mv[best_match].col));
1268
          // Get full pixel search range.
1269
264k
          search_range = (search_range + 4) >> 3;
1270
264k
        }
1271
289k
      }
1272
412k
    }
1273
1274
1.69M
    int_mv best_mv;
1275
1.69M
    av1_single_motion_search(cpi, x, bsize, ref_idx, rate_mv, search_range,
1276
1.69M
                             mode_info, &best_mv, args);
1277
1.69M
    if (best_mv.as_int == INVALID_MV) return INT64_MAX;
1278
1279
1.45M
    args->single_newmv[ref_mv_idx][refs[0]] = best_mv;
1280
1.45M
    args->single_newmv_rate[ref_mv_idx][refs[0]] = *rate_mv;
1281
1.45M
    args->single_newmv_valid[ref_mv_idx][refs[0]] = 1;
1282
1.45M
    cur_mv[0].as_int = best_mv.as_int;
1283
1284
    // Return after single_newmv is set.
1285
1.45M
    if (mode_info[mbmi->ref_mv_idx].skip) return INT64_MAX;
1286
1.45M
  }
1287
1288
1.59M
  return 0;
1289
1.84M
}
1290
1291
static inline void update_mode_start_end_index(
1292
    const AV1_COMP *const cpi, const MB_MODE_INFO *const mbmi,
1293
    int *mode_index_start, int *mode_index_end, int last_motion_mode_allowed,
1294
5.31M
    int interintra_allowed, int eval_motion_mode) {
1295
5.31M
  *mode_index_start = (int)SIMPLE_TRANSLATION;
1296
5.31M
  *mode_index_end = (int)last_motion_mode_allowed + interintra_allowed;
1297
5.31M
  if (cpi->sf.winner_mode_sf.motion_mode_for_winner_cand) {
1298
5.12M
    if (!eval_motion_mode) {
1299
3.54M
      *mode_index_end = (int)SIMPLE_TRANSLATION;
1300
3.54M
    } else {
1301
      // Set the start index appropriately to process motion modes other than
1302
      // simple translation
1303
1.58M
      *mode_index_start = 1;
1304
1.58M
    }
1305
5.12M
  }
1306
5.31M
  if (cpi->sf.inter_sf.extra_prune_warped && mbmi->bsize > BLOCK_16X16)
1307
0
    *mode_index_end = SIMPLE_TRANSLATION;
1308
5.31M
}
1309
1310
// Scale rate, dist and sse of RD_STATS as per the given bias percentage
1311
0
static inline void scale_rdstats(RD_STATS *rd_stats, double rd_scale_pct) {
1312
0
  if (rd_stats == NULL) return;
1313
0
  rd_stats->rate += (int)(rd_scale_pct * rd_stats->rate + 0.5);
1314
0
  rd_stats->dist += (int64_t)(rd_scale_pct * rd_stats->dist + 0.5);
1315
0
  rd_stats->sse += (int64_t)(rd_scale_pct * rd_stats->sse + 0.5);
1316
0
  rd_stats->zero_rate += (int)(rd_scale_pct * rd_stats->zero_rate + 0.5);
1317
0
}
1318
1319
// Increase rate, distortion and SSE in RD_STATS structure of warp and obmc
1320
// motion modes for low complexity decoding.
1321
static inline void increase_motion_mode_rdstats(const AV1_COMP *cpi,
1322
                                                const MB_MODE_INFO *this_mbmi,
1323
                                                RD_STATS *rd_stats,
1324
                                                RD_STATS *rd_stats_y,
1325
2.72M
                                                RD_STATS *rd_stats_uv) {
1326
2.72M
  if (rd_stats->rate == INT_MAX ||
1327
2.72M
      (rd_stats_y != NULL && rd_stats_y->rate == INT_MAX) ||
1328
2.72M
      (rd_stats_uv != NULL && rd_stats_uv->rate == INT_MAX))
1329
0
    return;
1330
2.72M
  const INTER_MODE_SPEED_FEATURES *const inter_sf = &cpi->sf.inter_sf;
1331
2.72M
  double rd_bias_scale = 0.0;
1332
2.72M
  if (this_mbmi->motion_mode == WARPED_CAUSAL) {
1333
158k
    rd_bias_scale = inter_sf->bias_warp_mode_rd_scale_pct / 100.0;
1334
2.56M
  } else if (this_mbmi->motion_mode == OBMC_CAUSAL) {
1335
0
    rd_bias_scale = inter_sf->bias_obmc_mode_rd_scale_pct / 100.0;
1336
2.56M
  } else if (this_mbmi->mode == GLOBALMV ||
1337
2.56M
             this_mbmi->mode == GLOBAL_GLOBALMV) {
1338
4.62k
    rd_bias_scale = get_global_mv_mode_bias(cpi, this_mbmi);
1339
4.62k
  }
1340
2.72M
  if (rd_bias_scale <= 0.0) return;
1341
1342
311
  scale_rdstats(rd_stats, rd_bias_scale);
1343
311
  scale_rdstats(rd_stats_y, rd_bias_scale);
1344
311
  scale_rdstats(rd_stats_uv, rd_bias_scale);
1345
311
}
1346
1347
/*!\brief AV1 motion mode search
1348
 *
1349
 * \ingroup inter_mode_search
1350
 * Function to search over and determine the motion mode. It will update
1351
 * mbmi->motion_mode to one of SIMPLE_TRANSLATION, OBMC_CAUSAL, or
1352
 * WARPED_CAUSAL and determine any necessary side information for the selected
1353
 * motion mode. It will also perform the full transform search, unless the
1354
 * input parameter do_tx_search indicates to do an estimation of the RD rather
1355
 * than an RD corresponding to a full transform search. It will return the
1356
 * RD for the final motion_mode.
1357
 * Do the RD search for a given inter mode and compute all information relevant
1358
 * to the input mode. It will compute the best MV,
1359
 * compound parameters (if the mode is a compound mode) and interpolation filter
1360
 * parameters.
1361
 *
1362
 * \param[in]     cpi               Top-level encoder structure.
1363
 * \param[in]     tile_data         Pointer to struct holding adaptive
1364
 *                                  data/contexts/models for the tile during
1365
 *                                  encoding.
1366
 * \param[in]     x                 Pointer to struct holding all the data for
1367
 *                                  the current macroblock.
1368
 * \param[in]     bsize             Current block size.
1369
 * \param[in,out] rd_stats          Struct to keep track of the overall RD
1370
 *                                  information.
1371
 * \param[in,out] rd_stats_y        Struct to keep track of the RD information
1372
 *                                  for only the Y plane.
1373
 * \param[in,out] rd_stats_uv       Struct to keep track of the RD information
1374
 *                                  for only the UV planes.
1375
 * \param[in]     args              HandleInterModeArgs struct holding
1376
 *                                  miscellaneous arguments for inter mode
1377
 *                                  search. See the documentation for this
1378
 *                                  struct for a description of each member.
1379
 * \param[in]     ref_best_rd       Best RD found so far for this block.
1380
 *                                  It is used for early termination of this
1381
 *                                  search if the RD exceeds this value.
1382
 * \param[in,out] ref_skip_rd       A length 2 array, where skip_rd[0] is the
1383
 *                                  best total RD for a skip mode so far, and
1384
 *                                  skip_rd[1] is the best RD for a skip mode so
1385
 *                                  far in luma. This is used as a speed feature
1386
 *                                  to skip the transform search if the computed
1387
 *                                  skip RD for the current mode is not better
1388
 *                                  than the best skip_rd so far.
1389
 * \param[in,out] rate_mv           The rate associated with the motion vectors.
1390
 *                                  This will be modified if a motion search is
1391
 *                                  done in the motion mode search.
1392
 * \param[in,out] orig_dst          A prediction buffer to hold a computed
1393
 *                                  prediction. This will eventually hold the
1394
 *                                  final prediction, and the tmp_dst info will
1395
 *                                  be copied here.
1396
 * \param[in,out] best_est_rd       Estimated RD for motion mode search if
1397
 *                                  do_tx_search (see below) is 0.
1398
 * \param[in]     do_tx_search      Parameter to indicate whether or not to do
1399
 *                                  a full transform search. This will compute
1400
 *                                  an estimated RD for the modes without the
1401
 *                                  transform search and later perform the full
1402
 *                                  transform search on the best candidates.
1403
 * \param[in]     inter_modes_info  InterModesInfo struct to hold inter mode
1404
 *                                  information to perform a full transform
1405
 *                                  search only on winning candidates searched
1406
 *                                  with an estimate for transform coding RD.
1407
 * \param[in]     eval_motion_mode  Boolean whether or not to evaluate motion
1408
 *                                  motion modes other than SIMPLE_TRANSLATION.
1409
 * \param[out]    yrd               Stores the rdcost corresponding to encoding
1410
 *                                  the luma plane.
1411
 * \return Returns INT64_MAX if the determined motion mode is invalid and the
1412
 * current motion mode being tested should be skipped. It returns 0 if the
1413
 * motion mode search is a success.
1414
 */
1415
static int64_t motion_mode_rd(
1416
    const AV1_COMP *const cpi, TileDataEnc *tile_data, MACROBLOCK *const x,
1417
    BLOCK_SIZE bsize, RD_STATS *rd_stats, RD_STATS *rd_stats_y,
1418
    RD_STATS *rd_stats_uv, HandleInterModeArgs *const args, int64_t ref_best_rd,
1419
    int64_t *ref_skip_rd, int *rate_mv, const BUFFER_SET *orig_dst,
1420
    int64_t *best_est_rd, int do_tx_search, InterModesInfo *inter_modes_info,
1421
5.31M
    int eval_motion_mode, int64_t *yrd) {
1422
5.31M
  const AV1_COMMON *const cm = &cpi->common;
1423
5.31M
  const FeatureFlags *const features = &cm->features;
1424
5.31M
  TxfmSearchInfo *txfm_info = &x->txfm_search_info;
1425
5.31M
  const int num_planes = av1_num_planes(cm);
1426
5.31M
  MACROBLOCKD *xd = &x->e_mbd;
1427
5.31M
  MB_MODE_INFO *mbmi = xd->mi[0];
1428
5.31M
  const int is_comp_pred = has_second_ref(mbmi);
1429
5.31M
  const PREDICTION_MODE this_mode = mbmi->mode;
1430
5.31M
  const int rate2_nocoeff = rd_stats->rate;
1431
5.31M
  int best_xskip_txfm = 0;
1432
5.31M
  RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
1433
5.31M
  uint8_t best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
1434
5.31M
  const int rate_mv0 = *rate_mv;
1435
5.31M
  const int interintra_allowed = cm->seq_params->enable_interintra_compound &&
1436
0
                                 is_interintra_allowed(mbmi) &&
1437
0
                                 mbmi->compound_idx;
1438
5.31M
  WARP_SAMPLE_INFO *const warp_sample_info =
1439
5.31M
      &x->warp_sample_info[mbmi->ref_frame[0]];
1440
5.31M
  int *pts0 = warp_sample_info->pts;
1441
5.31M
  int *pts_inref0 = warp_sample_info->pts_inref;
1442
1443
5.31M
  assert(mbmi->ref_frame[1] != INTRA_FRAME);
1444
5.31M
  const MV_REFERENCE_FRAME ref_frame_1 = mbmi->ref_frame[1];
1445
5.31M
  av1_invalid_rd_stats(&best_rd_stats);
1446
5.31M
  mbmi->num_proj_ref = 1;  // assume num_proj_ref >=1
1447
5.31M
  MOTION_MODE last_motion_mode_allowed = SIMPLE_TRANSLATION;
1448
5.31M
  *yrd = INT64_MAX;
1449
5.31M
  if (features->switchable_motion_mode) {
1450
    // Determine which motion modes to search if more than SIMPLE_TRANSLATION
1451
    // is allowed.
1452
5.31M
    last_motion_mode_allowed = motion_mode_allowed(
1453
5.31M
        xd->global_motion, xd, mbmi, features->allow_warped_motion);
1454
5.31M
  }
1455
1456
5.31M
  if (last_motion_mode_allowed == WARPED_CAUSAL) {
1457
    // Collect projection samples used in least squares approximation of
1458
    // the warped motion parameters if WARPED_CAUSAL is going to be searched.
1459
2.12M
    if (warp_sample_info->num < 0) {
1460
488k
      warp_sample_info->num = av1_findSamples(cm, xd, pts0, pts_inref0);
1461
488k
    }
1462
2.12M
    mbmi->num_proj_ref = warp_sample_info->num;
1463
2.12M
  }
1464
5.31M
  const int total_samples = mbmi->num_proj_ref;
1465
5.31M
  if (total_samples == 0) {
1466
    // Do not search WARPED_CAUSAL if there are no samples to use to determine
1467
    // warped parameters.
1468
505k
    last_motion_mode_allowed = OBMC_CAUSAL;
1469
505k
  }
1470
1471
5.31M
  const MB_MODE_INFO base_mbmi = *mbmi;
1472
5.31M
  MB_MODE_INFO best_mbmi;
1473
5.31M
  const int interp_filter = features->interp_filter;
1474
5.31M
  const int switchable_rate =
1475
5.31M
      av1_is_interp_needed(xd)
1476
5.31M
          ? av1_get_switchable_rate(x, xd, interp_filter,
1477
5.18M
                                    cm->seq_params->enable_dual_filter)
1478
5.31M
          : 0;
1479
5.31M
  int64_t best_rd = INT64_MAX;
1480
5.31M
  int best_rate_mv = rate_mv0;
1481
5.31M
  const int mi_row = xd->mi_row;
1482
5.31M
  const int mi_col = xd->mi_col;
1483
5.31M
  int mode_index_start, mode_index_end;
1484
5.31M
  const int txfm_rd_gate_level =
1485
5.31M
      get_txfm_rd_gate_level(cm->seq_params->enable_masked_compound,
1486
5.31M
                             cpi->sf.inter_sf.txfm_rd_gate_level, bsize,
1487
5.31M
                             TX_SEARCH_MOTION_MODE, eval_motion_mode);
1488
1489
  // Modify the start and end index according to speed features. For example,
1490
  // if SIMPLE_TRANSLATION has already been searched according to
1491
  // the motion_mode_for_winner_cand speed feature, update the mode_index_start
1492
  // to avoid searching it again.
1493
5.31M
  update_mode_start_end_index(cpi, mbmi, &mode_index_start, &mode_index_end,
1494
5.31M
                              last_motion_mode_allowed, interintra_allowed,
1495
5.31M
                              eval_motion_mode);
1496
  // Main function loop. This loops over all of the possible motion modes and
1497
  // computes RD to determine the best one. This process includes computing
1498
  // any necessary side information for the motion mode and performing the
1499
  // transform search.
1500
10.1M
  for (int mode_index = mode_index_start; mode_index <= mode_index_end;
1501
5.31M
       mode_index++) {
1502
4.88M
    if (args->skip_motion_mode && mode_index) continue;
1503
4.88M
    int tmp_rate2 = rate2_nocoeff;
1504
4.88M
    const int is_interintra_mode = mode_index > (int)last_motion_mode_allowed;
1505
4.88M
    int tmp_rate_mv = rate_mv0;
1506
1507
4.88M
    *mbmi = base_mbmi;
1508
4.88M
    if (is_interintra_mode) {
1509
      // Only use SIMPLE_TRANSLATION for interintra
1510
0
      mbmi->motion_mode = SIMPLE_TRANSLATION;
1511
4.88M
    } else {
1512
4.88M
      mbmi->motion_mode = (MOTION_MODE)mode_index;
1513
4.88M
      assert(mbmi->ref_frame[1] != INTRA_FRAME);
1514
4.88M
    }
1515
1516
4.88M
    if (cpi->oxcf.algo_cfg.sharpness == 3 &&
1517
0
        (mbmi->motion_mode == OBMC_CAUSAL ||
1518
0
         mbmi->motion_mode == WARPED_CAUSAL))
1519
0
      continue;
1520
1521
    // Do not search OBMC if the probability of selecting it is below a
1522
    // predetermined threshold for this update_type and block size.
1523
4.88M
    const FRAME_UPDATE_TYPE update_type =
1524
4.88M
        get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
1525
4.88M
    int use_actual_frame_probs = 1;
1526
4.88M
    int prune_obmc;
1527
#if CONFIG_FPMT_TEST
1528
    use_actual_frame_probs =
1529
        (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) ? 0 : 1;
1530
    if (!use_actual_frame_probs) {
1531
      prune_obmc = cpi->ppi->temp_frame_probs.obmc_probs[update_type][bsize] <
1532
                   cpi->sf.inter_sf.prune_obmc_prob_thresh;
1533
    }
1534
#endif
1535
4.88M
    if (use_actual_frame_probs) {
1536
4.88M
      prune_obmc = cpi->ppi->frame_probs.obmc_probs[update_type][bsize] <
1537
4.88M
                   cpi->sf.inter_sf.prune_obmc_prob_thresh;
1538
4.88M
    }
1539
4.88M
    if ((!cpi->oxcf.motion_mode_cfg.enable_obmc || prune_obmc) &&
1540
4.88M
        mbmi->motion_mode == OBMC_CAUSAL)
1541
623k
      continue;
1542
1543
4.26M
    if (mbmi->motion_mode == SIMPLE_TRANSLATION && !is_interintra_mode) {
1544
      // SIMPLE_TRANSLATION mode: no need to recalculate.
1545
      // The prediction is calculated before motion_mode_rd() is called in
1546
      // handle_inter_mode()
1547
3.73M
    } else if (mbmi->motion_mode == OBMC_CAUSAL) {
1548
0
      const uint32_t cur_mv = mbmi->mv[0].as_int;
1549
      // OBMC_CAUSAL not allowed for compound prediction
1550
0
      assert(!is_comp_pred);
1551
0
      if (have_newmv_in_inter_mode(this_mode)) {
1552
0
        av1_single_motion_search(cpi, x, bsize, 0, &tmp_rate_mv, INT_MAX, NULL,
1553
0
                                 &mbmi->mv[0], NULL);
1554
0
        tmp_rate2 = rate2_nocoeff - rate_mv0 + tmp_rate_mv;
1555
0
      }
1556
0
      if ((mbmi->mv[0].as_int != cur_mv) || eval_motion_mode) {
1557
        // Build the predictor according to the current motion vector if it has
1558
        // not already been built
1559
0
        av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
1560
0
                                      0, av1_num_planes(cm) - 1);
1561
0
      }
1562
      // Build the inter predictor by blending the predictor corresponding to
1563
      // this MV, and the neighboring blocks using the OBMC model
1564
0
      av1_build_obmc_inter_prediction(
1565
0
          cm, xd, args->above_pred_buf, args->above_pred_stride,
1566
0
          args->left_pred_buf, args->left_pred_stride);
1567
0
#if !CONFIG_REALTIME_ONLY
1568
530k
    } else if (mbmi->motion_mode == WARPED_CAUSAL) {
1569
530k
      int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
1570
530k
      mbmi->motion_mode = WARPED_CAUSAL;
1571
530k
      mbmi->wm_params.wmtype = DEFAULT_WMTYPE;
1572
530k
      mbmi->interp_filters =
1573
530k
          av1_broadcast_interp_filter(av1_unswitchable_filter(interp_filter));
1574
1575
530k
      memcpy(pts, pts0, total_samples * 2 * sizeof(*pts0));
1576
530k
      memcpy(pts_inref, pts_inref0, total_samples * 2 * sizeof(*pts_inref0));
1577
      // Select the samples according to motion vector difference
1578
530k
      if (mbmi->num_proj_ref > 1) {
1579
232k
        mbmi->num_proj_ref = av1_selectSamples(
1580
232k
            &mbmi->mv[0].as_mv, pts, pts_inref, mbmi->num_proj_ref, bsize);
1581
232k
      }
1582
1583
      // Compute the warped motion parameters with a least squares fit
1584
      //  using the collected samples
1585
530k
      if (!av1_find_projection(mbmi->num_proj_ref, pts, pts_inref, bsize,
1586
530k
                               mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
1587
530k
                               &mbmi->wm_params, mi_row, mi_col)) {
1588
430k
        assert(!is_comp_pred);
1589
430k
        if (have_newmv_in_inter_mode(this_mode)) {
1590
          // Refine MV for NEWMV mode
1591
88.1k
          const int_mv mv0 = mbmi->mv[0];
1592
88.1k
          const WarpedMotionParams wm_params0 = mbmi->wm_params;
1593
88.1k
          const int num_proj_ref0 = mbmi->num_proj_ref;
1594
1595
88.1k
          const int_mv ref_mv = av1_get_ref_mv(x, 0);
1596
88.1k
          SUBPEL_MOTION_SEARCH_PARAMS ms_params;
1597
88.1k
          av1_make_default_subpel_ms_params(&ms_params, cpi, x, bsize,
1598
88.1k
                                            &ref_mv.as_mv, NULL);
1599
1600
          // Refine MV in a small range.
1601
88.1k
          av1_refine_warped_mv(xd, cm, &ms_params, bsize, pts0, pts_inref0,
1602
88.1k
                               total_samples, cpi->sf.mv_sf.warp_search_method,
1603
88.1k
                               cpi->sf.mv_sf.warp_search_iters);
1604
1605
88.1k
          if (mv0.as_int != mbmi->mv[0].as_int) {
1606
            // Keep the refined MV and WM parameters.
1607
55.6k
            tmp_rate_mv = av1_mv_bit_cost(
1608
55.6k
                &mbmi->mv[0].as_mv, &ref_mv.as_mv, x->mv_costs->nmv_joint_cost,
1609
55.6k
                x->mv_costs->mv_cost_stack, MV_COST_WEIGHT);
1610
55.6k
            tmp_rate2 = rate2_nocoeff - rate_mv0 + tmp_rate_mv;
1611
55.6k
          } else {
1612
            // Restore the old MV and WM parameters.
1613
32.5k
            mbmi->mv[0] = mv0;
1614
32.5k
            mbmi->wm_params = wm_params0;
1615
32.5k
            mbmi->num_proj_ref = num_proj_ref0;
1616
32.5k
          }
1617
88.1k
        }
1618
1619
        // Build the warped predictor
1620
430k
        av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize, 0,
1621
430k
                                      av1_num_planes(cm) - 1);
1622
430k
      } else {
1623
99.3k
        continue;
1624
99.3k
      }
1625
530k
#endif  // !CONFIG_REALTIME_ONLY
1626
18.4E
    } else if (is_interintra_mode) {
1627
0
      const int ret =
1628
0
          av1_handle_inter_intra_mode(cpi, x, bsize, mbmi, args, ref_best_rd,
1629
0
                                      &tmp_rate_mv, &tmp_rate2, orig_dst);
1630
0
      if (ret < 0) continue;
1631
0
    }
1632
1633
    // If we are searching newmv and the mv is the same as refmv, skip the
1634
    // current mode
1635
4.16M
    if (!av1_check_newmv_joint_nonzero(cm, x)) continue;
1636
1637
    // Update rd_stats for the current motion mode
1638
3.95M
    txfm_info->skip_txfm = 0;
1639
3.95M
    rd_stats->dist = 0;
1640
3.95M
    rd_stats->sse = 0;
1641
3.95M
    rd_stats->skip_txfm = 1;
1642
3.95M
    rd_stats->rate = tmp_rate2;
1643
3.95M
    const ModeCosts *mode_costs = &x->mode_costs;
1644
3.95M
    if (mbmi->motion_mode != WARPED_CAUSAL) rd_stats->rate += switchable_rate;
1645
3.95M
    if (interintra_allowed) {
1646
0
      rd_stats->rate +=
1647
0
          mode_costs->interintra_cost[size_group_lookup[bsize]]
1648
0
                                     [mbmi->ref_frame[1] == INTRA_FRAME];
1649
0
    }
1650
3.95M
    if ((last_motion_mode_allowed > SIMPLE_TRANSLATION) &&
1651
1.84M
        (mbmi->ref_frame[1] != INTRA_FRAME)) {
1652
1.84M
      if (last_motion_mode_allowed == WARPED_CAUSAL) {
1653
1.49M
        rd_stats->rate +=
1654
1.49M
            mode_costs->motion_mode_cost[bsize][mbmi->motion_mode];
1655
1.49M
      } else {
1656
357k
        rd_stats->rate +=
1657
357k
            mode_costs->motion_mode_cost1[bsize][mbmi->motion_mode];
1658
357k
      }
1659
1.84M
    }
1660
1661
3.95M
    int64_t this_yrd = INT64_MAX;
1662
1663
3.95M
    if (!do_tx_search) {
1664
      // Avoid doing a transform search here to speed up the overall mode
1665
      // search. It will be done later in the mode search if the current
1666
      // motion mode seems promising.
1667
146k
      int64_t curr_sse = -1;
1668
146k
      int64_t sse_y = -1;
1669
146k
      int est_residue_cost = 0;
1670
146k
      int64_t est_dist = 0;
1671
146k
      int64_t est_rd = 0;
1672
146k
      if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1) {
1673
87.7k
        curr_sse = get_sse(cpi, x, &sse_y);
1674
87.7k
        const int has_est_rd = get_est_rate_dist(tile_data, bsize, curr_sse,
1675
87.7k
                                                 &est_residue_cost, &est_dist);
1676
87.7k
        (void)has_est_rd;
1677
87.7k
        assert(has_est_rd);
1678
87.7k
      } else if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 2 ||
1679
59.1k
                 cpi->sf.rt_sf.use_nonrd_pick_mode) {
1680
59.1k
        model_rd_sb_fn[MODELRD_TYPE_MOTION_MODE_RD](
1681
59.1k
            cpi, bsize, x, xd, 0, num_planes - 1, &est_residue_cost, &est_dist,
1682
59.1k
            NULL, &curr_sse, NULL, NULL, NULL);
1683
59.1k
        sse_y = x->pred_sse[xd->mi[0]->ref_frame[0]];
1684
59.1k
      }
1685
146k
      est_rd = RDCOST(x->rdmult, rd_stats->rate + est_residue_cost, est_dist);
1686
146k
      if (est_rd * 0.80 > *best_est_rd) {
1687
2.87k
        mbmi->ref_frame[1] = ref_frame_1;
1688
2.87k
        continue;
1689
2.87k
      }
1690
144k
      const int mode_rate = rd_stats->rate;
1691
144k
      rd_stats->rate += est_residue_cost;
1692
144k
      rd_stats->dist = est_dist;
1693
144k
      rd_stats->rdcost = est_rd;
1694
144k
      if (rd_stats->rdcost < *best_est_rd) {
1695
85.1k
        *best_est_rd = rd_stats->rdcost;
1696
85.1k
        assert(sse_y >= 0);
1697
85.1k
        ref_skip_rd[1] = txfm_rd_gate_level
1698
85.1k
                             ? RDCOST(x->rdmult, mode_rate, (sse_y << 4))
1699
85.1k
                             : INT64_MAX;
1700
85.1k
      }
1701
144k
      if (cm->current_frame.reference_mode == SINGLE_REFERENCE) {
1702
0
        if (!is_comp_pred) {
1703
0
          assert(curr_sse >= 0);
1704
0
          inter_modes_info_push(inter_modes_info, mode_rate, curr_sse,
1705
0
                                rd_stats->rdcost, rd_stats, rd_stats_y,
1706
0
                                rd_stats_uv, mbmi);
1707
0
        }
1708
144k
      } else {
1709
144k
        assert(curr_sse >= 0);
1710
144k
        inter_modes_info_push(inter_modes_info, mode_rate, curr_sse,
1711
144k
                              rd_stats->rdcost, rd_stats, rd_stats_y,
1712
144k
                              rd_stats_uv, mbmi);
1713
144k
      }
1714
144k
      mbmi->skip_txfm = 0;
1715
144k
      increase_motion_mode_rdstats(cpi, mbmi, rd_stats, NULL, NULL);
1716
1717
3.80M
    } else {
1718
      // Perform full transform search
1719
3.80M
      int64_t skip_rd = INT64_MAX;
1720
3.80M
      int64_t skip_rdy = INT64_MAX;
1721
3.80M
      if (txfm_rd_gate_level) {
1722
        // Check if the mode is good enough based on skip RD
1723
3.56M
        int64_t sse_y = INT64_MAX;
1724
3.56M
        int64_t curr_sse = get_sse(cpi, x, &sse_y);
1725
3.56M
        skip_rd = RDCOST(x->rdmult, rd_stats->rate, curr_sse);
1726
3.56M
        skip_rdy = RDCOST(x->rdmult, rd_stats->rate, (sse_y << 4));
1727
3.56M
        int eval_txfm = check_txfm_eval(x, bsize, ref_skip_rd[0], skip_rd,
1728
3.56M
                                        txfm_rd_gate_level, 0);
1729
3.56M
        if (!eval_txfm) continue;
1730
3.56M
      }
1731
1732
      // Do transform search
1733
3.30M
      const int mode_rate = rd_stats->rate;
1734
3.30M
      if (!av1_txfm_search(cpi, x, bsize, rd_stats, rd_stats_y, rd_stats_uv,
1735
3.30M
                           rd_stats->rate, ref_best_rd)) {
1736
1.44M
        if (rd_stats_y->rate == INT_MAX && mode_index == 0) {
1737
7.19k
          return INT64_MAX;
1738
7.19k
        }
1739
1.43M
        continue;
1740
1.44M
      }
1741
1.86M
      const int skip_ctx = av1_get_skip_txfm_context(xd);
1742
1.86M
      const int *skip_txfm_cost_ptr = mode_costs->skip_txfm_cost[skip_ctx];
1743
1744
1.86M
      if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1) {
1745
436k
        inter_mode_data_push(tile_data, mbmi->bsize, rd_stats->sse,
1746
436k
                             rd_stats->dist,
1747
436k
                             rd_stats_y->rate + rd_stats_uv->rate +
1748
436k
                                 skip_txfm_cost_ptr[mbmi->skip_txfm]);
1749
436k
      }
1750
      // Scale RD_STATS after mode stats are collected. Thus unscaled metrics
1751
      // are used for model generation
1752
1.86M
      increase_motion_mode_rdstats(cpi, mbmi, rd_stats, rd_stats_y,
1753
1.86M
                                   rd_stats_uv);
1754
1.86M
      const int skip_rate =
1755
1.86M
          rd_stats->skip_txfm ? skip_txfm_cost_ptr[1] : skip_txfm_cost_ptr[0];
1756
1757
1.86M
      const int32_t scaled_skip_rate =
1758
1.86M
          increase_motion_mode_rate(cpi, mbmi, skip_rate);
1759
1.86M
      const int y_rate =
1760
1.86M
          scaled_skip_rate + (rd_stats->skip_txfm ? 0 : rd_stats_y->rate);
1761
1.86M
      this_yrd = RDCOST(x->rdmult, y_rate + mode_rate, rd_stats_y->dist);
1762
1763
1.86M
      const int64_t curr_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
1764
1.86M
      if (curr_rd < ref_best_rd) {
1765
1.86M
        ref_best_rd = curr_rd;
1766
1.86M
        ref_skip_rd[0] = skip_rd;
1767
1.86M
        ref_skip_rd[1] = skip_rdy;
1768
1.86M
      }
1769
1.86M
    }
1770
1771
2.00M
    if (this_mode == GLOBALMV || this_mode == GLOBAL_GLOBALMV) {
1772
5.05k
      if (is_nontrans_global_motion(xd, xd->mi[0])) {
1773
5.04k
        mbmi->interp_filters =
1774
5.04k
            av1_broadcast_interp_filter(av1_unswitchable_filter(interp_filter));
1775
5.04k
      }
1776
5.05k
    }
1777
1778
2.00M
    if (this_yrd < INT64_MAX) {
1779
1.86M
      adjust_cost(cpi, x, &this_yrd, /*is_inter_pred=*/true);
1780
1.86M
    }
1781
2.00M
    adjust_rdcost(cpi, x, rd_stats, /*is_inter_pred=*/true);
1782
    // Bug 494653438: If do_tx_search is 0, rd_stats_y is uninitialized, so
1783
    // valgrind will warn if we use rd_stats_y->rdcost in a conditional.
1784
2.01M
    if (!do_tx_search || rd_stats_y->rdcost < INT64_MAX) {
1785
2.01M
      adjust_rdcost(cpi, x, rd_stats_y, /*is_inter_pred=*/true);
1786
2.01M
    }
1787
1788
2.00M
    const int64_t tmp_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
1789
2.00M
    if (mode_index == 0) {
1790
1.87M
      args->simple_rd[this_mode][mbmi->ref_mv_idx][mbmi->ref_frame[0]] = tmp_rd;
1791
1.87M
    }
1792
2.00M
    if (mode_index == 0 || tmp_rd < best_rd) {
1793
      // Update best_rd data if this is the best motion mode so far
1794
2.00M
      best_mbmi = *mbmi;
1795
2.00M
      best_rd = tmp_rd;
1796
2.00M
      best_rd_stats = *rd_stats;
1797
2.00M
      best_rd_stats_y = *rd_stats_y;
1798
2.00M
      best_rate_mv = tmp_rate_mv;
1799
2.00M
      *yrd = this_yrd;
1800
2.00M
      if (num_planes > 1) best_rd_stats_uv = *rd_stats_uv;
1801
2.00M
      av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width);
1802
2.00M
      best_xskip_txfm = mbmi->skip_txfm;
1803
2.00M
    }
1804
2.00M
  }
1805
  // Update RD and mbmi stats for selected motion mode
1806
5.30M
  mbmi->ref_frame[1] = ref_frame_1;
1807
5.30M
  *rate_mv = best_rate_mv;
1808
5.30M
  if (best_rd == INT64_MAX || !av1_check_newmv_joint_nonzero(cm, x)) {
1809
3.31M
    av1_invalid_rd_stats(rd_stats);
1810
3.31M
    restore_dst_buf(xd, *orig_dst, num_planes);
1811
3.31M
    return INT64_MAX;
1812
3.31M
  }
1813
1.99M
  *mbmi = best_mbmi;
1814
1.99M
  *rd_stats = best_rd_stats;
1815
1.99M
  *rd_stats_y = best_rd_stats_y;
1816
1.99M
  if (num_planes > 1) *rd_stats_uv = best_rd_stats_uv;
1817
1.99M
  av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width);
1818
1.99M
  txfm_info->skip_txfm = best_xskip_txfm;
1819
1820
1.99M
  restore_dst_buf(xd, *orig_dst, num_planes);
1821
1.99M
  return 0;
1822
5.30M
}
1823
1824
static int64_t skip_mode_rd(RD_STATS *rd_stats, const AV1_COMP *const cpi,
1825
                            MACROBLOCK *const x, BLOCK_SIZE bsize,
1826
135k
                            const BUFFER_SET *const orig_dst, int64_t best_rd) {
1827
135k
  assert(bsize < BLOCK_SIZES_ALL);
1828
135k
  const AV1_COMMON *cm = &cpi->common;
1829
135k
  const int num_planes = av1_num_planes(cm);
1830
135k
  MACROBLOCKD *const xd = &x->e_mbd;
1831
135k
  const int mi_row = xd->mi_row;
1832
135k
  const int mi_col = xd->mi_col;
1833
135k
  int64_t total_sse = 0;
1834
135k
  int64_t this_rd = INT64_MAX;
1835
135k
  const int skip_mode_ctx = av1_get_skip_mode_context(xd);
1836
135k
  rd_stats->rate = x->mode_costs.skip_mode_cost[skip_mode_ctx][1];
1837
1838
180k
  for (int plane = 0; plane < num_planes; ++plane) {
1839
    // Call av1_enc_build_inter_predictor() for one plane at a time.
1840
165k
    av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
1841
165k
                                  plane, plane);
1842
165k
    const struct macroblockd_plane *const pd = &xd->plane[plane];
1843
165k
    const BLOCK_SIZE plane_bsize =
1844
165k
        get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
1845
1846
165k
    av1_subtract_plane(x, plane_bsize, plane, cpi->do_border_pad);
1847
1848
165k
    int64_t sse =
1849
165k
        av1_pixel_diff_dist(x, plane, 0, 0, plane_bsize, plane_bsize, NULL);
1850
165k
    if (is_cur_buf_hbd(xd)) sse = ROUND_POWER_OF_TWO(sse, (xd->bd - 8) * 2);
1851
165k
    sse <<= 4;
1852
165k
    total_sse += sse;
1853
    // When current rd cost is more than the best rd, skip evaluation of
1854
    // remaining planes.
1855
165k
    this_rd = RDCOST(x->rdmult, rd_stats->rate, total_sse);
1856
165k
    if (this_rd > best_rd) break;
1857
165k
  }
1858
1859
135k
  rd_stats->dist = rd_stats->sse = total_sse;
1860
135k
  rd_stats->rdcost = this_rd;
1861
1862
135k
  restore_dst_buf(xd, *orig_dst, num_planes);
1863
135k
  return 0;
1864
135k
}
1865
1866
// Check NEARESTMV, NEARMV, GLOBALMV ref mvs for duplicate and skip the relevant
1867
// mode
1868
// Note(rachelbarker): This speed feature currently does not interact correctly
1869
// with global motion. The issue is that, when global motion is used, GLOBALMV
1870
// produces a different prediction to NEARESTMV/NEARMV even if the motion
1871
// vectors are the same. Thus GLOBALMV should not be pruned in this case.
1872
static inline int check_repeat_ref_mv(const MB_MODE_INFO_EXT *mbmi_ext,
1873
                                      int ref_idx,
1874
                                      const MV_REFERENCE_FRAME *ref_frame,
1875
0
                                      PREDICTION_MODE single_mode) {
1876
0
  const uint8_t ref_frame_type = av1_ref_frame_type(ref_frame);
1877
0
  const int ref_mv_count = mbmi_ext->ref_mv_count[ref_frame_type];
1878
0
  assert(single_mode != NEWMV);
1879
0
  if (single_mode == NEARESTMV) {
1880
0
    return 0;
1881
0
  } else if (single_mode == NEARMV) {
1882
    // when ref_mv_count = 0, NEARESTMV and NEARMV are same as GLOBALMV
1883
    // when ref_mv_count = 1, NEARMV is same as GLOBALMV
1884
0
    if (ref_mv_count < 2) return 1;
1885
0
  } else if (single_mode == GLOBALMV) {
1886
    // when ref_mv_count == 0, GLOBALMV is same as NEARESTMV
1887
0
    if (ref_mv_count == 0) return 1;
1888
    // when ref_mv_count == 1, NEARMV is same as GLOBALMV
1889
0
    else if (ref_mv_count == 1)
1890
0
      return 0;
1891
1892
0
    int stack_size = AOMMIN(USABLE_REF_MV_STACK_SIZE, ref_mv_count);
1893
    // Check GLOBALMV is matching with any mv in ref_mv_stack
1894
0
    for (int ref_mv_idx = 0; ref_mv_idx < stack_size; ref_mv_idx++) {
1895
0
      int_mv this_mv;
1896
1897
0
      if (ref_idx == 0)
1898
0
        this_mv = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].this_mv;
1899
0
      else
1900
0
        this_mv = mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_idx].comp_mv;
1901
1902
0
      if (this_mv.as_int == mbmi_ext->global_mvs[ref_frame[ref_idx]].as_int)
1903
0
        return 1;
1904
0
    }
1905
0
  }
1906
0
  return 0;
1907
0
}
1908
1909
static inline int get_this_mv(int_mv *this_mv, PREDICTION_MODE this_mode,
1910
                              int ref_idx, int ref_mv_idx,
1911
                              int skip_repeated_ref_mv,
1912
                              const MV_REFERENCE_FRAME *ref_frame,
1913
6.03M
                              const MB_MODE_INFO_EXT *mbmi_ext) {
1914
6.03M
  const PREDICTION_MODE single_mode = get_single_mode(this_mode, ref_idx);
1915
6.03M
  assert(is_inter_singleref_mode(single_mode));
1916
6.03M
  if (single_mode == NEWMV) {
1917
1.98M
    this_mv->as_int = INVALID_MV;
1918
4.05M
  } else if (single_mode == GLOBALMV) {
1919
1.32M
    if (skip_repeated_ref_mv &&
1920
0
        check_repeat_ref_mv(mbmi_ext, ref_idx, ref_frame, single_mode))
1921
0
      return 0;
1922
1.32M
    *this_mv = mbmi_ext->global_mvs[ref_frame[ref_idx]];
1923
2.72M
  } else {
1924
2.72M
    assert(single_mode == NEARMV || single_mode == NEARESTMV);
1925
2.72M
    const uint8_t ref_frame_type = av1_ref_frame_type(ref_frame);
1926
2.72M
    const int ref_mv_offset = single_mode == NEARESTMV ? 0 : ref_mv_idx + 1;
1927
2.72M
    if (ref_mv_offset < mbmi_ext->ref_mv_count[ref_frame_type]) {
1928
1.66M
      assert(ref_mv_offset >= 0);
1929
1.66M
      if (ref_idx == 0) {
1930
1.30M
        *this_mv =
1931
1.30M
            mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_offset].this_mv;
1932
1.30M
      } else {
1933
360k
        *this_mv =
1934
360k
            mbmi_ext->ref_mv_stack[ref_frame_type][ref_mv_offset].comp_mv;
1935
360k
      }
1936
1.66M
    } else {
1937
1.06M
      if (skip_repeated_ref_mv &&
1938
0
          check_repeat_ref_mv(mbmi_ext, ref_idx, ref_frame, single_mode))
1939
0
        return 0;
1940
1.06M
      *this_mv = mbmi_ext->global_mvs[ref_frame[ref_idx]];
1941
1.06M
    }
1942
2.72M
  }
1943
6.03M
  return 1;
1944
6.03M
}
1945
1946
// Skip NEARESTMV and NEARMV modes based on refmv weight computed in ref mv list
1947
// population
1948
static inline int skip_nearest_near_mv_using_refmv_weight(
1949
    const MACROBLOCK *const x, const PREDICTION_MODE this_mode,
1950
4.39M
    const int8_t ref_frame_type, PREDICTION_MODE best_mode) {
1951
4.39M
  if (this_mode != NEARESTMV && this_mode != NEARMV) return 0;
1952
  // Do not skip the mode if the current block has not yet obtained a valid
1953
  // inter mode.
1954
1.97M
  if (!is_inter_mode(best_mode)) return 0;
1955
1956
1.11M
  const MACROBLOCKD *xd = &x->e_mbd;
1957
  // Do not skip the mode if both the top and left neighboring blocks are not
1958
  // available.
1959
1.11M
  if (!xd->left_available || !xd->up_available) return 0;
1960
564k
  const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
1961
564k
  const uint16_t *const ref_mv_weight = mbmi_ext->weight[ref_frame_type];
1962
564k
  const int ref_mv_count =
1963
564k
      AOMMIN(MAX_REF_MV_SEARCH, mbmi_ext->ref_mv_count[ref_frame_type]);
1964
1965
564k
  if (ref_mv_count == 0) return 0;
1966
  // If ref mv list has at least one nearest candidate do not prune NEARESTMV
1967
358k
  if (this_mode == NEARESTMV && ref_mv_weight[0] >= REF_CAT_LEVEL) return 0;
1968
1969
  // Count number of ref mvs populated from nearest candidates
1970
325k
  int nearest_refmv_count = 0;
1971
911k
  for (int ref_mv_idx = 0; ref_mv_idx < ref_mv_count; ref_mv_idx++) {
1972
585k
    if (ref_mv_weight[ref_mv_idx] >= REF_CAT_LEVEL) nearest_refmv_count++;
1973
585k
  }
1974
1975
  // nearest_refmv_count indicates the closeness of block motion characteristics
1976
  // with respect to its spatial neighbor. Smaller value of nearest_refmv_count
1977
  // w.r.t to ref_mv_count means less correlation with its spatial neighbors.
1978
  // Hence less possibility for NEARESTMV and NEARMV modes becoming the best
1979
  // mode since these modes work well for blocks that shares similar motion
1980
  // characteristics with its neighbor. Thus, NEARMV mode is pruned when
1981
  // nearest_refmv_count is relatively smaller than ref_mv_count and NEARESTMV
1982
  // mode is pruned if none of the ref mvs are populated from nearest candidate.
1983
325k
  const int prune_thresh = 1 + (ref_mv_count >= 2);
1984
325k
  if (nearest_refmv_count < prune_thresh) return 1;
1985
120k
  return 0;
1986
325k
}
1987
1988
// This function update the non-new mv for the current prediction mode
1989
static inline int build_cur_mv(int_mv *cur_mv, PREDICTION_MODE this_mode,
1990
                               const AV1_COMMON *cm, const MACROBLOCK *x,
1991
5.44M
                               int skip_repeated_ref_mv) {
1992
5.44M
  const MACROBLOCKD *xd = &x->e_mbd;
1993
5.44M
  const MB_MODE_INFO *mbmi = xd->mi[0];
1994
5.44M
  const int is_comp_pred = has_second_ref(mbmi);
1995
1996
5.44M
  int ret = 1;
1997
11.4M
  for (int i = 0; i < is_comp_pred + 1; ++i) {
1998
6.03M
    int_mv this_mv;
1999
6.03M
    this_mv.as_int = INVALID_MV;
2000
6.03M
    ret = get_this_mv(&this_mv, this_mode, i, mbmi->ref_mv_idx,
2001
6.03M
                      skip_repeated_ref_mv, mbmi->ref_frame, &x->mbmi_ext);
2002
6.03M
    if (!ret) return 0;
2003
6.03M
    const PREDICTION_MODE single_mode = get_single_mode(this_mode, i);
2004
6.03M
    if (single_mode == NEWMV) {
2005
1.98M
      const uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2006
1.98M
      cur_mv[i] =
2007
1.98M
          (i == 0) ? x->mbmi_ext.ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
2008
1.84M
                         .this_mv
2009
1.98M
                   : x->mbmi_ext.ref_mv_stack[ref_frame_type][mbmi->ref_mv_idx]
2010
143k
                         .comp_mv;
2011
4.05M
    } else {
2012
4.05M
      ret &= clamp_and_check_mv(cur_mv + i, this_mv, cm, x);
2013
4.05M
    }
2014
6.03M
  }
2015
5.44M
  return ret;
2016
5.44M
}
2017
2018
static inline int get_drl_cost(const MB_MODE_INFO *mbmi,
2019
                               const MB_MODE_INFO_EXT *mbmi_ext,
2020
                               const int (*const drl_mode_cost0)[2],
2021
6.79M
                               int8_t ref_frame_type) {
2022
6.79M
  int cost = 0;
2023
6.79M
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
2024
6.66M
    for (int idx = 0; idx < 2; ++idx) {
2025
4.94M
      if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2026
2.55M
        uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->weight[ref_frame_type], idx);
2027
2.55M
        cost += drl_mode_cost0[drl_ctx][mbmi->ref_mv_idx != idx];
2028
2.55M
        if (mbmi->ref_mv_idx == idx) return cost;
2029
2.55M
      }
2030
4.94M
    }
2031
1.71M
    return cost;
2032
2.94M
  }
2033
2034
3.85M
  if (have_nearmv_in_inter_mode(mbmi->mode)) {
2035
2.93M
    for (int idx = 1; idx < 3; ++idx) {
2036
2.09M
      if (mbmi_ext->ref_mv_count[ref_frame_type] > idx + 1) {
2037
728k
        uint8_t drl_ctx = av1_drl_ctx(mbmi_ext->weight[ref_frame_type], idx);
2038
728k
        cost += drl_mode_cost0[drl_ctx][mbmi->ref_mv_idx != (idx - 1)];
2039
728k
        if (mbmi->ref_mv_idx == (idx - 1)) return cost;
2040
728k
      }
2041
2.09M
    }
2042
838k
    return cost;
2043
1.14M
  }
2044
2.70M
  return cost;
2045
3.85M
}
2046
2047
static inline int is_single_newmv_valid(const HandleInterModeArgs *const args,
2048
                                        const MB_MODE_INFO *const mbmi,
2049
300k
                                        PREDICTION_MODE this_mode) {
2050
642k
  for (int ref_idx = 0; ref_idx < 2; ++ref_idx) {
2051
478k
    const PREDICTION_MODE single_mode = get_single_mode(this_mode, ref_idx);
2052
478k
    const MV_REFERENCE_FRAME ref = mbmi->ref_frame[ref_idx];
2053
478k
    if (single_mode == NEWMV &&
2054
437k
        args->single_newmv_valid[mbmi->ref_mv_idx][ref] == 0) {
2055
137k
      return 0;
2056
137k
    }
2057
478k
  }
2058
163k
  return 1;
2059
300k
}
2060
2061
static int get_drl_refmv_count(const MACROBLOCK *const x,
2062
                               const MV_REFERENCE_FRAME *ref_frame,
2063
5.05M
                               PREDICTION_MODE mode) {
2064
5.05M
  const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2065
5.05M
  const int8_t ref_frame_type = av1_ref_frame_type(ref_frame);
2066
5.05M
  const int has_nearmv = have_nearmv_in_inter_mode(mode) ? 1 : 0;
2067
5.05M
  const int ref_mv_count = mbmi_ext->ref_mv_count[ref_frame_type];
2068
5.05M
  const int only_newmv = (mode == NEWMV || mode == NEW_NEWMV);
2069
5.05M
  const int has_drl =
2070
5.05M
      (has_nearmv && ref_mv_count > 2) || (only_newmv && ref_mv_count > 1);
2071
5.05M
  const int ref_set =
2072
5.05M
      has_drl ? AOMMIN(MAX_REF_MV_SEARCH, ref_mv_count - has_nearmv) : 1;
2073
2074
5.05M
  return ref_set;
2075
5.05M
}
2076
2077
// Checks if particular ref_mv_idx should be pruned.
2078
static int prune_ref_mv_idx_using_qindex(const int reduce_inter_modes,
2079
                                         const int qindex,
2080
36.8k
                                         const int ref_mv_idx) {
2081
36.8k
  if (reduce_inter_modes >= 3) return 1;
2082
  // Q-index logic based pruning is enabled only for
2083
  // reduce_inter_modes = 2.
2084
18.4E
  assert(reduce_inter_modes == 2);
2085
  // When reduce_inter_modes=2, pruning happens as below based on q index.
2086
  // For q index range between 0 and 85: prune if ref_mv_idx >= 1.
2087
  // For q index range between 86 and 170: prune if ref_mv_idx == 2.
2088
  // For q index range between 171 and 255: no pruning.
2089
18.4E
  const int min_prune_ref_mv_idx = (qindex * 3 / QINDEX_RANGE) + 1;
2090
18.4E
  return (ref_mv_idx >= min_prune_ref_mv_idx);
2091
36.8k
}
2092
2093
// Whether this reference motion vector can be skipped, based on initial
2094
// heuristics.
2095
static bool ref_mv_idx_early_breakout(
2096
    const SPEED_FEATURES *const sf,
2097
    const RefFrameDistanceInfo *const ref_frame_dist_info, MACROBLOCK *x,
2098
    const HandleInterModeArgs *const args, int64_t ref_best_rd,
2099
1.34M
    int ref_mv_idx) {
2100
1.34M
  MACROBLOCKD *xd = &x->e_mbd;
2101
1.34M
  MB_MODE_INFO *mbmi = xd->mi[0];
2102
1.34M
  const MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2103
1.34M
  const int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2104
1.34M
  const int is_comp_pred = has_second_ref(mbmi);
2105
1.34M
  if (sf->inter_sf.reduce_inter_modes && ref_mv_idx > 0) {
2106
771k
    if (mbmi->ref_frame[0] == LAST2_FRAME ||
2107
761k
        mbmi->ref_frame[0] == LAST3_FRAME ||
2108
761k
        mbmi->ref_frame[1] == LAST2_FRAME ||
2109
761k
        mbmi->ref_frame[1] == LAST3_FRAME) {
2110
9.79k
      const int has_nearmv = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
2111
9.79k
      if (mbmi_ext->weight[ref_frame_type][ref_mv_idx + has_nearmv] <
2112
9.79k
          REF_CAT_LEVEL) {
2113
9.76k
        return true;
2114
9.76k
      }
2115
9.79k
    }
2116
    // TODO(any): Experiment with reduce_inter_modes for compound prediction
2117
761k
    if (sf->inter_sf.reduce_inter_modes >= 2 && !is_comp_pred &&
2118
564k
        have_newmv_in_inter_mode(mbmi->mode)) {
2119
432k
      if (mbmi->ref_frame[0] != ref_frame_dist_info->nearest_past_ref &&
2120
114k
          mbmi->ref_frame[0] != ref_frame_dist_info->nearest_future_ref) {
2121
36.8k
        const int has_nearmv = have_nearmv_in_inter_mode(mbmi->mode) ? 1 : 0;
2122
36.8k
        const int do_prune = prune_ref_mv_idx_using_qindex(
2123
36.8k
            sf->inter_sf.reduce_inter_modes, x->qindex, ref_mv_idx);
2124
36.8k
        if (do_prune &&
2125
36.8k
            (mbmi_ext->weight[ref_frame_type][ref_mv_idx + has_nearmv] <
2126
36.8k
             REF_CAT_LEVEL)) {
2127
35.7k
          return true;
2128
35.7k
        }
2129
36.8k
      }
2130
432k
    }
2131
761k
  }
2132
2133
1.29M
  mbmi->ref_mv_idx = ref_mv_idx;
2134
1.29M
  if (is_comp_pred && (!is_single_newmv_valid(args, mbmi, mbmi->mode))) {
2135
137k
    return true;
2136
137k
  }
2137
1.15M
  size_t est_rd_rate = args->ref_frame_cost + args->single_comp_cost;
2138
1.15M
  const int drl_cost = get_drl_cost(
2139
1.15M
      mbmi, mbmi_ext, x->mode_costs.drl_mode_cost0, ref_frame_type);
2140
1.15M
  est_rd_rate += drl_cost;
2141
1.15M
  if (RDCOST(x->rdmult, est_rd_rate, 0) > ref_best_rd &&
2142
158
      mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV) {
2143
158
    return true;
2144
158
  }
2145
1.15M
  return false;
2146
1.15M
}
2147
2148
// Compute the estimated RD cost for the motion vector with simple translation.
2149
static int64_t simple_translation_pred_rd(AV1_COMP *const cpi, MACROBLOCK *x,
2150
                                          HandleInterModeArgs *args,
2151
                                          int ref_mv_idx, int64_t ref_best_rd,
2152
7.90k
                                          BLOCK_SIZE bsize) {
2153
7.90k
  MACROBLOCKD *xd = &x->e_mbd;
2154
7.90k
  MB_MODE_INFO *mbmi = xd->mi[0];
2155
7.90k
  MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2156
7.90k
  const int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2157
7.90k
  const AV1_COMMON *cm = &cpi->common;
2158
7.90k
  const int is_comp_pred = has_second_ref(mbmi);
2159
7.90k
  const ModeCosts *mode_costs = &x->mode_costs;
2160
2161
7.90k
  struct macroblockd_plane *p = xd->plane;
2162
7.90k
  const BUFFER_SET orig_dst = {
2163
7.90k
    { p[0].dst.buf, p[1].dst.buf, p[2].dst.buf },
2164
7.90k
    { p[0].dst.stride, p[1].dst.stride, p[2].dst.stride },
2165
7.90k
  };
2166
7.90k
  RD_STATS rd_stats;
2167
7.90k
  av1_init_rd_stats(&rd_stats);
2168
2169
7.90k
  mbmi->interinter_comp.type = COMPOUND_AVERAGE;
2170
7.90k
  mbmi->comp_group_idx = 0;
2171
7.90k
  mbmi->compound_idx = 1;
2172
7.90k
  if (mbmi->ref_frame[1] == INTRA_FRAME) {
2173
0
    mbmi->ref_frame[1] = NONE_FRAME;
2174
0
  }
2175
7.90k
  int16_t mode_ctx =
2176
7.90k
      av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame);
2177
2178
7.90k
  mbmi->num_proj_ref = 0;
2179
7.90k
  mbmi->motion_mode = SIMPLE_TRANSLATION;
2180
7.90k
  mbmi->ref_mv_idx = ref_mv_idx;
2181
2182
7.90k
  rd_stats.rate += args->ref_frame_cost + args->single_comp_cost;
2183
7.90k
  const int drl_cost =
2184
7.90k
      get_drl_cost(mbmi, mbmi_ext, mode_costs->drl_mode_cost0, ref_frame_type);
2185
7.90k
  rd_stats.rate += drl_cost;
2186
2187
7.90k
  int_mv cur_mv[2];
2188
7.90k
  if (!build_cur_mv(cur_mv, mbmi->mode, cm, x, 0)) {
2189
382
    return INT64_MAX;
2190
382
  }
2191
7.90k
  assert(have_nearmv_in_inter_mode(mbmi->mode));
2192
15.7k
  for (int i = 0; i < is_comp_pred + 1; ++i) {
2193
8.24k
    mbmi->mv[i].as_int = cur_mv[i].as_int;
2194
8.24k
  }
2195
7.52k
  const int ref_mv_cost = cost_mv_ref(mode_costs, mbmi->mode, mode_ctx);
2196
7.52k
  rd_stats.rate += ref_mv_cost;
2197
2198
7.52k
  if (RDCOST(x->rdmult, rd_stats.rate, 0) > ref_best_rd) {
2199
0
    return INT64_MAX;
2200
0
  }
2201
2202
7.52k
  mbmi->motion_mode = SIMPLE_TRANSLATION;
2203
7.52k
  mbmi->num_proj_ref = 0;
2204
7.52k
  if (is_comp_pred) {
2205
    // Only compound_average
2206
722
    mbmi->interinter_comp.type = COMPOUND_AVERAGE;
2207
722
    mbmi->comp_group_idx = 0;
2208
722
    mbmi->compound_idx = 1;
2209
722
  }
2210
7.52k
  set_default_interp_filters(mbmi, cm->features.interp_filter);
2211
2212
7.52k
  const int mi_row = xd->mi_row;
2213
7.52k
  const int mi_col = xd->mi_col;
2214
7.52k
  av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, &orig_dst, bsize,
2215
7.52k
                                AOM_PLANE_Y, AOM_PLANE_Y);
2216
7.52k
  int est_rate;
2217
7.52k
  int64_t est_dist;
2218
7.52k
  model_rd_sb_fn[MODELRD_CURVFIT](cpi, bsize, x, xd, 0, 0, &est_rate, &est_dist,
2219
7.52k
                                  NULL, NULL, NULL, NULL, NULL);
2220
7.52k
  return RDCOST(x->rdmult, rd_stats.rate + est_rate, est_dist);
2221
7.52k
}
2222
2223
// Represents a set of integers, from 0 to sizeof(int) * 8, as bits in
2224
// an integer. 0 for the i-th bit means that integer is excluded, 1 means
2225
// it is included.
2226
1.16M
static inline void mask_set_bit(int *mask, int index) { *mask |= (1 << index); }
2227
2228
5.65M
static inline bool mask_check_bit(int mask, int index) {
2229
5.65M
  return (mask >> index) & 0x1;
2230
5.65M
}
2231
2232
// Before performing the full MV search in handle_inter_mode, do a simple
2233
// translation search and see if we can eliminate any motion vectors.
2234
// Returns an integer where, if the i-th bit is set, it means that the i-th
2235
// motion vector should be searched. This is only set for NEAR_MV.
2236
static int ref_mv_idx_to_search(AV1_COMP *const cpi, MACROBLOCK *x,
2237
                                HandleInterModeArgs *const args,
2238
                                int64_t ref_best_rd, BLOCK_SIZE bsize,
2239
4.86M
                                const int ref_set) {
2240
  // If the number of ref mv count is equal to 1, do not prune the same. It
2241
  // is better to evaluate the same than to prune it.
2242
4.86M
  if (ref_set == 1) return 1;
2243
568k
  AV1_COMMON *const cm = &cpi->common;
2244
568k
  const MACROBLOCKD *const xd = &x->e_mbd;
2245
568k
  const MB_MODE_INFO *const mbmi = xd->mi[0];
2246
568k
  const PREDICTION_MODE this_mode = mbmi->mode;
2247
2248
  // Only search indices if they have some chance of being good.
2249
568k
  int good_indices = 0;
2250
1.90M
  for (int i = 0; i < ref_set; ++i) {
2251
1.34M
    if (ref_mv_idx_early_breakout(&cpi->sf, &cpi->ref_frame_dist_info, x, args,
2252
1.34M
                                  ref_best_rd, i)) {
2253
182k
      continue;
2254
182k
    }
2255
1.15M
    mask_set_bit(&good_indices, i);
2256
1.15M
  }
2257
2258
  // Only prune in NEARMV mode, if the speed feature is set, and the block size
2259
  // is large enough. If these conditions are not met, return all good indices
2260
  // found so far.
2261
568k
  if (!cpi->sf.inter_sf.prune_mode_search_simple_translation)
2262
0
    return good_indices;
2263
568k
  if (!have_nearmv_in_inter_mode(this_mode)) return good_indices;
2264
99.0k
  if (num_pels_log2_lookup[bsize] <= 6) return good_indices;
2265
  // Do not prune when there is internal resizing. TODO(elliottk) fix this
2266
  // so b/2384 can be resolved.
2267
1.76k
  if (av1_is_scaled(get_ref_scale_factors(cm, mbmi->ref_frame[0])) ||
2268
3.29k
      (mbmi->ref_frame[1] > 0 &&
2269
306
       av1_is_scaled(get_ref_scale_factors(cm, mbmi->ref_frame[1])))) {
2270
0
    return good_indices;
2271
0
  }
2272
2273
  // Calculate the RD cost for the motion vectors using simple translation.
2274
1.76k
  int64_t idx_rdcost[] = { INT64_MAX, INT64_MAX, INT64_MAX };
2275
9.73k
  for (int ref_mv_idx = 0; ref_mv_idx < ref_set; ++ref_mv_idx) {
2276
    // If this index is bad, ignore it.
2277
7.97k
    if (!mask_check_bit(good_indices, ref_mv_idx)) {
2278
67
      continue;
2279
67
    }
2280
7.90k
    idx_rdcost[ref_mv_idx] = simple_translation_pred_rd(
2281
7.90k
        cpi, x, args, ref_mv_idx, ref_best_rd, bsize);
2282
7.90k
  }
2283
  // Find the index with the best RD cost.
2284
1.76k
  int best_idx = 0;
2285
8.34k
  for (int i = 1; i < MAX_REF_MV_SEARCH; ++i) {
2286
6.58k
    if (idx_rdcost[i] < idx_rdcost[best_idx]) {
2287
1.71k
      best_idx = i;
2288
1.71k
    }
2289
6.58k
  }
2290
  // Only include indices that are good and within a % of the best.
2291
1.76k
  const double dth = has_second_ref(mbmi) ? 1.05 : 1.001;
2292
  // If the simple translation cost is not within this multiple of the
2293
  // best RD, skip it. Note that the cutoff is derived experimentally.
2294
1.76k
  const double ref_dth = 5;
2295
1.76k
  int result = 0;
2296
9.73k
  for (int i = 0; i < ref_set; ++i) {
2297
7.97k
    if (mask_check_bit(good_indices, i) &&
2298
7.90k
        (1.0 * idx_rdcost[i]) / idx_rdcost[best_idx] < dth &&
2299
3.95k
        (1.0 * idx_rdcost[i]) / ref_best_rd < ref_dth) {
2300
3.72k
      mask_set_bit(&result, i);
2301
3.72k
    }
2302
7.97k
  }
2303
1.76k
  return result;
2304
1.76k
}
2305
2306
/*!\brief Motion mode information for inter mode search speedup.
2307
 *
2308
 * Used in a speed feature to search motion modes other than
2309
 * SIMPLE_TRANSLATION only on winning candidates.
2310
 */
2311
typedef struct motion_mode_candidate {
2312
  /*!
2313
   * Mode info for the motion mode candidate.
2314
   */
2315
  MB_MODE_INFO mbmi;
2316
  /*!
2317
   * Rate describing the cost of the motion vectors for this candidate.
2318
   */
2319
  int rate_mv;
2320
  /*!
2321
   * Rate before motion mode search and transform coding is applied.
2322
   */
2323
  int rate2_nocoeff;
2324
  /*!
2325
   * An integer value 0 or 1 which indicates whether or not to skip the motion
2326
   * mode search and default to SIMPLE_TRANSLATION as a speed feature for this
2327
   * candidate.
2328
   */
2329
  int skip_motion_mode;
2330
  /*!
2331
   * Total RD cost for this candidate.
2332
   */
2333
  int64_t rd_cost;
2334
} motion_mode_candidate;
2335
2336
/*!\cond */
2337
typedef struct motion_mode_best_st_candidate {
2338
  motion_mode_candidate motion_mode_cand[MAX_WINNER_MOTION_MODES];
2339
  int num_motion_mode_cand;
2340
} motion_mode_best_st_candidate;
2341
2342
// Checks if the current reference frame matches with neighbouring block's
2343
// (top/left) reference frames
2344
static inline int ref_match_found_in_nb_blocks(MB_MODE_INFO *cur_mbmi,
2345
1.45M
                                               MB_MODE_INFO *nb_mbmi) {
2346
1.45M
  MV_REFERENCE_FRAME nb_ref_frames[2] = { nb_mbmi->ref_frame[0],
2347
1.45M
                                          nb_mbmi->ref_frame[1] };
2348
1.45M
  MV_REFERENCE_FRAME cur_ref_frames[2] = { cur_mbmi->ref_frame[0],
2349
1.45M
                                           cur_mbmi->ref_frame[1] };
2350
1.45M
  const int is_cur_comp_pred = has_second_ref(cur_mbmi);
2351
1.45M
  int match_found = 0;
2352
2353
3.18M
  for (int i = 0; i < (is_cur_comp_pred + 1); i++) {
2354
1.72M
    if ((cur_ref_frames[i] == nb_ref_frames[0]) ||
2355
629k
        (cur_ref_frames[i] == nb_ref_frames[1]))
2356
1.34M
      match_found = 1;
2357
1.72M
  }
2358
1.45M
  return match_found;
2359
1.45M
}
2360
2361
static inline int find_ref_match_in_above_nbs(const int total_mi_cols,
2362
2.48M
                                              MACROBLOCKD *xd) {
2363
2.48M
  if (!xd->up_available) return 1;
2364
1.86M
  const int mi_col = xd->mi_col;
2365
1.86M
  MB_MODE_INFO **cur_mbmi = xd->mi;
2366
  // prev_row_mi points into the mi array, starting at the beginning of the
2367
  // previous row.
2368
1.86M
  MB_MODE_INFO **prev_row_mi = xd->mi - mi_col - 1 * xd->mi_stride;
2369
1.86M
  const int end_col = AOMMIN(mi_col + xd->width, total_mi_cols);
2370
1.86M
  uint8_t mi_step;
2371
3.12M
  for (int above_mi_col = mi_col; above_mi_col < end_col;
2372
1.88M
       above_mi_col += mi_step) {
2373
1.88M
    MB_MODE_INFO **above_mi = prev_row_mi + above_mi_col;
2374
1.88M
    mi_step = mi_size_wide[above_mi[0]->bsize];
2375
1.88M
    int match_found = 0;
2376
1.88M
    if (is_inter_block(*above_mi))
2377
749k
      match_found = ref_match_found_in_nb_blocks(*cur_mbmi, *above_mi);
2378
1.88M
    if (match_found) return 1;
2379
1.88M
  }
2380
1.24M
  return 0;
2381
1.86M
}
2382
2383
static inline int find_ref_match_in_left_nbs(const int total_mi_rows,
2384
2.48M
                                             MACROBLOCKD *xd) {
2385
2.48M
  if (!xd->left_available) return 1;
2386
1.84M
  const int mi_row = xd->mi_row;
2387
1.84M
  MB_MODE_INFO **cur_mbmi = xd->mi;
2388
  // prev_col_mi points into the mi array, starting at the top of the
2389
  // previous column
2390
1.84M
  MB_MODE_INFO **prev_col_mi = xd->mi - 1 - mi_row * xd->mi_stride;
2391
1.84M
  const int end_row = AOMMIN(mi_row + xd->height, total_mi_rows);
2392
1.84M
  uint8_t mi_step;
2393
3.10M
  for (int left_mi_row = mi_row; left_mi_row < end_row;
2394
1.85M
       left_mi_row += mi_step) {
2395
1.85M
    MB_MODE_INFO **left_mi = prev_col_mi + left_mi_row * xd->mi_stride;
2396
1.85M
    mi_step = mi_size_high[left_mi[0]->bsize];
2397
1.85M
    int match_found = 0;
2398
1.85M
    if (is_inter_block(*left_mi))
2399
709k
      match_found = ref_match_found_in_nb_blocks(*cur_mbmi, *left_mi);
2400
1.85M
    if (match_found) return 1;
2401
1.85M
  }
2402
1.24M
  return 0;
2403
1.84M
}
2404
/*!\endcond */
2405
2406
/*! \brief Struct used to hold TPL data to
2407
 * narrow down parts of the inter mode search.
2408
 */
2409
typedef struct {
2410
  /*!
2411
   * The best inter cost out of all of the reference frames.
2412
   */
2413
  int64_t best_inter_cost;
2414
  /*!
2415
   * The inter cost for each reference frame.
2416
   */
2417
  int64_t ref_inter_cost[INTER_REFS_PER_FRAME];
2418
} PruneInfoFromTpl;
2419
2420
#if !CONFIG_REALTIME_ONLY
2421
// TODO(Remya): Check if get_tpl_stats_b() can be reused
2422
static inline void get_block_level_tpl_stats(
2423
    AV1_COMP *cpi, BLOCK_SIZE bsize, int mi_row, int mi_col, int *valid_refs,
2424
903k
    PruneInfoFromTpl *inter_cost_info_from_tpl) {
2425
903k
  AV1_COMMON *const cm = &cpi->common;
2426
2427
903k
  assert(IMPLIES(cpi->ppi->gf_group.size > 0,
2428
903k
                 cpi->gf_frame_index < cpi->ppi->gf_group.size));
2429
903k
  const int tpl_idx = cpi->gf_frame_index;
2430
903k
  TplParams *const tpl_data = &cpi->ppi->tpl_data;
2431
903k
  if (!av1_tpl_stats_ready(tpl_data, tpl_idx)) return;
2432
392k
  const TplDepFrame *tpl_frame = &tpl_data->tpl_frame[tpl_idx];
2433
392k
  const TplDepStats *tpl_stats = tpl_frame->tpl_stats_ptr;
2434
392k
  const int mi_wide = mi_size_wide[bsize];
2435
392k
  const int mi_high = mi_size_high[bsize];
2436
392k
  const int tpl_stride = tpl_frame->stride;
2437
392k
  const int step = 1 << tpl_data->tpl_stats_block_mis_log2;
2438
392k
  const int mi_col_sr =
2439
392k
      coded_to_superres_mi(mi_col, cm->superres_scale_denominator);
2440
392k
  const int mi_col_end_sr =
2441
392k
      coded_to_superres_mi(mi_col + mi_wide, cm->superres_scale_denominator);
2442
392k
  const int mi_cols_sr = av1_pixels_to_mi(cm->superres_upscaled_width);
2443
2444
392k
  const int row_step = step;
2445
392k
  const int col_step_sr =
2446
392k
      coded_to_superres_mi(step, cm->superres_scale_denominator);
2447
791k
  for (int row = mi_row; row < AOMMIN(mi_row + mi_high, cm->mi_params.mi_rows);
2448
399k
       row += row_step) {
2449
818k
    for (int col = mi_col_sr; col < AOMMIN(mi_col_end_sr, mi_cols_sr);
2450
419k
         col += col_step_sr) {
2451
419k
      const TplDepStats *this_stats = &tpl_stats[av1_tpl_ptr_pos(
2452
419k
          row, col, tpl_stride, tpl_data->tpl_stats_block_mis_log2)];
2453
2454
      // Sums up the inter cost of corresponding ref frames
2455
3.35M
      for (int ref_idx = 0; ref_idx < INTER_REFS_PER_FRAME; ref_idx++) {
2456
2.93M
        inter_cost_info_from_tpl->ref_inter_cost[ref_idx] +=
2457
2.93M
            this_stats->pred_error[ref_idx];
2458
2.93M
      }
2459
419k
    }
2460
399k
  }
2461
2462
  // Computes the best inter cost (minimum inter_cost)
2463
392k
  int64_t best_inter_cost = INT64_MAX;
2464
3.13M
  for (int ref_idx = 0; ref_idx < INTER_REFS_PER_FRAME; ref_idx++) {
2465
2.73M
    const int64_t cur_inter_cost =
2466
2.73M
        inter_cost_info_from_tpl->ref_inter_cost[ref_idx];
2467
    // For invalid ref frames, cur_inter_cost = 0 and has to be handled while
2468
    // calculating the minimum inter_cost
2469
2.73M
    if (cur_inter_cost != 0 && (cur_inter_cost < best_inter_cost) &&
2470
487k
        valid_refs[ref_idx])
2471
486k
      best_inter_cost = cur_inter_cost;
2472
2.73M
  }
2473
392k
  inter_cost_info_from_tpl->best_inter_cost = best_inter_cost;
2474
392k
}
2475
#endif
2476
2477
static inline int prune_modes_based_on_tpl_stats(
2478
    PruneInfoFromTpl *inter_cost_info_from_tpl, const int *refs, int ref_mv_idx,
2479
772k
    const PREDICTION_MODE this_mode, int prune_mode_level) {
2480
772k
  const int is_ref_last2 = refs[0] == LAST2_FRAME || refs[1] == LAST2_FRAME;
2481
772k
  if (prune_mode_level == 1 && !is_ref_last2) return 0;
2482
2483
732k
  const int have_newmv = have_newmv_in_inter_mode(this_mode);
2484
732k
  if ((prune_mode_level == 2) && have_newmv) return 0;
2485
2486
732k
  const int64_t best_inter_cost = inter_cost_info_from_tpl->best_inter_cost;
2487
732k
  if (best_inter_cost == INT64_MAX) return 0;
2488
2489
732k
  int64_t cur_inter_cost;
2490
2491
732k
  const int is_comp_pred = (refs[1] > INTRA_FRAME);
2492
732k
  if (!is_comp_pred) {
2493
578k
    cur_inter_cost = inter_cost_info_from_tpl->ref_inter_cost[refs[0] - 1];
2494
578k
  } else {
2495
154k
    const int64_t inter_cost_ref0 =
2496
154k
        inter_cost_info_from_tpl->ref_inter_cost[refs[0] - 1];
2497
154k
    const int64_t inter_cost_ref1 =
2498
154k
        inter_cost_info_from_tpl->ref_inter_cost[refs[1] - 1];
2499
    // Choose maximum inter_cost among inter_cost_ref0 and inter_cost_ref1 for
2500
    // more aggressive pruning
2501
154k
    cur_inter_cost = AOMMAX(inter_cost_ref0, inter_cost_ref1);
2502
154k
  }
2503
2504
732k
  if (is_ref_last2) return (cur_inter_cost > best_inter_cost);
2505
2506
732k
  const int is_globalmv =
2507
732k
      (this_mode == GLOBALMV) || (this_mode == GLOBAL_GLOBALMV);
2508
732k
  const int prune_index = is_globalmv ? MAX_REF_MV_SEARCH : ref_mv_idx;
2509
732k
  const int prune_level = prune_mode_level - 2;
2510
2511
  // Thresholds used for pruning:
2512
  // Lower value indicates aggressive pruning and higher value indicates
2513
  // conservative pruning which is set based on ref_mv_idx and speed feature.
2514
  // 'prune_index' 0, 1, 2 corresponds to ref_mv indices 0, 1 and 2.
2515
  // prune_index 3 corresponds to GLOBALMV/GLOBAL_GLOBALMV
2516
732k
  static const int tpl_inter_mode_prune_mul_factor[3][MAX_REF_MV_SEARCH + 1] = {
2517
732k
    { 6, 6, 6, 4 }, { 6, 4, 4, 4 }, { 5, 4, 4, 4 }
2518
732k
  };
2519
2520
  // Prune the mode if cur_inter_cost is greater than threshold times
2521
  // best_inter_cost
2522
732k
  if (cur_inter_cost >
2523
732k
      ((tpl_inter_mode_prune_mul_factor[prune_level][prune_index] *
2524
732k
        best_inter_cost) >>
2525
732k
       2))
2526
144k
    return 1;
2527
588k
  return 0;
2528
732k
}
2529
2530
/*!\brief High level function to select parameters for compound mode.
2531
 *
2532
 * \ingroup inter_mode_search
2533
 * The main search functionality is done in the call to av1_compound_type_rd().
2534
 *
2535
 * \param[in]     cpi               Top-level encoder structure.
2536
 * \param[in]     x                 Pointer to struct holding all the data for
2537
 *                                  the current macroblock.
2538
 * \param[in]     args              HandleInterModeArgs struct holding
2539
 *                                  miscellaneous arguments for inter mode
2540
 *                                  search. See the documentation for this
2541
 *                                  struct for a description of each member.
2542
 * \param[in]     ref_best_rd       Best RD found so far for this block.
2543
 *                                  It is used for early termination of this
2544
 *                                  search if the RD exceeds this value.
2545
 * \param[in,out] cur_mv            Current motion vector.
2546
 * \param[in]     bsize             Current block size.
2547
 * \param[in,out] compmode_interinter_cost  RD of the selected interinter
2548
                                    compound mode.
2549
 * \param[in,out] rd_buffers        CompoundTypeRdBuffers struct to hold all
2550
 *                                  allocated buffers for the compound
2551
 *                                  predictors and masks in the compound type
2552
 *                                  search.
2553
 * \param[in,out] orig_dst          A prediction buffer to hold a computed
2554
 *                                  prediction. This will eventually hold the
2555
 *                                  final prediction, and the tmp_dst info will
2556
 *                                  be copied here.
2557
 * \param[in]     tmp_dst           A temporary prediction buffer to hold a
2558
 *                                  computed prediction.
2559
 * \param[in,out] rate_mv           The rate associated with the motion vectors.
2560
 *                                  This will be modified if a motion search is
2561
 *                                  done in the motion mode search.
2562
 * \param[in,out] rd_stats          Struct to keep track of the overall RD
2563
 *                                  information.
2564
 * \param[in,out] skip_rd           An array of length 2 where skip_rd[0] is the
2565
 *                                  best total RD for a skip mode so far, and
2566
 *                                  skip_rd[1] is the best RD for a skip mode so
2567
 *                                  far in luma. This is used as a speed feature
2568
 *                                  to skip the transform search if the computed
2569
 *                                  skip RD for the current mode is not better
2570
 *                                  than the best skip_rd so far.
2571
 * \param[out] skip_build_pred      Indicates whether or not to build the inter
2572
 *                                  predictor during/after interpolation
2573
 *                                  filter search.
2574
 * \return Returns 1 if this mode is worse than one already seen and 0 if it is
2575
 * a viable candidate.
2576
 */
2577
static int process_compound_inter_mode(
2578
    AV1_COMP *const cpi, MACROBLOCK *x, HandleInterModeArgs *args,
2579
    int64_t ref_best_rd, int_mv *cur_mv, BLOCK_SIZE bsize,
2580
    int *compmode_interinter_cost, const CompoundTypeRdBuffers *rd_buffers,
2581
    const BUFFER_SET *orig_dst, const BUFFER_SET *tmp_dst, int *rate_mv,
2582
367k
    RD_STATS *rd_stats, int64_t *skip_rd, int *skip_build_pred) {
2583
367k
  MACROBLOCKD *xd = &x->e_mbd;
2584
367k
  MB_MODE_INFO *mbmi = xd->mi[0];
2585
367k
  const AV1_COMMON *cm = &cpi->common;
2586
367k
  const int masked_compound_used = is_any_masked_compound_used(bsize) &&
2587
367k
                                   cm->seq_params->enable_masked_compound;
2588
367k
  int mode_search_mask = (1 << COMPOUND_AVERAGE) | (1 << COMPOUND_DISTWTD) |
2589
367k
                         (1 << COMPOUND_WEDGE) | (1 << COMPOUND_DIFFWTD);
2590
2591
367k
  const int num_planes = av1_num_planes(cm);
2592
367k
  const int mi_row = xd->mi_row;
2593
367k
  const int mi_col = xd->mi_col;
2594
367k
  int is_luma_interp_done = 0;
2595
367k
  set_default_interp_filters(mbmi, cm->features.interp_filter);
2596
2597
367k
  int64_t best_rd_compound;
2598
367k
  int64_t rd_thresh;
2599
367k
  const int comp_type_rd_shift = COMP_TYPE_RD_THRESH_SHIFT;
2600
367k
  const int comp_type_rd_scale = COMP_TYPE_RD_THRESH_SCALE;
2601
367k
  rd_thresh = get_rd_thresh_from_best_rd(ref_best_rd, (1 << comp_type_rd_shift),
2602
367k
                                         comp_type_rd_scale);
2603
  // Select compound type and any parameters related to that type
2604
  // (for example, the mask parameters if it is a masked mode) and compute
2605
  // the RD
2606
367k
  *compmode_interinter_cost = av1_compound_type_rd(
2607
367k
      cpi, x, args, bsize, cur_mv, mode_search_mask, masked_compound_used,
2608
367k
      orig_dst, tmp_dst, rd_buffers, rate_mv, &best_rd_compound, rd_stats,
2609
367k
      ref_best_rd, skip_rd[1], &is_luma_interp_done, rd_thresh);
2610
367k
  if (ref_best_rd < INT64_MAX &&
2611
367k
      (best_rd_compound >> comp_type_rd_shift) * comp_type_rd_scale >
2612
367k
          ref_best_rd) {
2613
169k
    restore_dst_buf(xd, *orig_dst, num_planes);
2614
169k
    return 1;
2615
169k
  }
2616
2617
  // Build only uv predictor for COMPOUND_AVERAGE.
2618
  // Note there is no need to call av1_enc_build_inter_predictor
2619
  // for luma if COMPOUND_AVERAGE is selected because it is the first
2620
  // candidate in av1_compound_type_rd, which means it used the dst_buf
2621
  // rather than the tmp_buf.
2622
197k
  if (mbmi->interinter_comp.type == COMPOUND_AVERAGE && is_luma_interp_done) {
2623
152k
    if (num_planes > 1) {
2624
103k
      av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
2625
103k
                                    AOM_PLANE_U, num_planes - 1);
2626
103k
    }
2627
152k
    *skip_build_pred = INTERP_SKIP_LUMA_SKIP_CHROMA;
2628
152k
  }
2629
197k
  return 0;
2630
367k
}
2631
2632
// Speed feature to prune out MVs that are similar to previous MVs if they
2633
// don't achieve the best RD advantage.
2634
static int prune_ref_mv_idx_search(int ref_mv_idx, int best_ref_mv_idx,
2635
                                   int_mv save_mv[MAX_REF_MV_SEARCH - 1][2],
2636
443k
                                   MB_MODE_INFO *mbmi, int pruning_factor) {
2637
443k
  int i;
2638
443k
  const int is_comp_pred = has_second_ref(mbmi);
2639
443k
  const int thr = (1 + is_comp_pred) << (pruning_factor + 1);
2640
2641
  // Skip the evaluation if an MV match is found.
2642
443k
  if (ref_mv_idx > 0) {
2643
46.0k
    for (int idx = 0; idx < ref_mv_idx; ++idx) {
2644
25.6k
      if (save_mv[idx][0].as_int == INVALID_MV) continue;
2645
2646
24.7k
      int mv_diff = 0;
2647
74.3k
      for (i = 0; i < 1 + is_comp_pred; ++i) {
2648
49.5k
        mv_diff += abs(save_mv[idx][i].as_mv.row - mbmi->mv[i].as_mv.row) +
2649
49.5k
                   abs(save_mv[idx][i].as_mv.col - mbmi->mv[i].as_mv.col);
2650
49.5k
      }
2651
2652
      // If this mode is not the best one, and current MV is similar to
2653
      // previous stored MV, terminate this ref_mv_idx evaluation.
2654
24.7k
      if (best_ref_mv_idx == -1 && mv_diff <= thr) return 1;
2655
24.7k
    }
2656
21.3k
  }
2657
2658
442k
  if (ref_mv_idx < MAX_REF_MV_SEARCH - 1) {
2659
1.31M
    for (i = 0; i < is_comp_pred + 1; ++i)
2660
876k
      save_mv[ref_mv_idx][i].as_int = mbmi->mv[i].as_int;
2661
438k
  }
2662
2663
442k
  return 0;
2664
443k
}
2665
2666
/*!\brief Prunes ZeroMV Search Using Best NEWMV's SSE
2667
 *
2668
 * \ingroup inter_mode_search
2669
 *
2670
 * Compares the sse of zero mv and the best sse found in single new_mv. If the
2671
 * sse of the zero_mv is higher, returns 1 to signal zero_mv can be skipped.
2672
 * Else returns 0.
2673
 *
2674
 * Note that the sse of here comes from single_motion_search. So it is
2675
 * interpolated with the filter in motion search, not the actual interpolation
2676
 * filter used in encoding.
2677
 *
2678
 * \param[in]     fn_ptr            A table of function pointers to compute SSE.
2679
 * \param[in]     x                 Pointer to struct holding all the data for
2680
 *                                  the current macroblock.
2681
 * \param[in]     bsize             The current block_size.
2682
 * \param[in]     args              The args to handle_inter_mode, used to track
2683
 *                                  the best SSE.
2684
 * \param[in]    prune_zero_mv_with_sse  The argument holds speed feature
2685
 *                                       prune_zero_mv_with_sse value
2686
 * \return Returns 1 if zero_mv is pruned, 0 otherwise.
2687
 */
2688
static inline int prune_zero_mv_with_sse(const aom_variance_fn_ptr_t *fn_ptr,
2689
                                         const MACROBLOCK *x, BLOCK_SIZE bsize,
2690
                                         const HandleInterModeArgs *args,
2691
1.23M
                                         int prune_zero_mv_with_sse) {
2692
1.23M
  const MACROBLOCKD *xd = &x->e_mbd;
2693
1.23M
  const MB_MODE_INFO *mbmi = xd->mi[0];
2694
2695
1.23M
  const int is_comp_pred = has_second_ref(mbmi);
2696
1.23M
  const MV_REFERENCE_FRAME *refs = mbmi->ref_frame;
2697
2698
2.55M
  for (int idx = 0; idx < 1 + is_comp_pred; idx++) {
2699
1.32M
    if (xd->global_motion[refs[idx]].wmtype != IDENTITY) {
2700
      // Pruning logic only works for IDENTITY type models
2701
      // Note: In theory we could apply similar logic for TRANSLATION
2702
      // type models, but we do not code these due to a spec bug
2703
      // (see comments in gm_get_motion_vector() in av1/common/mv.h)
2704
0
      assert(xd->global_motion[refs[idx]].wmtype != TRANSLATION);
2705
0
      return 0;
2706
0
    }
2707
2708
    // Don't prune if we have invalid data
2709
1.32M
    assert(mbmi->mv[idx].as_int == 0);
2710
1.32M
    if (args->best_single_sse_in_refs[refs[idx]] == INT32_MAX) {
2711
364
      return 0;
2712
364
    }
2713
1.32M
  }
2714
2715
  // Sum up the sse of ZEROMV and best NEWMV
2716
1.23M
  unsigned int this_sse_sum = 0;
2717
1.23M
  unsigned int best_sse_sum = 0;
2718
2.55M
  for (int idx = 0; idx < 1 + is_comp_pred; idx++) {
2719
1.32M
    const struct macroblock_plane *const p = &x->plane[AOM_PLANE_Y];
2720
1.32M
    const struct macroblockd_plane *pd = xd->plane;
2721
1.32M
    const struct buf_2d *src_buf = &p->src;
2722
1.32M
    const struct buf_2d *ref_buf = &pd->pre[idx];
2723
1.32M
    const uint8_t *src = src_buf->buf;
2724
1.32M
    const uint8_t *ref = ref_buf->buf;
2725
1.32M
    const int src_stride = src_buf->stride;
2726
1.32M
    const int ref_stride = ref_buf->stride;
2727
2728
1.32M
    unsigned int this_sse;
2729
1.32M
    fn_ptr[bsize].vf(ref, ref_stride, src, src_stride, &this_sse);
2730
1.32M
    this_sse_sum += this_sse;
2731
2732
1.32M
    const unsigned int best_sse = args->best_single_sse_in_refs[refs[idx]];
2733
1.32M
    best_sse_sum += best_sse;
2734
1.32M
  }
2735
2736
1.23M
  const double mul = prune_zero_mv_with_sse > 1 ? 1.00 : 1.25;
2737
1.23M
  if ((double)this_sse_sum > (mul * (double)best_sse_sum)) {
2738
1.11M
    return 1;
2739
1.11M
  }
2740
2741
126k
  return 0;
2742
1.23M
}
2743
2744
/*!\brief Searches for interpolation filter in realtime mode during winner eval
2745
 *
2746
 * \ingroup inter_mode_search
2747
 *
2748
 * Does a simple interpolation filter search during winner mode evaluation. This
2749
 * is currently only used by realtime mode as \ref
2750
 * av1_interpolation_filter_search is not called during realtime encoding.
2751
 *
2752
 * This function only searches over two possible filters. EIGHTTAP_REGULAR is
2753
 * always search. For lowres clips (<= 240p), MULTITAP_SHARP is also search. For
2754
 * higher  res slips (>240p), EIGHTTAP_SMOOTH is also searched.
2755
 *  *
2756
 * \param[in]     cpi               Pointer to the compressor. Used for feature
2757
 *                                  flags.
2758
 * \param[in,out] x                 Pointer to macroblock. This is primarily
2759
 *                                  used to access the buffers.
2760
 * \param[in]     mi_row            The current row in mi unit (4X4 pixels).
2761
 * \param[in]     mi_col            The current col in mi unit (4X4 pixels).
2762
 * \param[in]     bsize             The current block_size.
2763
 * \return Returns true if a predictor is built in xd->dst, false otherwise.
2764
 */
2765
static inline bool fast_interp_search(const AV1_COMP *cpi, MACROBLOCK *x,
2766
                                      int mi_row, int mi_col,
2767
0
                                      BLOCK_SIZE bsize) {
2768
0
  static const InterpFilters filters_ref_set[3] = {
2769
0
    { EIGHTTAP_REGULAR, EIGHTTAP_REGULAR },
2770
0
    { EIGHTTAP_SMOOTH, EIGHTTAP_SMOOTH },
2771
0
    { MULTITAP_SHARP, MULTITAP_SHARP }
2772
0
  };
2773
2774
0
  const AV1_COMMON *const cm = &cpi->common;
2775
0
  MACROBLOCKD *const xd = &x->e_mbd;
2776
0
  MB_MODE_INFO *const mi = xd->mi[0];
2777
0
  int64_t best_cost = INT64_MAX;
2778
0
  int best_filter_index = -1;
2779
  // dst_bufs[0] sores the new predictor, and dist_bifs[1] stores the best
2780
0
  const int num_planes = av1_num_planes(cm);
2781
0
  const int is_240p_or_lesser = AOMMIN(cm->width, cm->height) <= 240;
2782
0
  assert(is_inter_mode(mi->mode));
2783
0
  assert(mi->motion_mode == SIMPLE_TRANSLATION);
2784
0
  assert(!is_inter_compound_mode(mi->mode));
2785
2786
0
  if (!av1_is_interp_needed(xd)) {
2787
0
    return false;
2788
0
  }
2789
2790
0
  struct macroblockd_plane *pd = xd->plane;
2791
0
  const BUFFER_SET orig_dst = {
2792
0
    { pd[0].dst.buf, pd[1].dst.buf, pd[2].dst.buf },
2793
0
    { pd[0].dst.stride, pd[1].dst.stride, pd[2].dst.stride },
2794
0
  };
2795
0
  uint8_t *const tmp_buf = get_buf_by_bd(xd, x->tmp_pred_bufs[0]);
2796
0
  const BUFFER_SET tmp_dst = { { tmp_buf, tmp_buf + 1 * MAX_SB_SQUARE,
2797
0
                                 tmp_buf + 2 * MAX_SB_SQUARE },
2798
0
                               { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE } };
2799
0
  const BUFFER_SET *dst_bufs[2] = { &orig_dst, &tmp_dst };
2800
2801
0
  for (int i = 0; i < 3; ++i) {
2802
0
    if (is_240p_or_lesser) {
2803
0
      if (filters_ref_set[i].x_filter == EIGHTTAP_SMOOTH) {
2804
0
        continue;
2805
0
      }
2806
0
    } else {
2807
0
      if (filters_ref_set[i].x_filter == MULTITAP_SHARP) {
2808
0
        continue;
2809
0
      }
2810
0
    }
2811
0
    int64_t cost;
2812
0
    RD_STATS tmp_rd = { 0 };
2813
2814
0
    mi->interp_filters.as_filters = filters_ref_set[i];
2815
0
    av1_enc_build_inter_predictor_y(xd, mi_row, mi_col);
2816
2817
0
    model_rd_sb_fn[cpi->sf.rt_sf.use_simple_rd_model
2818
0
                       ? MODELRD_LEGACY
2819
0
                       : MODELRD_TYPE_INTERP_FILTER](
2820
0
        cpi, bsize, x, xd, AOM_PLANE_Y, AOM_PLANE_Y, &tmp_rd.rate, &tmp_rd.dist,
2821
0
        &tmp_rd.skip_txfm, &tmp_rd.sse, NULL, NULL, NULL);
2822
2823
0
    tmp_rd.rate += av1_get_switchable_rate(x, xd, cm->features.interp_filter,
2824
0
                                           cm->seq_params->enable_dual_filter);
2825
0
    cost = RDCOST(x->rdmult, tmp_rd.rate, tmp_rd.dist);
2826
0
    if (cost < best_cost) {
2827
0
      best_filter_index = i;
2828
0
      best_cost = cost;
2829
0
      swap_dst_buf(xd, dst_bufs, num_planes);
2830
0
    }
2831
0
  }
2832
0
  assert(best_filter_index >= 0);
2833
2834
0
  mi->interp_filters.as_filters = filters_ref_set[best_filter_index];
2835
2836
0
  const bool is_best_pred_in_orig = &orig_dst == dst_bufs[1];
2837
2838
0
  if (is_best_pred_in_orig) {
2839
0
    swap_dst_buf(xd, dst_bufs, num_planes);
2840
0
  } else {
2841
    // Note that xd->pd's bufers are kept in sync with dst_bufs[0]. So if
2842
    // is_best_pred_in_orig is false, that means the current buffer is the
2843
    // original one.
2844
0
    assert(&orig_dst == dst_bufs[0]);
2845
0
    assert(xd->plane[AOM_PLANE_Y].dst.buf == orig_dst.plane[AOM_PLANE_Y]);
2846
0
    const int width = block_size_wide[bsize];
2847
0
    const int height = block_size_high[bsize];
2848
0
#if CONFIG_AV1_HIGHBITDEPTH
2849
0
    const bool is_hbd = is_cur_buf_hbd(xd);
2850
0
    if (is_hbd) {
2851
0
      aom_highbd_convolve_copy(CONVERT_TO_SHORTPTR(tmp_dst.plane[AOM_PLANE_Y]),
2852
0
                               tmp_dst.stride[AOM_PLANE_Y],
2853
0
                               CONVERT_TO_SHORTPTR(orig_dst.plane[AOM_PLANE_Y]),
2854
0
                               orig_dst.stride[AOM_PLANE_Y], width, height);
2855
0
    } else {
2856
0
      aom_convolve_copy(tmp_dst.plane[AOM_PLANE_Y], tmp_dst.stride[AOM_PLANE_Y],
2857
0
                        orig_dst.plane[AOM_PLANE_Y],
2858
0
                        orig_dst.stride[AOM_PLANE_Y], width, height);
2859
0
    }
2860
#else
2861
    aom_convolve_copy(tmp_dst.plane[AOM_PLANE_Y], tmp_dst.stride[AOM_PLANE_Y],
2862
                      orig_dst.plane[AOM_PLANE_Y], orig_dst.stride[AOM_PLANE_Y],
2863
                      width, height);
2864
#endif
2865
0
  }
2866
2867
  // Build the YUV predictor.
2868
0
  if (num_planes > 1) {
2869
0
    av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize,
2870
0
                                  AOM_PLANE_U, AOM_PLANE_V);
2871
0
  }
2872
2873
0
  return true;
2874
0
}
2875
2876
/*!\brief AV1 inter mode RD computation
2877
 *
2878
 * \ingroup inter_mode_search
2879
 * Do the RD search for a given inter mode and compute all information relevant
2880
 * to the input mode. It will compute the best MV,
2881
 * compound parameters (if the mode is a compound mode) and interpolation filter
2882
 * parameters.
2883
 *
2884
 * \param[in]     cpi               Top-level encoder structure.
2885
 * \param[in]     tile_data         Pointer to struct holding adaptive
2886
 *                                  data/contexts/models for the tile during
2887
 *                                  encoding.
2888
 * \param[in]     x                 Pointer to structure holding all the data
2889
 *                                  for the current macroblock.
2890
 * \param[in]     bsize             Current block size.
2891
 * \param[in,out] rd_stats          Struct to keep track of the overall RD
2892
 *                                  information.
2893
 * \param[out]    rd_stats_y        Struct to keep track of the RD information
2894
 *                                  for only the Y plane.
2895
 * \param[out]    rd_stats_uv       Struct to keep track of the RD information
2896
 *                                  for only the UV planes.
2897
 * \param[in]     args              HandleInterModeArgs struct holding
2898
 *                                  miscellaneous arguments for inter mode
2899
 *                                  search. See the documentation for this
2900
 *                                  struct for a description of each member.
2901
 * \param[in]     ref_best_rd       Best RD found so far for this block.
2902
 *                                  It is used for early termination of this
2903
 *                                  search if the RD exceeds this value.
2904
 * \param[in]     tmp_buf           Temporary buffer used to hold predictors
2905
 *                                  built in this search.
2906
 * \param[in,out] rd_buffers        CompoundTypeRdBuffers struct to hold all
2907
 *                                  allocated buffers for the compound
2908
 *                                  predictors and masks in the compound type
2909
 *                                  search.
2910
 * \param[in,out] best_est_rd       Estimated RD for motion mode search if
2911
 *                                  do_tx_search (see below) is 0.
2912
 * \param[in]     do_tx_search      Parameter to indicate whether or not to do
2913
 *                                  a full transform search. This will compute
2914
 *                                  an estimated RD for the modes without the
2915
 *                                  transform search and later perform the full
2916
 *                                  transform search on the best candidates.
2917
 * \param[in,out] inter_modes_info  InterModesInfo struct to hold inter mode
2918
 *                                  information to perform a full transform
2919
 *                                  search only on winning candidates searched
2920
 *                                  with an estimate for transform coding RD.
2921
 * \param[in,out] motion_mode_cand  A motion_mode_candidate struct to store
2922
 *                                  motion mode information used in a speed
2923
 *                                  feature to search motion modes other than
2924
 *                                  SIMPLE_TRANSLATION only on winning
2925
 *                                  candidates.
2926
 * \param[in,out] skip_rd           A length 2 array, where skip_rd[0] is the
2927
 *                                  best total RD for a skip mode so far, and
2928
 *                                  skip_rd[1] is the best RD for a skip mode so
2929
 *                                  far in luma. This is used as a speed feature
2930
 *                                  to skip the transform search if the computed
2931
 *                                  skip RD for the current mode is not better
2932
 *                                  than the best skip_rd so far.
2933
 * \param[in]     inter_cost_info_from_tpl A PruneInfoFromTpl struct used to
2934
 *                                         narrow down the search based on data
2935
 *                                         collected in the TPL model.
2936
 * \param[out]    yrd               Stores the rdcost corresponding to encoding
2937
 *                                  the luma plane.
2938
 *
2939
 * \return The RD cost for the mode being searched. If the return value is
2940
 *         INT64_MAX, the output parameters are not set; do not use them.
2941
 */
2942
static int64_t handle_inter_mode(
2943
    AV1_COMP *const cpi, TileDataEnc *tile_data, MACROBLOCK *x,
2944
    BLOCK_SIZE bsize, RD_STATS *rd_stats, RD_STATS *rd_stats_y,
2945
    RD_STATS *rd_stats_uv, HandleInterModeArgs *args, int64_t ref_best_rd,
2946
    uint8_t *const tmp_buf, const CompoundTypeRdBuffers *rd_buffers,
2947
    int64_t *best_est_rd, const int do_tx_search,
2948
    InterModesInfo *inter_modes_info, motion_mode_candidate *motion_mode_cand,
2949
    int64_t *skip_rd, PruneInfoFromTpl *inter_cost_info_from_tpl,
2950
4.86M
    int64_t *yrd) {
2951
4.86M
  const AV1_COMMON *cm = &cpi->common;
2952
4.86M
  const int num_planes = av1_num_planes(cm);
2953
4.86M
  MACROBLOCKD *xd = &x->e_mbd;
2954
4.86M
  MB_MODE_INFO *mbmi = xd->mi[0];
2955
4.86M
  MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
2956
4.86M
  TxfmSearchInfo *txfm_info = &x->txfm_search_info;
2957
4.86M
  const int is_comp_pred = has_second_ref(mbmi);
2958
4.86M
  const PREDICTION_MODE this_mode = mbmi->mode;
2959
2960
#if CONFIG_REALTIME_ONLY
2961
  const int prune_modes_based_on_tpl = 0;
2962
#else   // CONFIG_REALTIME_ONLY
2963
4.86M
  const TplParams *const tpl_data = &cpi->ppi->tpl_data;
2964
4.86M
  const int prune_modes_based_on_tpl =
2965
4.86M
      cpi->sf.inter_sf.prune_inter_modes_based_on_tpl &&
2966
4.85M
      av1_tpl_stats_ready(tpl_data, cpi->gf_frame_index);
2967
4.86M
#endif  // CONFIG_REALTIME_ONLY
2968
4.86M
  int i;
2969
  // Reference frames for this mode
2970
4.86M
  const int refs[2] = { mbmi->ref_frame[0],
2971
4.86M
                        (mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]) };
2972
4.86M
  int rate_mv = 0;
2973
4.86M
  int64_t rd = INT64_MAX;
2974
  // Do first prediction into the destination buffer. Do the next
2975
  // prediction into a temporary buffer. Then keep track of which one
2976
  // of these currently holds the best predictor, and use the other
2977
  // one for future predictions. In the end, copy from tmp_buf to
2978
  // dst if necessary.
2979
4.86M
  struct macroblockd_plane *pd = xd->plane;
2980
4.86M
  const BUFFER_SET orig_dst = {
2981
4.86M
    { pd[0].dst.buf, pd[1].dst.buf, pd[2].dst.buf },
2982
4.86M
    { pd[0].dst.stride, pd[1].dst.stride, pd[2].dst.stride },
2983
4.86M
  };
2984
4.86M
  const BUFFER_SET tmp_dst = { { tmp_buf, tmp_buf + 1 * MAX_SB_SQUARE,
2985
4.86M
                                 tmp_buf + 2 * MAX_SB_SQUARE },
2986
4.86M
                               { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE } };
2987
2988
4.86M
  int64_t ret_val = INT64_MAX;
2989
4.86M
  const int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
2990
4.86M
  RD_STATS best_rd_stats, best_rd_stats_y, best_rd_stats_uv;
2991
4.86M
  int64_t best_rd = INT64_MAX;
2992
4.86M
  uint8_t best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
2993
4.86M
  int64_t best_yrd = INT64_MAX;
2994
4.86M
  MB_MODE_INFO best_mbmi = *mbmi;
2995
4.86M
  int best_xskip_txfm = 0;
2996
4.86M
  int64_t newmv_ret_val = INT64_MAX;
2997
4.86M
  inter_mode_info mode_info[MAX_REF_MV_SEARCH];
2998
2999
  // Do not prune the mode based on inter cost from tpl if the current ref frame
3000
  // is the winner ref in neighbouring blocks.
3001
4.86M
  int ref_match_found_in_above_nb = 0;
3002
4.86M
  int ref_match_found_in_left_nb = 0;
3003
4.86M
  if (prune_modes_based_on_tpl) {
3004
2.48M
    ref_match_found_in_above_nb =
3005
2.48M
        find_ref_match_in_above_nbs(cm->mi_params.mi_cols, xd);
3006
2.48M
    ref_match_found_in_left_nb =
3007
2.48M
        find_ref_match_in_left_nbs(cm->mi_params.mi_rows, xd);
3008
2.48M
  }
3009
3010
  // First, perform a simple translation search for each of the indices. If
3011
  // an index performs well, it will be fully searched in the main loop
3012
  // of this function.
3013
4.86M
  const int ref_set = get_drl_refmv_count(x, mbmi->ref_frame, this_mode);
3014
  // Save MV results from first 2 ref_mv_idx.
3015
4.86M
  int_mv save_mv[MAX_REF_MV_SEARCH - 1][2];
3016
4.86M
  int best_ref_mv_idx = -1;
3017
4.86M
  const int idx_mask =
3018
4.86M
      ref_mv_idx_to_search(cpi, x, args, ref_best_rd, bsize, ref_set);
3019
4.86M
  const int16_t mode_ctx =
3020
4.86M
      av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame);
3021
4.86M
  const ModeCosts *mode_costs = &x->mode_costs;
3022
4.86M
  const int ref_mv_cost = cost_mv_ref(mode_costs, this_mode, mode_ctx);
3023
4.86M
  const int base_rate =
3024
4.86M
      args->ref_frame_cost + args->single_comp_cost + ref_mv_cost;
3025
3026
14.5M
  for (i = 0; i < MAX_REF_MV_SEARCH - 1; ++i) {
3027
9.72M
    save_mv[i][0].as_int = INVALID_MV;
3028
9.72M
    save_mv[i][1].as_int = INVALID_MV;
3029
9.72M
  }
3030
4.86M
  args->start_mv_cnt = 0;
3031
3032
  // Main loop of this function. This will  iterate over all of the ref mvs
3033
  // in the dynamic reference list and do the following:
3034
  //    1.) Get the current MV. Create newmv MV if necessary
3035
  //    2.) Search compound type and parameters if applicable
3036
  //    3.) Do interpolation filter search
3037
  //    4.) Build the inter predictor
3038
  //    5.) Pick the motion mode (SIMPLE_TRANSLATION, OBMC_CAUSAL,
3039
  //        WARPED_CAUSAL)
3040
  //    6.) Update stats if best so far
3041
10.4M
  for (int ref_mv_idx = 0; ref_mv_idx < ref_set; ++ref_mv_idx) {
3042
5.63M
    mbmi->ref_mv_idx = ref_mv_idx;
3043
3044
5.63M
    mode_info[ref_mv_idx].full_search_mv.as_int = INVALID_MV;
3045
5.63M
    mode_info[ref_mv_idx].full_mv_bestsme = INT_MAX;
3046
5.63M
    const int drl_cost = get_drl_cost(
3047
5.63M
        mbmi, mbmi_ext, mode_costs->drl_mode_cost0, ref_frame_type);
3048
5.63M
    mode_info[ref_mv_idx].drl_cost = drl_cost;
3049
5.63M
    mode_info[ref_mv_idx].skip = 0;
3050
3051
5.63M
    if (!mask_check_bit(idx_mask, ref_mv_idx)) {
3052
      // MV did not perform well in simple translation search. Skip it.
3053
187k
      continue;
3054
187k
    }
3055
5.44M
    if (prune_modes_based_on_tpl && !ref_match_found_in_above_nb &&
3056
1.31M
        !ref_match_found_in_left_nb && (ref_best_rd != INT64_MAX)) {
3057
      // Skip mode if TPL model indicates it will not be beneficial.
3058
772k
      if (prune_modes_based_on_tpl_stats(
3059
772k
              inter_cost_info_from_tpl, refs, ref_mv_idx, this_mode,
3060
772k
              cpi->sf.inter_sf.prune_inter_modes_based_on_tpl))
3061
144k
        continue;
3062
772k
    }
3063
5.30M
    av1_init_rd_stats(rd_stats);
3064
3065
    // Initialize compound mode data
3066
5.30M
    mbmi->interinter_comp.type = COMPOUND_AVERAGE;
3067
5.30M
    mbmi->comp_group_idx = 0;
3068
5.30M
    mbmi->compound_idx = 1;
3069
5.30M
    if (mbmi->ref_frame[1] == INTRA_FRAME) mbmi->ref_frame[1] = NONE_FRAME;
3070
3071
5.30M
    mbmi->num_proj_ref = 0;
3072
5.30M
    mbmi->motion_mode = SIMPLE_TRANSLATION;
3073
3074
    // Compute cost for signalling this DRL index
3075
5.30M
    rd_stats->rate = base_rate;
3076
5.30M
    rd_stats->rate += drl_cost;
3077
3078
5.30M
    int rs = 0;
3079
5.30M
    int compmode_interinter_cost = 0;
3080
3081
5.30M
    int_mv cur_mv[2];
3082
3083
    // TODO(Cherma): Extend this speed feature to support compound mode
3084
5.30M
    int skip_repeated_ref_mv =
3085
5.30M
        is_comp_pred ? 0 : cpi->sf.inter_sf.skip_repeated_ref_mv;
3086
    // Generate the current mv according to the prediction mode
3087
5.30M
    if (!build_cur_mv(cur_mv, this_mode, cm, x, skip_repeated_ref_mv)) {
3088
30.9k
      continue;
3089
30.9k
    }
3090
3091
    // The above call to build_cur_mv does not handle NEWMV modes. Build
3092
    // the mv here if we have NEWMV for any predictors.
3093
5.27M
    if (have_newmv_in_inter_mode(this_mode)) {
3094
#if CONFIG_COLLECT_COMPONENT_TIMING
3095
      start_timing(cpi, handle_newmv_time);
3096
#endif
3097
1.84M
      newmv_ret_val =
3098
1.84M
          handle_newmv(cpi, x, bsize, cur_mv, &rate_mv, args, mode_info);
3099
#if CONFIG_COLLECT_COMPONENT_TIMING
3100
      end_timing(cpi, handle_newmv_time);
3101
#endif
3102
3103
1.84M
      if (newmv_ret_val != 0) continue;
3104
3105
1.59M
      if (is_inter_singleref_mode(this_mode) &&
3106
1.44M
          cur_mv[0].as_int != INVALID_MV) {
3107
1.44M
        const MV_REFERENCE_FRAME ref = refs[0];
3108
1.44M
        const unsigned int this_sse = x->pred_sse[ref];
3109
1.44M
        if (this_sse < args->best_single_sse_in_refs[ref]) {
3110
1.36M
          args->best_single_sse_in_refs[ref] = this_sse;
3111
1.36M
        }
3112
3113
1.44M
        if (cpi->sf.rt_sf.skip_newmv_mode_based_on_sse) {
3114
0
          const int th_idx = cpi->sf.rt_sf.skip_newmv_mode_based_on_sse - 1;
3115
0
          const int pix_idx = num_pels_log2_lookup[bsize] - 4;
3116
0
          const double scale_factor[3][11] = {
3117
0
            { 0.7, 0.7, 0.7, 0.7, 0.7, 0.8, 0.8, 0.9, 0.9, 0.9, 0.9 },
3118
0
            { 0.7, 0.7, 0.7, 0.7, 0.8, 0.8, 1, 1, 1, 1, 1 },
3119
0
            { 0.7, 0.7, 0.7, 0.7, 1, 1, 1, 1, 1, 1, 1 }
3120
0
          };
3121
0
          assert(pix_idx >= 0);
3122
0
          assert(th_idx <= 2);
3123
0
          if (args->best_pred_sse < scale_factor[th_idx][pix_idx] * this_sse)
3124
0
            continue;
3125
0
        }
3126
1.44M
      }
3127
3128
1.59M
      rd_stats->rate += rate_mv;
3129
1.59M
    }
3130
    // Copy the motion vector for this mode into mbmi struct
3131
10.4M
    for (i = 0; i < is_comp_pred + 1; ++i) {
3132
5.47M
      mbmi->mv[i].as_int = cur_mv[i].as_int;
3133
5.47M
    }
3134
3135
5.02M
    if (RDCOST(x->rdmult, rd_stats->rate, 0) > ref_best_rd &&
3136
13.4k
        mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV) {
3137
12.6k
      continue;
3138
12.6k
    }
3139
3140
    // Skip the rest of the search if prune_ref_mv_idx_search speed feature
3141
    // is enabled, and the current MV is similar to a previous one.
3142
5.01M
    if (cpi->sf.inter_sf.prune_ref_mv_idx_search && is_comp_pred &&
3143
443k
        prune_ref_mv_idx_search(ref_mv_idx, best_ref_mv_idx, save_mv, mbmi,
3144
443k
                                cpi->sf.inter_sf.prune_ref_mv_idx_search))
3145
909
      continue;
3146
3147
5.00M
    if (cpi->sf.gm_sf.prune_zero_mv_with_sse &&
3148
5.01M
        (this_mode == GLOBALMV || this_mode == GLOBAL_GLOBALMV)) {
3149
1.23M
      if (prune_zero_mv_with_sse(cpi->ppi->fn_ptr, x, bsize, args,
3150
1.23M
                                 cpi->sf.gm_sf.prune_zero_mv_with_sse)) {
3151
1.11M
        continue;
3152
1.11M
      }
3153
1.23M
    }
3154
3155
    // Flag to indicate whether to skip av1_enc_build_inter_predictor() after
3156
    // interpolation filter search
3157
3.89M
    int skip_build_pred = INTERP_EVAL_LUMA_EVAL_CHROMA;
3158
3.89M
    const int mi_row = xd->mi_row;
3159
3.89M
    const int mi_col = xd->mi_col;
3160
3161
    // Handle a compound predictor, continue if it is determined this
3162
    // cannot be the best compound mode
3163
3.89M
    if (is_comp_pred) {
3164
#if CONFIG_COLLECT_COMPONENT_TIMING
3165
      start_timing(cpi, compound_type_rd_time);
3166
#endif
3167
367k
      const int not_best_mode = process_compound_inter_mode(
3168
367k
          cpi, x, args, ref_best_rd, cur_mv, bsize, &compmode_interinter_cost,
3169
367k
          rd_buffers, &orig_dst, &tmp_dst, &rate_mv, rd_stats, skip_rd,
3170
367k
          &skip_build_pred);
3171
#if CONFIG_COLLECT_COMPONENT_TIMING
3172
      end_timing(cpi, compound_type_rd_time);
3173
#endif
3174
367k
      if (not_best_mode) continue;
3175
367k
    }
3176
3177
3.72M
    if (!args->skip_ifs) {
3178
#if CONFIG_COLLECT_COMPONENT_TIMING
3179
      start_timing(cpi, interpolation_filter_search_time);
3180
#endif
3181
      // Determine the interpolation filter for this mode
3182
385k
      ret_val = av1_interpolation_filter_search(
3183
385k
          x, cpi, tile_data, bsize, &tmp_dst, &orig_dst, &rd, &rs,
3184
385k
          &skip_build_pred, args, ref_best_rd);
3185
#if CONFIG_COLLECT_COMPONENT_TIMING
3186
      end_timing(cpi, interpolation_filter_search_time);
3187
#endif
3188
385k
      if (args->modelled_rd != NULL && !is_comp_pred) {
3189
187k
        args->modelled_rd[this_mode][ref_mv_idx][refs[0]] = rd;
3190
187k
      }
3191
385k
      if (ret_val != 0) {
3192
0
        restore_dst_buf(xd, orig_dst, num_planes);
3193
0
        continue;
3194
385k
      } else if (cpi->sf.inter_sf.model_based_post_interp_filter_breakout &&
3195
385k
                 ref_best_rd != INT64_MAX && (rd >> 3) * 3 > ref_best_rd) {
3196
138
        restore_dst_buf(xd, orig_dst, num_planes);
3197
138
        continue;
3198
138
      }
3199
3200
      // Compute modelled RD if enabled
3201
385k
      if (args->modelled_rd != NULL) {
3202
385k
        if (is_comp_pred) {
3203
197k
          const int mode0 = compound_ref0_mode(this_mode);
3204
197k
          const int mode1 = compound_ref1_mode(this_mode);
3205
197k
          const int64_t mrd =
3206
197k
              AOMMIN(args->modelled_rd[mode0][ref_mv_idx][refs[0]],
3207
197k
                     args->modelled_rd[mode1][ref_mv_idx][refs[1]]);
3208
197k
          if ((rd >> 3) * 6 > mrd && ref_best_rd < INT64_MAX) {
3209
0
            restore_dst_buf(xd, orig_dst, num_planes);
3210
0
            continue;
3211
0
          }
3212
197k
        }
3213
385k
      }
3214
385k
    }
3215
3216
3.72M
    rd_stats->rate += compmode_interinter_cost;
3217
3.72M
    if (skip_build_pred != INTERP_SKIP_LUMA_SKIP_CHROMA) {
3218
      // Chroma plane of COMPOUND_DIFFWTD mode shares the segment mask of luma
3219
      // which is stored in xd->seg_mask. Hence, the predictor is populated for
3220
      // all planes. This should avoid usage of incorrect segment mask when the
3221
      // call is made only for chroma.
3222
3.60M
      const int skip_luma_plane =
3223
3.60M
          skip_build_pred == INTERP_SKIP_LUMA_EVAL_CHROMA &&
3224
212k
          mbmi->interinter_comp.type != COMPOUND_DIFFWTD;
3225
3.60M
      const int start_plane = skip_luma_plane ? AOM_PLANE_U : AOM_PLANE_Y;
3226
      // Build this inter predictor if it has not been previously built
3227
3.60M
      av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, &orig_dst, bsize,
3228
3.60M
                                    start_plane, num_planes - 1);
3229
3.60M
    }
3230
#if CONFIG_COLLECT_COMPONENT_TIMING
3231
    start_timing(cpi, motion_mode_rd_time);
3232
#endif
3233
3.72M
    int rate2_nocoeff = rd_stats->rate;
3234
    // Determine the motion mode. This will be one of SIMPLE_TRANSLATION,
3235
    // OBMC_CAUSAL or WARPED_CAUSAL
3236
3.72M
    int64_t this_yrd;
3237
3.72M
    ret_val = motion_mode_rd(cpi, tile_data, x, bsize, rd_stats, rd_stats_y,
3238
3.72M
                             rd_stats_uv, args, ref_best_rd, skip_rd, &rate_mv,
3239
3.72M
                             &orig_dst, best_est_rd, do_tx_search,
3240
3.72M
                             inter_modes_info, 0, &this_yrd);
3241
#if CONFIG_COLLECT_COMPONENT_TIMING
3242
    end_timing(cpi, motion_mode_rd_time);
3243
#endif
3244
3.72M
    assert(
3245
3.72M
        IMPLIES(!av1_check_newmv_joint_nonzero(cm, x), ret_val == INT64_MAX));
3246
3247
3.72M
    if (ret_val != INT64_MAX) {
3248
1.87M
      int64_t tmp_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
3249
1.87M
      const THR_MODES mode_enum = get_prediction_mode_idx(
3250
1.87M
          mbmi->mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3251
      // Collect mode stats for multiwinner mode processing
3252
1.87M
      store_winner_mode_stats(cpi, x, mbmi, rd_stats, rd_stats_y, rd_stats_uv,
3253
1.87M
                              mode_enum, NULL, bsize, tmp_rd,
3254
1.87M
                              cpi->sf.winner_mode_sf.multi_winner_mode_type,
3255
1.87M
                              do_tx_search);
3256
1.87M
      if (tmp_rd < best_rd) {
3257
1.87M
        best_yrd = this_yrd;
3258
        // Update the best rd stats if we found the best mode so far
3259
1.87M
        best_rd_stats = *rd_stats;
3260
1.87M
        best_rd_stats_y = *rd_stats_y;
3261
1.87M
        best_rd_stats_uv = *rd_stats_uv;
3262
1.87M
        best_rd = tmp_rd;
3263
1.87M
        best_mbmi = *mbmi;
3264
1.87M
        best_xskip_txfm = txfm_info->skip_txfm;
3265
1.87M
        av1_copy_array(best_tx_type_map, xd->tx_type_map,
3266
1.87M
                       xd->height * xd->width);
3267
1.87M
        motion_mode_cand->rate_mv = rate_mv;
3268
1.87M
        motion_mode_cand->rate2_nocoeff = rate2_nocoeff;
3269
1.87M
      }
3270
3271
1.87M
      if (tmp_rd < ref_best_rd) {
3272
1.82M
        ref_best_rd = tmp_rd;
3273
1.82M
        best_ref_mv_idx = ref_mv_idx;
3274
1.82M
      }
3275
1.87M
    }
3276
3.72M
    restore_dst_buf(xd, orig_dst, num_planes);
3277
3.72M
  }
3278
3279
4.86M
  if (best_rd == INT64_MAX) return INT64_MAX;
3280
3281
  // re-instate status of the best choice
3282
1.83M
  *rd_stats = best_rd_stats;
3283
1.83M
  *rd_stats_y = best_rd_stats_y;
3284
1.83M
  *rd_stats_uv = best_rd_stats_uv;
3285
1.83M
  *yrd = best_yrd;
3286
1.83M
  *mbmi = best_mbmi;
3287
1.83M
  txfm_info->skip_txfm = best_xskip_txfm;
3288
1.83M
  assert(IMPLIES(mbmi->comp_group_idx == 1,
3289
1.83M
                 mbmi->interinter_comp.type != COMPOUND_AVERAGE));
3290
1.83M
  av1_copy_array(xd->tx_type_map, best_tx_type_map, xd->height * xd->width);
3291
3292
1.83M
  rd_stats->rdcost = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
3293
3294
1.83M
  return rd_stats->rdcost;
3295
4.86M
}
3296
3297
/*!\brief Search for the best intrabc predictor
3298
 *
3299
 * \ingroup intra_mode_search
3300
 * \callergraph
3301
 * This function performs a motion search to find the best intrabc predictor.
3302
 *
3303
 * \returns Returns the best overall rdcost (including the non-intrabc modes
3304
 * search before this function).
3305
 */
3306
static int64_t rd_pick_intrabc_mode_sb(const AV1_COMP *cpi, MACROBLOCK *x,
3307
                                       PICK_MODE_CONTEXT *ctx,
3308
                                       RD_STATS *rd_stats, BLOCK_SIZE bsize,
3309
18.0M
                                       int64_t best_rd) {
3310
18.0M
  const AV1_COMMON *const cm = &cpi->common;
3311
18.0M
  if (!av1_allow_intrabc(cm) || !cpi->oxcf.kf_cfg.enable_intrabc ||
3312
1.92M
      !cpi->sf.mv_sf.use_intrabc ||
3313
1.92M
      (cpi->sf.rt_sf.use_nonrd_pick_mode && !cpi->sf.rt_sf.rt_use_intrabc))
3314
16.1M
    return INT64_MAX;
3315
1.85M
  if (cpi->sf.mv_sf.intrabc_search_level >= 1 && bsize != BLOCK_4X4 &&
3316
910k
      bsize != BLOCK_8X8 && bsize != BLOCK_16X16) {
3317
317k
    return INT64_MAX;
3318
317k
  }
3319
1.53M
  const int num_planes = av1_num_planes(cm);
3320
3321
1.53M
  MACROBLOCKD *const xd = &x->e_mbd;
3322
1.53M
  const TileInfo *tile = &xd->tile;
3323
1.53M
  MB_MODE_INFO *mbmi = xd->mi[0];
3324
3325
1.53M
  const int mi_row = xd->mi_row;
3326
1.53M
  const int mi_col = xd->mi_col;
3327
1.53M
  const int w = block_size_wide[bsize];
3328
1.53M
  const int h = block_size_high[bsize];
3329
1.53M
  const int sb_row = mi_row >> cm->seq_params->mib_size_log2;
3330
1.53M
  const int sb_col = mi_col >> cm->seq_params->mib_size_log2;
3331
3332
1.53M
  MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
3333
1.53M
  const MV_REFERENCE_FRAME ref_frame = INTRA_FRAME;
3334
1.53M
  av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
3335
1.53M
                   xd->ref_mv_stack, xd->weight, NULL, mbmi_ext->global_mvs,
3336
1.53M
                   mbmi_ext->mode_context);
3337
  // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
3338
  // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
3339
1.53M
  av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
3340
1.53M
  int_mv nearestmv, nearmv;
3341
1.53M
  av1_find_best_ref_mvs_from_stack(0, mbmi_ext, ref_frame, &nearestmv, &nearmv,
3342
1.53M
                                   0);
3343
3344
1.53M
  if (nearestmv.as_int == INVALID_MV) {
3345
1.44M
    nearestmv.as_int = 0;
3346
1.44M
  }
3347
1.53M
  if (nearmv.as_int == INVALID_MV) {
3348
1.48M
    nearmv.as_int = 0;
3349
1.48M
  }
3350
3351
1.53M
  int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
3352
1.53M
  if (dv_ref.as_int == 0) {
3353
1.44M
    av1_find_ref_dv(&dv_ref, tile, cm->seq_params->mib_size, mi_row);
3354
1.44M
  }
3355
  // Ref DV should not have sub-pel.
3356
1.53M
  assert((dv_ref.as_mv.col & 7) == 0);
3357
1.53M
  assert((dv_ref.as_mv.row & 7) == 0);
3358
1.53M
  mbmi_ext->ref_mv_stack[INTRA_FRAME][0].this_mv = dv_ref;
3359
3360
1.53M
  struct buf_2d yv12_mb[MAX_MB_PLANE];
3361
1.53M
  av1_setup_pred_block(xd, yv12_mb, xd->cur_buf, NULL, NULL, num_planes);
3362
4.85M
  for (int i = 0; i < num_planes; ++i) {
3363
3.32M
    xd->plane[i].pre[0] = yv12_mb[i];
3364
3.32M
  }
3365
3366
1.53M
  enum IntrabcMotionDirection {
3367
1.53M
    IBC_MOTION_ABOVE,
3368
1.53M
    IBC_MOTION_LEFT,
3369
1.53M
    IBC_MOTION_DIRECTIONS
3370
1.53M
  };
3371
3372
1.53M
  MB_MODE_INFO best_mbmi = *mbmi;
3373
1.53M
  RD_STATS best_rdstats = *rd_stats;
3374
1.53M
  uint8_t best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
3375
1.53M
  av1_copy_array(best_tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
3376
3377
1.53M
  FULLPEL_MOTION_SEARCH_PARAMS fullms_params;
3378
1.53M
  const SEARCH_METHODS search_method =
3379
1.53M
      av1_get_default_mv_search_method(x, &cpi->sf.mv_sf, bsize);
3380
1.53M
  const search_site_config *lookahead_search_sites =
3381
1.53M
      cpi->mv_search_params.search_site_cfg[SS_CFG_LOOKAHEAD];
3382
1.53M
  const FULLPEL_MV start_mv = get_fullmv_from_mv(&dv_ref.as_mv);
3383
1.53M
  av1_make_default_fullpel_ms_params(&fullms_params, cpi, x, bsize,
3384
1.53M
                                     &dv_ref.as_mv, start_mv,
3385
1.53M
                                     lookahead_search_sites, search_method,
3386
1.53M
                                     /*fine_search_interval=*/0);
3387
1.53M
  const IntraBCMVCosts *const dv_costs = x->dv_costs;
3388
1.53M
  av1_set_ms_to_intra_mode(&fullms_params, dv_costs);
3389
3390
1.53M
  const enum IntrabcMotionDirection max_dir = cpi->sf.mv_sf.intrabc_search_level
3391
1.53M
                                                  ? IBC_MOTION_LEFT
3392
1.53M
                                                  : IBC_MOTION_DIRECTIONS;
3393
3394
3.06M
  for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE; dir < max_dir;
3395
1.53M
       ++dir) {
3396
1.53M
    switch (dir) {
3397
1.53M
      case IBC_MOTION_ABOVE:
3398
1.53M
        fullms_params.mv_limits.col_min =
3399
1.53M
            (tile->mi_col_start - mi_col) * MI_SIZE;
3400
1.53M
        fullms_params.mv_limits.col_max =
3401
1.53M
            (tile->mi_col_end - mi_col) * MI_SIZE - w;
3402
1.53M
        fullms_params.mv_limits.row_min =
3403
1.53M
            (tile->mi_row_start - mi_row) * MI_SIZE;
3404
1.53M
        fullms_params.mv_limits.row_max =
3405
1.53M
            (sb_row * cm->seq_params->mib_size - mi_row) * MI_SIZE - h;
3406
1.53M
        break;
3407
0
      case IBC_MOTION_LEFT:
3408
0
        fullms_params.mv_limits.col_min =
3409
0
            (tile->mi_col_start - mi_col) * MI_SIZE;
3410
0
        fullms_params.mv_limits.col_max =
3411
0
            (sb_col * cm->seq_params->mib_size - mi_col) * MI_SIZE - w;
3412
        // TODO(aconverse@google.com): Minimize the overlap between above and
3413
        // left areas.
3414
0
        fullms_params.mv_limits.row_min =
3415
0
            (tile->mi_row_start - mi_row) * MI_SIZE;
3416
0
        int bottom_coded_mi_edge =
3417
0
            AOMMIN((sb_row + 1) * cm->seq_params->mib_size, tile->mi_row_end);
3418
0
        fullms_params.mv_limits.row_max =
3419
0
            (bottom_coded_mi_edge - mi_row) * MI_SIZE - h;
3420
0
        break;
3421
0
      default: assert(0);
3422
1.53M
    }
3423
1.53M
    assert(fullms_params.mv_limits.col_min >= fullms_params.mv_limits.col_min);
3424
1.53M
    assert(fullms_params.mv_limits.col_max <= fullms_params.mv_limits.col_max);
3425
1.53M
    assert(fullms_params.mv_limits.row_min >= fullms_params.mv_limits.row_min);
3426
1.53M
    assert(fullms_params.mv_limits.row_max <= fullms_params.mv_limits.row_max);
3427
3428
1.53M
    av1_set_mv_search_range(&fullms_params.mv_limits, &dv_ref.as_mv);
3429
3430
1.53M
    if (fullms_params.mv_limits.col_max < fullms_params.mv_limits.col_min ||
3431
1.53M
        fullms_params.mv_limits.row_max < fullms_params.mv_limits.row_min) {
3432
0
      continue;
3433
0
    }
3434
3435
1.53M
    const int step_param = cpi->mv_search_params.mv_step_param;
3436
1.53M
    IntraBCHashInfo *intrabc_hash_info = &x->intrabc_hash_info;
3437
1.53M
    int_mv best_mv;
3438
1.53M
    FULLPEL_MV_STATS best_mv_stats;
3439
1.53M
    int bestsme = INT_MAX;
3440
3441
    // Perform a hash search first, and see if we get any matches.
3442
1.53M
    if (!cpi->sf.mv_sf.hash_max_8x8_intrabc_blocks || bsize <= BLOCK_8X8) {
3443
1.45M
      bestsme = av1_intrabc_hash_search(cpi, xd, &fullms_params,
3444
1.45M
                                        intrabc_hash_info, &best_mv.as_fullmv);
3445
1.45M
    }
3446
3447
    // If intrabc_search_level is not 0 and we found a hash search match, do
3448
    // not proceed with pixel search as the hash match is very likely to be the
3449
    // best intrabc candidate anyway.
3450
1.53M
    if (bestsme == INT_MAX || cpi->sf.mv_sf.intrabc_search_level == 0) {
3451
1.53M
      int_mv best_pixel_mv;
3452
1.53M
      const int pixelsme =
3453
1.53M
          av1_full_pixel_search(start_mv, &fullms_params, step_param, NULL,
3454
1.53M
                                &best_pixel_mv.as_fullmv, &best_mv_stats, NULL);
3455
1.53M
      if (pixelsme < bestsme) {
3456
1.53M
        bestsme = pixelsme;
3457
1.53M
        best_mv = best_pixel_mv;
3458
1.53M
      }
3459
1.53M
    }
3460
1.53M
    if (bestsme == INT_MAX) continue;
3461
1.53M
    const MV dv = get_mv_from_fullmv(&best_mv.as_fullmv);
3462
1.53M
    if (!av1_is_fullmv_in_range(&fullms_params.mv_limits,
3463
1.53M
                                get_fullmv_from_mv(&dv)))
3464
0
      continue;
3465
1.53M
    if (!av1_is_dv_valid(dv, cm, xd, mi_row, mi_col, bsize,
3466
1.53M
                         cm->seq_params->mib_size_log2))
3467
1.36M
      continue;
3468
3469
    // DV should not have sub-pel.
3470
1.53M
    assert((dv.col & 7) == 0);
3471
168k
    assert((dv.row & 7) == 0);
3472
168k
    memset(&mbmi->palette_mode_info, 0, sizeof(mbmi->palette_mode_info));
3473
168k
    mbmi->filter_intra_mode_info.use_filter_intra = 0;
3474
168k
    mbmi->use_intrabc = 1;
3475
168k
    mbmi->mode = DC_PRED;
3476
168k
    mbmi->uv_mode = UV_DC_PRED;
3477
168k
    mbmi->motion_mode = SIMPLE_TRANSLATION;
3478
168k
    mbmi->mv[0].as_mv = dv;
3479
168k
    mbmi->interp_filters = av1_broadcast_interp_filter(BILINEAR);
3480
168k
    mbmi->skip_txfm = 0;
3481
168k
    av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize, 0,
3482
168k
                                  av1_num_planes(cm) - 1);
3483
3484
    // TODO(aconverse@google.com): The full motion field defining discount
3485
    // in MV_COST_WEIGHT is too large. Explore other values.
3486
168k
    const int rate_mv = av1_mv_bit_cost(&dv, &dv_ref.as_mv, dv_costs->joint_mv,
3487
168k
                                        dv_costs->dv_costs, MV_COST_WEIGHT_SUB);
3488
168k
    const int rate_mode = x->mode_costs.intrabc_cost[1];
3489
168k
    RD_STATS rd_stats_yuv, rd_stats_y, rd_stats_uv;
3490
168k
    if (!av1_txfm_search(cpi, x, bsize, &rd_stats_yuv, &rd_stats_y,
3491
168k
                         &rd_stats_uv, rate_mode + rate_mv, INT64_MAX))
3492
0
      continue;
3493
168k
    rd_stats_yuv.rdcost =
3494
168k
        RDCOST(x->rdmult, rd_stats_yuv.rate, rd_stats_yuv.dist);
3495
168k
    if (rd_stats_yuv.rdcost < best_rd) {
3496
48.6k
      best_rd = rd_stats_yuv.rdcost;
3497
48.6k
      best_mbmi = *mbmi;
3498
48.6k
      best_rdstats = rd_stats_yuv;
3499
48.6k
      av1_copy_array(best_tx_type_map, xd->tx_type_map, xd->height * xd->width);
3500
48.6k
    }
3501
168k
  }
3502
1.53M
  *mbmi = best_mbmi;
3503
1.53M
  *rd_stats = best_rdstats;
3504
1.53M
  av1_copy_array(xd->tx_type_map, best_tx_type_map, ctx->num_4x4_blk);
3505
#if CONFIG_RD_DEBUG
3506
  mbmi->rd_stats = *rd_stats;
3507
#endif
3508
1.53M
  return best_rd;
3509
1.53M
}
3510
3511
// TODO(chiyotsai@google.com): We are using struct $struct_name instead of their
3512
// typedef here because Doxygen doesn't know about the typedefs yet. So using
3513
// the typedef will prevent doxygen from finding this function and generating
3514
// the callgraph. Once documents for AV1_COMP and MACROBLOCK are added to
3515
// doxygen, we can revert back to using the typedefs.
3516
void av1_rd_pick_intra_mode_sb(const struct AV1_COMP *cpi, struct macroblock *x,
3517
                               struct RD_STATS *rd_cost, BLOCK_SIZE bsize,
3518
18.0M
                               PICK_MODE_CONTEXT *ctx, int64_t best_rd) {
3519
18.0M
  const AV1_COMMON *const cm = &cpi->common;
3520
18.0M
  MACROBLOCKD *const xd = &x->e_mbd;
3521
18.0M
  MB_MODE_INFO *const mbmi = xd->mi[0];
3522
18.0M
  const int num_planes = av1_num_planes(cm);
3523
18.0M
  int rate_y = 0, rate_uv = 0, rate_y_tokenonly = 0, rate_uv_tokenonly = 0;
3524
18.0M
  uint8_t y_skip_txfm = 0, uv_skip_txfm = 0;
3525
18.0M
  int64_t dist_y = 0, dist_uv = 0;
3526
3527
18.0M
  ctx->rd_stats.skip_txfm = 0;
3528
18.0M
  mbmi->ref_frame[0] = INTRA_FRAME;
3529
18.0M
  mbmi->ref_frame[1] = NONE_FRAME;
3530
18.0M
  mbmi->use_intrabc = 0;
3531
18.0M
  mbmi->mv[0].as_int = 0;
3532
18.0M
  mbmi->skip_mode = 0;
3533
3534
18.0M
  const int64_t intra_yrd =
3535
18.0M
      av1_rd_pick_intra_sby_mode(cpi, x, &rate_y, &rate_y_tokenonly, &dist_y,
3536
18.0M
                                 &y_skip_txfm, bsize, best_rd, ctx);
3537
3538
  // Initialize default mode evaluation params
3539
18.0M
  set_mode_eval_params(cpi, x, DEFAULT_EVAL);
3540
3541
18.0M
  if (intra_yrd < best_rd) {
3542
    // Search intra modes for uv planes if needed
3543
16.1M
    if (num_planes > 1) {
3544
      // Set up the tx variables for reproducing the y predictions in case we
3545
      // need it for chroma-from-luma.
3546
7.55M
      if (xd->is_chroma_ref && store_cfl_required_rdo(cm, x)) {
3547
5.76M
        av1_copy_array(xd->tx_type_map, ctx->tx_type_map, ctx->num_4x4_blk);
3548
5.76M
      }
3549
7.55M
      const TX_SIZE max_uv_tx_size = av1_get_tx_size(AOM_PLANE_U, xd);
3550
7.55M
      av1_rd_pick_intra_sbuv_mode(cpi, x, &rate_uv, &rate_uv_tokenonly,
3551
7.55M
                                  &dist_uv, &uv_skip_txfm, bsize,
3552
7.55M
                                  max_uv_tx_size);
3553
7.55M
    }
3554
3555
    // Intra block is always coded as non-skip
3556
16.1M
    rd_cost->rate =
3557
16.1M
        rate_y + rate_uv +
3558
16.1M
        x->mode_costs.skip_txfm_cost[av1_get_skip_txfm_context(xd)][0];
3559
16.1M
    rd_cost->dist = dist_y + dist_uv;
3560
16.1M
    rd_cost->rdcost = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
3561
16.1M
    rd_cost->skip_txfm = 0;
3562
16.1M
  } else {
3563
1.88M
    rd_cost->rate = INT_MAX;
3564
1.88M
  }
3565
3566
18.0M
  if (rd_cost->rate != INT_MAX && rd_cost->rdcost < best_rd)
3567
15.3M
    best_rd = rd_cost->rdcost;
3568
18.0M
  if (rd_pick_intrabc_mode_sb(cpi, x, ctx, rd_cost, bsize, best_rd) < best_rd) {
3569
48.6k
    ctx->rd_stats.skip_txfm = mbmi->skip_txfm;
3570
48.6k
    assert(rd_cost->rate != INT_MAX);
3571
48.6k
  }
3572
18.0M
  if (rd_cost->rate == INT_MAX) return;
3573
3574
16.1M
  ctx->mic = *mbmi;
3575
16.1M
  av1_copy_mbmi_ext_to_mbmi_ext_frame(&ctx->mbmi_ext_best, &x->mbmi_ext,
3576
16.1M
                                      av1_ref_frame_type(xd->mi[0]->ref_frame));
3577
16.1M
  av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
3578
16.1M
}
3579
3580
static inline void calc_target_weighted_pred(
3581
    const AV1_COMMON *cm, const MACROBLOCK *x, const MACROBLOCKD *xd,
3582
    const uint8_t *above, int above_stride, const uint8_t *left,
3583
    int left_stride);
3584
3585
static inline void rd_pick_skip_mode(
3586
    RD_STATS *rd_cost, InterModeSearchState *search_state,
3587
    const AV1_COMP *const cpi, MACROBLOCK *const x, BLOCK_SIZE bsize,
3588
223k
    struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE]) {
3589
223k
  const AV1_COMMON *const cm = &cpi->common;
3590
223k
  const SkipModeInfo *const skip_mode_info = &cm->current_frame.skip_mode_info;
3591
223k
  const int num_planes = av1_num_planes(cm);
3592
223k
  MACROBLOCKD *const xd = &x->e_mbd;
3593
223k
  MB_MODE_INFO *const mbmi = xd->mi[0];
3594
3595
223k
  x->compound_idx = 1;  // COMPOUND_AVERAGE
3596
223k
  RD_STATS skip_mode_rd_stats;
3597
223k
  av1_invalid_rd_stats(&skip_mode_rd_stats);
3598
3599
223k
  if (skip_mode_info->ref_frame_idx_0 == INVALID_IDX ||
3600
223k
      skip_mode_info->ref_frame_idx_1 == INVALID_IDX) {
3601
0
    return;
3602
0
  }
3603
3604
223k
  const MV_REFERENCE_FRAME ref_frame =
3605
223k
      LAST_FRAME + skip_mode_info->ref_frame_idx_0;
3606
223k
  const MV_REFERENCE_FRAME second_ref_frame =
3607
223k
      LAST_FRAME + skip_mode_info->ref_frame_idx_1;
3608
223k
  const PREDICTION_MODE this_mode = NEAREST_NEARESTMV;
3609
223k
  const THR_MODES mode_index =
3610
223k
      get_prediction_mode_idx(this_mode, ref_frame, second_ref_frame);
3611
3612
223k
  if (mode_index == THR_INVALID) {
3613
0
    return;
3614
0
  }
3615
3616
223k
  if ((!cpi->oxcf.ref_frm_cfg.enable_onesided_comp ||
3617
223k
       cpi->sf.inter_sf.disable_onesided_comp) &&
3618
223k
      cpi->all_one_sided_refs) {
3619
85.1k
    return;
3620
85.1k
  }
3621
3622
138k
  mbmi->mode = this_mode;
3623
138k
  mbmi->uv_mode = UV_DC_PRED;
3624
138k
  mbmi->ref_frame[0] = ref_frame;
3625
138k
  mbmi->ref_frame[1] = second_ref_frame;
3626
138k
  const uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
3627
138k
  if (x->mbmi_ext.ref_mv_count[ref_frame_type] == UINT8_MAX) {
3628
763
    MB_MODE_INFO_EXT *mbmi_ext = &x->mbmi_ext;
3629
763
    if (mbmi_ext->ref_mv_count[ref_frame] == UINT8_MAX ||
3630
590
        mbmi_ext->ref_mv_count[second_ref_frame] == UINT8_MAX) {
3631
590
      return;
3632
590
    }
3633
173
    av1_find_mv_refs(cm, xd, mbmi, ref_frame_type, mbmi_ext->ref_mv_count,
3634
173
                     xd->ref_mv_stack, xd->weight, NULL, mbmi_ext->global_mvs,
3635
173
                     mbmi_ext->mode_context);
3636
    // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
3637
    // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
3638
173
    av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame_type);
3639
173
  }
3640
3641
138k
  assert(this_mode == NEAREST_NEARESTMV);
3642
137k
  if (!build_cur_mv(mbmi->mv, this_mode, cm, x, 0)) {
3643
1.81k
    return;
3644
1.81k
  }
3645
3646
135k
  mbmi->filter_intra_mode_info.use_filter_intra = 0;
3647
135k
  mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
3648
135k
  mbmi->comp_group_idx = 0;
3649
135k
  mbmi->compound_idx = x->compound_idx;
3650
135k
  mbmi->interinter_comp.type = COMPOUND_AVERAGE;
3651
135k
  mbmi->motion_mode = SIMPLE_TRANSLATION;
3652
135k
  mbmi->ref_mv_idx = 0;
3653
135k
  mbmi->skip_mode = mbmi->skip_txfm = 1;
3654
135k
  mbmi->palette_mode_info.palette_size[0] = 0;
3655
135k
  mbmi->palette_mode_info.palette_size[1] = 0;
3656
3657
135k
  set_default_interp_filters(mbmi, cm->features.interp_filter);
3658
3659
135k
  set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3660
434k
  for (int i = 0; i < num_planes; i++) {
3661
299k
    xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
3662
299k
    xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
3663
299k
  }
3664
3665
135k
  BUFFER_SET orig_dst;
3666
434k
  for (int i = 0; i < num_planes; i++) {
3667
299k
    orig_dst.plane[i] = xd->plane[i].dst.buf;
3668
299k
    orig_dst.stride[i] = xd->plane[i].dst.stride;
3669
299k
  }
3670
3671
  // Compare the use of skip_mode with the best intra/inter mode obtained.
3672
135k
  const int skip_mode_ctx = av1_get_skip_mode_context(xd);
3673
135k
  int64_t best_intra_inter_mode_cost = INT64_MAX;
3674
135k
  if (rd_cost->dist < INT64_MAX && rd_cost->rate < INT32_MAX) {
3675
133k
    const ModeCosts *mode_costs = &x->mode_costs;
3676
133k
    best_intra_inter_mode_cost = RDCOST(
3677
133k
        x->rdmult, rd_cost->rate + mode_costs->skip_mode_cost[skip_mode_ctx][0],
3678
133k
        rd_cost->dist);
3679
    // Account for non-skip mode rate in total rd stats
3680
133k
    rd_cost->rate += mode_costs->skip_mode_cost[skip_mode_ctx][0];
3681
133k
    av1_rd_cost_update(x->rdmult, rd_cost);
3682
133k
  }
3683
3684
  // Obtain the rdcost for skip_mode.
3685
135k
  skip_mode_rd(&skip_mode_rd_stats, cpi, x, bsize, &orig_dst,
3686
135k
               best_intra_inter_mode_cost);
3687
3688
135k
  if (skip_mode_rd_stats.rdcost <= best_intra_inter_mode_cost &&
3689
14.7k
      (!xd->lossless[mbmi->segment_id] || skip_mode_rd_stats.dist == 0)) {
3690
14.7k
    assert(mode_index != THR_INVALID);
3691
14.7k
    search_state->best_mbmode.skip_mode = 1;
3692
14.7k
    search_state->best_mbmode = *mbmi;
3693
14.7k
    memset(search_state->best_mbmode.inter_tx_size,
3694
14.7k
           search_state->best_mbmode.tx_size,
3695
14.7k
           sizeof(search_state->best_mbmode.inter_tx_size));
3696
14.7k
    set_txfm_ctxs(search_state->best_mbmode.tx_size, xd->width, xd->height,
3697
14.7k
                  search_state->best_mbmode.skip_txfm && is_inter_block(mbmi),
3698
14.7k
                  xd);
3699
14.7k
    search_state->best_mode_index = mode_index;
3700
3701
    // Update rd_cost
3702
14.7k
    rd_cost->rate = skip_mode_rd_stats.rate;
3703
14.7k
    rd_cost->dist = rd_cost->sse = skip_mode_rd_stats.dist;
3704
14.7k
    rd_cost->rdcost = skip_mode_rd_stats.rdcost;
3705
3706
14.7k
    search_state->best_rd = rd_cost->rdcost;
3707
14.7k
    search_state->best_skip2 = 1;
3708
14.7k
    search_state->best_mode_skippable = 1;
3709
3710
14.7k
    x->txfm_search_info.skip_txfm = 1;
3711
14.7k
  }
3712
135k
}
3713
3714
// Get winner mode stats of given mode index
3715
static inline MB_MODE_INFO *get_winner_mode_stats(
3716
    MACROBLOCK *x, MB_MODE_INFO *best_mbmode, RD_STATS *best_rd_cost,
3717
    int best_rate_y, int best_rate_uv, THR_MODES *best_mode_index,
3718
    RD_STATS **winner_rd_cost, int *winner_rate_y, int *winner_rate_uv,
3719
    THR_MODES *winner_mode_index, MULTI_WINNER_MODE_TYPE multi_winner_mode_type,
3720
718k
    int mode_idx) {
3721
718k
  MB_MODE_INFO *winner_mbmi;
3722
718k
  if (multi_winner_mode_type) {
3723
0
    assert(mode_idx >= 0 && mode_idx < x->winner_mode_count);
3724
0
    WinnerModeStats *winner_mode_stat = &x->winner_mode_stats[mode_idx];
3725
0
    winner_mbmi = &winner_mode_stat->mbmi;
3726
3727
0
    *winner_rd_cost = &winner_mode_stat->rd_cost;
3728
0
    *winner_rate_y = winner_mode_stat->rate_y;
3729
0
    *winner_rate_uv = winner_mode_stat->rate_uv;
3730
0
    *winner_mode_index = winner_mode_stat->mode_index;
3731
718k
  } else {
3732
718k
    winner_mbmi = best_mbmode;
3733
718k
    *winner_rd_cost = best_rd_cost;
3734
718k
    *winner_rate_y = best_rate_y;
3735
718k
    *winner_rate_uv = best_rate_uv;
3736
718k
    *winner_mode_index = *best_mode_index;
3737
718k
  }
3738
718k
  return winner_mbmi;
3739
718k
}
3740
3741
// speed feature: fast intra/inter transform type search
3742
// Used for speed >= 2
3743
// When this speed feature is on, in rd mode search, only DCT is used.
3744
// After the mode is determined, this function is called, to select
3745
// transform types and get accurate rdcost.
3746
static inline void refine_winner_mode_tx(
3747
    const AV1_COMP *cpi, MACROBLOCK *x, RD_STATS *rd_cost, BLOCK_SIZE bsize,
3748
    PICK_MODE_CONTEXT *ctx, THR_MODES *best_mode_index,
3749
    MB_MODE_INFO *best_mbmode, struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE],
3750
903k
    int best_rate_y, int best_rate_uv, int *best_skip2, int winner_mode_count) {
3751
903k
  const AV1_COMMON *const cm = &cpi->common;
3752
903k
  MACROBLOCKD *const xd = &x->e_mbd;
3753
903k
  MB_MODE_INFO *const mbmi = xd->mi[0];
3754
903k
  TxfmSearchParams *txfm_params = &x->txfm_search_params;
3755
903k
  int64_t best_rd;
3756
903k
  const int num_planes = av1_num_planes(cm);
3757
3758
903k
  if (!is_winner_mode_processing_enabled(cpi, x, best_mbmode,
3759
903k
                                         rd_cost->skip_txfm))
3760
171k
    return;
3761
3762
  // Set params for winner mode evaluation
3763
731k
  set_mode_eval_params(cpi, x, WINNER_MODE_EVAL);
3764
3765
  // No best mode identified so far
3766
731k
  if (*best_mode_index == THR_INVALID) return;
3767
3768
718k
  best_rd = RDCOST(x->rdmult, rd_cost->rate, rd_cost->dist);
3769
1.43M
  for (int mode_idx = 0; mode_idx < winner_mode_count; mode_idx++) {
3770
718k
    RD_STATS *winner_rd_stats = NULL;
3771
718k
    int winner_rate_y = 0, winner_rate_uv = 0;
3772
718k
    THR_MODES winner_mode_index = 0;
3773
3774
    // TODO(any): Combine best mode and multi-winner mode processing paths
3775
    // Get winner mode stats for current mode index
3776
718k
    MB_MODE_INFO *winner_mbmi = get_winner_mode_stats(
3777
718k
        x, best_mbmode, rd_cost, best_rate_y, best_rate_uv, best_mode_index,
3778
718k
        &winner_rd_stats, &winner_rate_y, &winner_rate_uv, &winner_mode_index,
3779
718k
        cpi->sf.winner_mode_sf.multi_winner_mode_type, mode_idx);
3780
3781
718k
    if (xd->lossless[winner_mbmi->segment_id] == 0 &&
3782
672k
        winner_mode_index != THR_INVALID &&
3783
672k
        is_winner_mode_processing_enabled(cpi, x, winner_mbmi,
3784
672k
                                          rd_cost->skip_txfm)) {
3785
672k
      RD_STATS rd_stats = *winner_rd_stats;
3786
672k
      int skip_blk = 0;
3787
672k
      RD_STATS rd_stats_y, rd_stats_uv;
3788
672k
      const int skip_ctx = av1_get_skip_txfm_context(xd);
3789
3790
672k
      *mbmi = *winner_mbmi;
3791
3792
672k
      set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
3793
3794
      // Select prediction reference frames.
3795
1.88M
      for (int i = 0; i < num_planes; i++) {
3796
1.21M
        xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
3797
1.21M
        if (has_second_ref(mbmi))
3798
11.3k
          xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
3799
1.21M
      }
3800
3801
672k
      if (is_inter_mode(mbmi->mode)) {
3802
154k
        const int mi_row = xd->mi_row;
3803
154k
        const int mi_col = xd->mi_col;
3804
154k
        bool is_predictor_built = false;
3805
154k
        const PREDICTION_MODE prediction_mode = mbmi->mode;
3806
        // Do interpolation filter search for realtime mode if applicable.
3807
154k
        if (cpi->sf.winner_mode_sf.winner_mode_ifs &&
3808
0
            cpi->oxcf.mode == REALTIME &&
3809
0
            cm->current_frame.reference_mode == SINGLE_REFERENCE &&
3810
0
            is_inter_mode(prediction_mode) &&
3811
0
            mbmi->motion_mode == SIMPLE_TRANSLATION &&
3812
0
            !is_inter_compound_mode(prediction_mode)) {
3813
0
          is_predictor_built =
3814
0
              fast_interp_search(cpi, x, mi_row, mi_col, bsize);
3815
0
        }
3816
154k
        if (!is_predictor_built) {
3817
154k
          av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize, 0,
3818
154k
                                        av1_num_planes(cm) - 1);
3819
154k
        }
3820
154k
        if (mbmi->motion_mode == OBMC_CAUSAL)
3821
0
          av1_build_obmc_inter_predictors_sb(cm, xd);
3822
3823
154k
        av1_subtract_plane(x, bsize, PLANE_TYPE_Y, cpi->do_border_pad);
3824
154k
        if (txfm_params->tx_mode_search_type == TX_MODE_SELECT &&
3825
154k
            !xd->lossless[mbmi->segment_id]) {
3826
154k
          av1_pick_recursive_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
3827
154k
                                              INT64_MAX);
3828
154k
          assert(rd_stats_y.rate != INT_MAX);
3829
18.4E
        } else {
3830
18.4E
          av1_pick_uniform_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
3831
18.4E
                                            INT64_MAX);
3832
18.4E
          memset(mbmi->inter_tx_size, mbmi->tx_size,
3833
18.4E
                 sizeof(mbmi->inter_tx_size));
3834
18.4E
        }
3835
518k
      } else {
3836
518k
        av1_pick_uniform_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize,
3837
518k
                                          INT64_MAX);
3838
518k
      }
3839
3840
672k
      if (num_planes > 1) {
3841
272k
        av1_txfm_uvrd(cpi, x, &rd_stats_uv, bsize, INT64_MAX);
3842
399k
      } else {
3843
399k
        av1_init_rd_stats(&rd_stats_uv);
3844
399k
      }
3845
3846
672k
      const int comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
3847
3848
672k
      const ModeCosts *mode_costs = &x->mode_costs;
3849
672k
      int64_t this_dist = rd_stats_y.dist + rd_stats_uv.dist;
3850
672k
      int64_t this_sse = rd_stats_y.sse + rd_stats_uv.sse;
3851
672k
      if (cpi->sf.hl_sf.weighted_chroma_distortion) {
3852
0
        this_dist = rd_stats_y.dist + rd_stats_uv.dist * 15 / 16;
3853
0
        this_sse = rd_stats_y.sse + rd_stats_uv.sse * 15 / 16;
3854
0
      }
3855
3856
672k
      if (is_inter_mode(mbmi->mode) &&
3857
154k
          (!cpi->oxcf.algo_cfg.sharpness || !comp_pred) &&
3858
154k
          RDCOST(x->rdmult,
3859
154k
                 mode_costs->skip_txfm_cost[skip_ctx][0] + rd_stats_y.rate +
3860
154k
                     rd_stats_uv.rate,
3861
154k
                 this_dist) > RDCOST(x->rdmult,
3862
672k
                                     mode_costs->skip_txfm_cost[skip_ctx][1],
3863
672k
                                     this_sse)) {
3864
15.0k
        skip_blk = 1;
3865
15.0k
        rd_stats_y.rate = mode_costs->skip_txfm_cost[skip_ctx][1];
3866
15.0k
        rd_stats_uv.rate = 0;
3867
15.0k
        rd_stats_y.dist = rd_stats_y.sse;
3868
15.0k
        rd_stats_uv.dist = rd_stats_uv.sse;
3869
15.0k
        this_dist = this_sse;
3870
657k
      } else {
3871
657k
        skip_blk = 0;
3872
657k
        rd_stats_y.rate += mode_costs->skip_txfm_cost[skip_ctx][0];
3873
657k
      }
3874
672k
      increase_motion_mode_rdstats(cpi, mbmi, &rd_stats, &rd_stats_y,
3875
672k
                                   &rd_stats_uv);
3876
672k
      int this_rate = rd_stats.rate + rd_stats_y.rate + rd_stats_uv.rate -
3877
672k
                      winner_rate_y - winner_rate_uv;
3878
672k
      int64_t this_rd = RDCOST(x->rdmult, this_rate, this_dist);
3879
672k
      if (best_rd > this_rd) {
3880
577k
        *best_mbmode = *mbmi;
3881
577k
        *best_mode_index = winner_mode_index;
3882
577k
        av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
3883
577k
        rd_cost->rate = this_rate;
3884
577k
        rd_cost->dist = this_dist;
3885
577k
        rd_cost->sse = this_sse;
3886
577k
        rd_cost->rdcost = this_rd;
3887
577k
        best_rd = this_rd;
3888
577k
        *best_skip2 = skip_blk;
3889
577k
      }
3890
672k
    }
3891
718k
  }
3892
718k
}
3893
3894
/*!\cond */
3895
typedef struct {
3896
  // Mask for each reference frame, specifying which prediction modes to NOT try
3897
  // during search.
3898
  uint32_t pred_modes[REF_FRAMES];
3899
  // If ref_combo[i][j + 1] is true, do NOT try prediction using combination of
3900
  // reference frames (i, j).
3901
  // Note: indexing with 'j + 1' is due to the fact that 2nd reference can be -1
3902
  // (NONE_FRAME).
3903
  bool ref_combo[REF_FRAMES][REF_FRAMES + 1];
3904
} mode_skip_mask_t;
3905
/*!\endcond */
3906
3907
// Update 'ref_combo' mask to disable given 'ref' in single and compound modes.
3908
static inline void disable_reference(
3909
4.98M
    MV_REFERENCE_FRAME ref, bool ref_combo[REF_FRAMES][REF_FRAMES + 1]) {
3910
49.8M
  for (MV_REFERENCE_FRAME ref2 = NONE_FRAME; ref2 < REF_FRAMES; ++ref2) {
3911
44.9M
    ref_combo[ref][ref2 + 1] = true;
3912
44.9M
  }
3913
4.98M
}
3914
3915
// Update 'ref_combo' mask to disable all inter references except ALTREF.
3916
static inline void disable_inter_references_except_altref(
3917
40.5k
    bool ref_combo[REF_FRAMES][REF_FRAMES + 1]) {
3918
40.5k
  disable_reference(LAST_FRAME, ref_combo);
3919
40.5k
  disable_reference(LAST2_FRAME, ref_combo);
3920
40.5k
  disable_reference(LAST3_FRAME, ref_combo);
3921
40.5k
  disable_reference(GOLDEN_FRAME, ref_combo);
3922
40.5k
  disable_reference(BWDREF_FRAME, ref_combo);
3923
40.5k
  disable_reference(ALTREF2_FRAME, ref_combo);
3924
40.5k
}
3925
3926
static const MV_REFERENCE_FRAME reduced_ref_combos[][2] = {
3927
  { LAST_FRAME, NONE_FRAME },     { ALTREF_FRAME, NONE_FRAME },
3928
  { LAST_FRAME, ALTREF_FRAME },   { GOLDEN_FRAME, NONE_FRAME },
3929
  { INTRA_FRAME, NONE_FRAME },    { GOLDEN_FRAME, ALTREF_FRAME },
3930
  { LAST_FRAME, GOLDEN_FRAME },   { LAST_FRAME, INTRA_FRAME },
3931
  { LAST_FRAME, BWDREF_FRAME },   { LAST_FRAME, LAST3_FRAME },
3932
  { GOLDEN_FRAME, BWDREF_FRAME }, { GOLDEN_FRAME, INTRA_FRAME },
3933
  { BWDREF_FRAME, NONE_FRAME },   { BWDREF_FRAME, ALTREF_FRAME },
3934
  { ALTREF_FRAME, INTRA_FRAME },  { BWDREF_FRAME, INTRA_FRAME },
3935
};
3936
3937
typedef enum { REF_SET_FULL, REF_SET_REDUCED, REF_SET_REALTIME } REF_SET;
3938
3939
902k
static inline void default_skip_mask(mode_skip_mask_t *mask, REF_SET ref_set) {
3940
902k
  if (ref_set == REF_SET_FULL) {
3941
    // Everything available by default.
3942
902k
    memset(mask, 0, sizeof(*mask));
3943
902k
  } else {
3944
    // All modes available by default.
3945
297
    memset(mask->pred_modes, 0, sizeof(mask->pred_modes));
3946
    // All references disabled first.
3947
297
    for (MV_REFERENCE_FRAME ref1 = INTRA_FRAME; ref1 < REF_FRAMES; ++ref1) {
3948
0
      for (MV_REFERENCE_FRAME ref2 = NONE_FRAME; ref2 < REF_FRAMES; ++ref2) {
3949
0
        mask->ref_combo[ref1][ref2 + 1] = true;
3950
0
      }
3951
0
    }
3952
297
    const MV_REFERENCE_FRAME(*ref_set_combos)[2];
3953
297
    int num_ref_combos;
3954
3955
    // Then enable reduced set of references explicitly.
3956
297
    switch (ref_set) {
3957
0
      case REF_SET_REDUCED:
3958
0
        ref_set_combos = reduced_ref_combos;
3959
0
        num_ref_combos =
3960
0
            (int)sizeof(reduced_ref_combos) / sizeof(reduced_ref_combos[0]);
3961
0
        break;
3962
0
      case REF_SET_REALTIME:
3963
0
        ref_set_combos = real_time_ref_combos;
3964
0
        num_ref_combos =
3965
0
            (int)sizeof(real_time_ref_combos) / sizeof(real_time_ref_combos[0]);
3966
0
        break;
3967
0
      default: assert(0); num_ref_combos = 0;
3968
297
    }
3969
3970
0
    for (int i = 0; i < num_ref_combos; ++i) {
3971
0
      const MV_REFERENCE_FRAME *const this_combo = ref_set_combos[i];
3972
0
      mask->ref_combo[this_combo[0]][this_combo[1] + 1] = false;
3973
0
    }
3974
0
  }
3975
902k
}
3976
3977
static inline void init_mode_skip_mask(mode_skip_mask_t *mask,
3978
                                       const AV1_COMP *cpi, MACROBLOCK *x,
3979
903k
                                       BLOCK_SIZE bsize) {
3980
903k
  const AV1_COMMON *const cm = &cpi->common;
3981
903k
  const struct segmentation *const seg = &cm->seg;
3982
903k
  MACROBLOCKD *const xd = &x->e_mbd;
3983
903k
  MB_MODE_INFO *const mbmi = xd->mi[0];
3984
903k
  unsigned char segment_id = mbmi->segment_id;
3985
903k
  const SPEED_FEATURES *const sf = &cpi->sf;
3986
903k
  const INTER_MODE_SPEED_FEATURES *const inter_sf = &sf->inter_sf;
3987
903k
  REF_SET ref_set = REF_SET_FULL;
3988
3989
903k
  if (sf->rt_sf.use_real_time_ref_set)
3990
0
    ref_set = REF_SET_REALTIME;
3991
903k
  else if (cpi->oxcf.ref_frm_cfg.enable_reduced_reference_set)
3992
0
    ref_set = REF_SET_REDUCED;
3993
3994
903k
  default_skip_mask(mask, ref_set);
3995
3996
903k
  int min_pred_mv_sad = INT_MAX;
3997
903k
  MV_REFERENCE_FRAME ref_frame;
3998
903k
  if (ref_set == REF_SET_REALTIME) {
3999
    // For real-time encoding, we only look at a subset of ref frames. So the
4000
    // threshold for pruning should be computed from this subset as well.
4001
0
    const int num_rt_refs =
4002
0
        sizeof(real_time_ref_combos) / sizeof(*real_time_ref_combos);
4003
0
    for (int r_idx = 0; r_idx < num_rt_refs; r_idx++) {
4004
0
      const MV_REFERENCE_FRAME ref = real_time_ref_combos[r_idx][0];
4005
0
      if (ref != INTRA_FRAME) {
4006
0
        const MV_REFERENCE_FRAME ref_frames[2] = { ref, NONE_FRAME };
4007
0
        const int_mv ref_mv =
4008
0
            av1_get_ref_mv_from_stack(0, ref_frames, 0, &x->mbmi_ext);
4009
0
        const FULLPEL_MV full_mv = get_fullmv_from_mv(&ref_mv.as_mv);
4010
0
        if (av1_is_fullmv_in_range(&x->mv_limits, full_mv)) {
4011
0
          min_pred_mv_sad = AOMMIN(min_pred_mv_sad, x->pred_mv_sad[ref]);
4012
0
        }
4013
0
      }
4014
0
    }
4015
903k
  } else {
4016
7.22M
    for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame)
4017
6.31M
      min_pred_mv_sad = AOMMIN(min_pred_mv_sad, x->pred_mv_sad[ref_frame]);
4018
903k
  }
4019
4020
7.20M
  for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4021
6.30M
    if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame])) {
4022
      // Skip checking missing reference in both single and compound reference
4023
      // modes.
4024
4.70M
      disable_reference(ref_frame, mask->ref_combo);
4025
4.70M
    } else {
4026
      // Skip fixed mv modes for poor references
4027
1.59M
      if ((x->pred_mv_sad[ref_frame] >> 2) > min_pred_mv_sad) {
4028
80.1k
        mask->pred_modes[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
4029
80.1k
      }
4030
1.59M
    }
4031
6.30M
    if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME) &&
4032
0
        get_segdata(seg, segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame) {
4033
      // Reference not used for the segment.
4034
0
      disable_reference(ref_frame, mask->ref_combo);
4035
0
    }
4036
6.30M
  }
4037
  // Note: We use the following drop-out only if the SEG_LVL_REF_FRAME feature
4038
  // is disabled for this segment. This is to prevent the possibility that we
4039
  // end up unable to pick any mode.
4040
903k
  if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
4041
    // Only consider GLOBALMV/ALTREF_FRAME for alt ref frame,
4042
    // unless ARNR filtering is enabled in which case we want
4043
    // an unfiltered alternative. We allow near/nearest as well
4044
    // because they may result in zero-zero MVs but be cheaper.
4045
902k
    if (cpi->rc.is_src_frame_alt_ref &&
4046
40.6k
        (cpi->oxcf.algo_cfg.arnr_max_frames == 0)) {
4047
0
      disable_inter_references_except_altref(mask->ref_combo);
4048
4049
0
      mask->pred_modes[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
4050
0
      const MV_REFERENCE_FRAME tmp_ref_frames[2] = { ALTREF_FRAME, NONE_FRAME };
4051
0
      int_mv near_mv, nearest_mv, global_mv;
4052
0
      get_this_mv(&nearest_mv, NEARESTMV, 0, 0, 0, tmp_ref_frames,
4053
0
                  &x->mbmi_ext);
4054
0
      get_this_mv(&near_mv, NEARMV, 0, 0, 0, tmp_ref_frames, &x->mbmi_ext);
4055
0
      get_this_mv(&global_mv, GLOBALMV, 0, 0, 0, tmp_ref_frames, &x->mbmi_ext);
4056
4057
0
      if (near_mv.as_int != global_mv.as_int)
4058
0
        mask->pred_modes[ALTREF_FRAME] |= (1 << NEARMV);
4059
0
      if (nearest_mv.as_int != global_mv.as_int)
4060
0
        mask->pred_modes[ALTREF_FRAME] |= (1 << NEARESTMV);
4061
0
    }
4062
902k
  }
4063
4064
903k
  if (cpi->rc.is_src_frame_alt_ref) {
4065
40.6k
    if (inter_sf->alt_ref_search_fp &&
4066
40.6k
        (cpi->ref_frame_flags & av1_ref_frame_flag_list[ALTREF_FRAME])) {
4067
40.5k
      mask->pred_modes[ALTREF_FRAME] = 0;
4068
40.5k
      disable_inter_references_except_altref(mask->ref_combo);
4069
40.5k
      disable_reference(INTRA_FRAME, mask->ref_combo);
4070
40.5k
    }
4071
40.6k
  }
4072
4073
903k
  if (inter_sf->alt_ref_search_fp) {
4074
902k
    if (!cm->show_frame && x->best_pred_mv_sad[0] < INT_MAX) {
4075
69.1k
      int sad_thresh = x->best_pred_mv_sad[0] + (x->best_pred_mv_sad[0] >> 3);
4076
      // Conservatively skip the modes w.r.t. BWDREF, ALTREF2 and ALTREF, if
4077
      // those are past frames
4078
69.1k
      MV_REFERENCE_FRAME start_frame =
4079
69.1k
          inter_sf->alt_ref_search_fp == 1 ? ALTREF2_FRAME : BWDREF_FRAME;
4080
276k
      for (ref_frame = start_frame; ref_frame <= ALTREF_FRAME; ref_frame++) {
4081
207k
        if (cpi->ref_frame_dist_info.ref_relative_dist[ref_frame - LAST_FRAME] <
4082
207k
            0) {
4083
          // Prune inter modes when relative dist of ALTREF2 and ALTREF is close
4084
          // to the relative dist of LAST_FRAME.
4085
0
          if (abs(cpi->ref_frame_dist_info
4086
0
                      .ref_relative_dist[ref_frame - LAST_FRAME] -
4087
0
                  cpi->ref_frame_dist_info
4088
0
                      .ref_relative_dist[LAST_FRAME - LAST_FRAME]) > 4) {
4089
0
            continue;
4090
0
          }
4091
0
          if (x->pred_mv_sad[ref_frame] > sad_thresh)
4092
0
            mask->pred_modes[ref_frame] |= INTER_ALL;
4093
0
        }
4094
207k
      }
4095
69.1k
    }
4096
902k
  }
4097
4098
903k
  if (sf->rt_sf.prune_inter_modes_wrt_gf_arf_based_on_sad) {
4099
0
    if (x->best_pred_mv_sad[0] < INT_MAX) {
4100
0
      int sad_thresh = x->best_pred_mv_sad[0] + (x->best_pred_mv_sad[0] >> 1);
4101
0
      const int prune_ref_list[2] = { GOLDEN_FRAME, ALTREF_FRAME };
4102
4103
      // Conservatively skip the modes w.r.t. GOLDEN and ALTREF references
4104
0
      for (int ref_idx = 0; ref_idx < 2; ref_idx++) {
4105
0
        ref_frame = prune_ref_list[ref_idx];
4106
0
        if (x->pred_mv_sad[ref_frame] > sad_thresh)
4107
0
          mask->pred_modes[ref_frame] |= INTER_NEAREST_NEAR_ZERO;
4108
0
      }
4109
0
    }
4110
0
  }
4111
4112
903k
  if (bsize > sf->part_sf.max_intra_bsize) {
4113
4.01k
    disable_reference(INTRA_FRAME, mask->ref_combo);
4114
4.01k
  }
4115
4116
903k
  if (!cpi->oxcf.tool_cfg.enable_global_motion) {
4117
0
    for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4118
0
      mask->pred_modes[ref_frame] |= (1 << GLOBALMV);
4119
0
      mask->pred_modes[ref_frame] |= (1 << GLOBAL_GLOBALMV);
4120
0
    }
4121
0
  }
4122
4123
903k
  mask->pred_modes[INTRA_FRAME] |=
4124
903k
      ~(uint32_t)sf->intra_sf.intra_y_mode_mask[max_txsize_lookup[bsize]];
4125
4126
  // Prune reference frames which are not the closest to the current
4127
  // frame and with large pred_mv_sad.
4128
903k
  if (inter_sf->prune_single_ref) {
4129
833k
    assert(inter_sf->prune_single_ref > 0 && inter_sf->prune_single_ref < 5);
4130
833k
    const double prune_thresh = (inter_sf->prune_single_ref <= 3) ? 1.20 : 1.05;
4131
4132
6.65M
    for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
4133
5.82M
      const RefFrameDistanceInfo *const ref_frame_dist_info =
4134
5.82M
          &cpi->ref_frame_dist_info;
4135
5.82M
      const int is_closest_ref =
4136
5.82M
          (ref_frame == ref_frame_dist_info->nearest_past_ref) ||
4137
4.98M
          (ref_frame == ref_frame_dist_info->nearest_future_ref);
4138
5.82M
      const int ref_idx = ref_frame - LAST_FRAME;
4139
4140
5.82M
      if (!(cpi->keep_single_ref_frame_mask & (1 << ref_idx) ||
4141
5.82M
            is_closest_ref)) {
4142
4.85M
        const int dir =
4143
4.85M
            (ref_frame_dist_info->ref_relative_dist[ref_frame - LAST_FRAME] < 0)
4144
4.85M
                ? 0
4145
4.85M
                : 1;
4146
4.85M
        if (x->best_pred_mv_sad[dir] < INT_MAX &&
4147
1.29M
            x->pred_mv_sad[ref_frame] > prune_thresh * x->best_pred_mv_sad[dir])
4148
950k
          mask->pred_modes[ref_frame] |= INTER_SINGLE_ALL;
4149
4.85M
      }
4150
5.82M
    }
4151
833k
  }
4152
903k
}
4153
4154
static inline void init_neighbor_pred_buf(const OBMCBuffer *const obmc_buffer,
4155
                                          HandleInterModeArgs *const args,
4156
902k
                                          int is_hbd) {
4157
902k
  if (is_hbd) {
4158
110k
    const int len = sizeof(uint16_t);
4159
110k
    args->above_pred_buf[0] = CONVERT_TO_BYTEPTR(obmc_buffer->above_pred);
4160
110k
    args->above_pred_buf[1] = CONVERT_TO_BYTEPTR(obmc_buffer->above_pred +
4161
110k
                                                 (MAX_SB_SQUARE >> 1) * len);
4162
110k
    args->above_pred_buf[2] =
4163
110k
        CONVERT_TO_BYTEPTR(obmc_buffer->above_pred + MAX_SB_SQUARE * len);
4164
110k
    args->left_pred_buf[0] = CONVERT_TO_BYTEPTR(obmc_buffer->left_pred);
4165
110k
    args->left_pred_buf[1] =
4166
110k
        CONVERT_TO_BYTEPTR(obmc_buffer->left_pred + (MAX_SB_SQUARE >> 1) * len);
4167
110k
    args->left_pred_buf[2] =
4168
110k
        CONVERT_TO_BYTEPTR(obmc_buffer->left_pred + MAX_SB_SQUARE * len);
4169
792k
  } else {
4170
792k
    args->above_pred_buf[0] = obmc_buffer->above_pred;
4171
792k
    args->above_pred_buf[1] = obmc_buffer->above_pred + (MAX_SB_SQUARE >> 1);
4172
792k
    args->above_pred_buf[2] = obmc_buffer->above_pred + MAX_SB_SQUARE;
4173
792k
    args->left_pred_buf[0] = obmc_buffer->left_pred;
4174
792k
    args->left_pred_buf[1] = obmc_buffer->left_pred + (MAX_SB_SQUARE >> 1);
4175
792k
    args->left_pred_buf[2] = obmc_buffer->left_pred + MAX_SB_SQUARE;
4176
792k
  }
4177
902k
}
4178
4179
static inline int prune_ref_frame(const AV1_COMP *cpi, const MACROBLOCK *x,
4180
12.0M
                                  MV_REFERENCE_FRAME ref_frame) {
4181
12.0M
  const AV1_COMMON *const cm = &cpi->common;
4182
12.0M
  MV_REFERENCE_FRAME rf[2];
4183
12.0M
  av1_set_ref_frame(rf, ref_frame);
4184
4185
12.0M
  if ((cpi->prune_ref_frame_mask >> ref_frame) & 1) return 1;
4186
4187
7.07M
  if (prune_ref_by_selective_ref_frame(cpi, x, rf,
4188
7.07M
                                       cm->cur_frame->ref_display_order_hint)) {
4189
653k
    return 1;
4190
653k
  }
4191
4192
6.41M
  return 0;
4193
7.07M
}
4194
4195
static inline int is_ref_frame_used_by_compound_ref(int ref_frame,
4196
27.7k
                                                    int skip_ref_frame_mask) {
4197
431k
  for (int r = ALTREF_FRAME + 1; r < MODE_CTX_REF_FRAMES; ++r) {
4198
414k
    if (!(skip_ref_frame_mask & (1 << r))) {
4199
11.2k
      const MV_REFERENCE_FRAME *rf = ref_frame_map[r - REF_FRAMES];
4200
11.2k
      if (rf[0] == ref_frame || rf[1] == ref_frame) {
4201
10.6k
        return 1;
4202
10.6k
      }
4203
11.2k
    }
4204
414k
  }
4205
17.1k
  return 0;
4206
27.7k
}
4207
4208
static inline int is_ref_frame_used_in_cache(MV_REFERENCE_FRAME ref_frame,
4209
101k
                                             const MB_MODE_INFO *mi_cache) {
4210
101k
  if (!mi_cache) {
4211
101k
    return 0;
4212
101k
  }
4213
4214
10
  if (ref_frame < REF_FRAMES) {
4215
0
    return (ref_frame == mi_cache->ref_frame[0] ||
4216
0
            ref_frame == mi_cache->ref_frame[1]);
4217
0
  }
4218
4219
  // if we are here, then the current mode is compound.
4220
10
  MV_REFERENCE_FRAME cached_ref_type = av1_ref_frame_type(mi_cache->ref_frame);
4221
10
  return ref_frame == cached_ref_type;
4222
10
}
4223
4224
// Please add/modify parameter setting in this function, making it consistent
4225
// and easy to read and maintain.
4226
static inline void set_params_rd_pick_inter_mode(
4227
    const AV1_COMP *cpi, MACROBLOCK *x, HandleInterModeArgs *args,
4228
    BLOCK_SIZE bsize, mode_skip_mask_t *mode_skip_mask, int skip_ref_frame_mask,
4229
    unsigned int *ref_costs_single, unsigned int (*ref_costs_comp)[REF_FRAMES],
4230
902k
    struct buf_2d (*yv12_mb)[MAX_MB_PLANE]) {
4231
902k
  const AV1_COMMON *const cm = &cpi->common;
4232
902k
  MACROBLOCKD *const xd = &x->e_mbd;
4233
902k
  MB_MODE_INFO *const mbmi = xd->mi[0];
4234
902k
  MB_MODE_INFO_EXT *const mbmi_ext = &x->mbmi_ext;
4235
902k
  unsigned char segment_id = mbmi->segment_id;
4236
4237
902k
  init_neighbor_pred_buf(&x->obmc_buffer, args, is_cur_buf_hbd(&x->e_mbd));
4238
902k
  av1_collect_neighbors_ref_counts(xd);
4239
902k
  estimate_ref_frame_costs(cm, xd, &x->mode_costs, segment_id, ref_costs_single,
4240
902k
                           ref_costs_comp);
4241
4242
902k
  const int mi_row = xd->mi_row;
4243
902k
  const int mi_col = xd->mi_col;
4244
902k
  x->best_pred_mv_sad[0] = INT_MAX;
4245
902k
  x->best_pred_mv_sad[1] = INT_MAX;
4246
4247
7.22M
  for (MV_REFERENCE_FRAME ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME;
4248
6.31M
       ++ref_frame) {
4249
6.31M
    x->pred_mv_sad[ref_frame] = INT_MAX;
4250
6.31M
    mbmi_ext->mode_context[ref_frame] = 0;
4251
6.31M
    mbmi_ext->ref_mv_count[ref_frame] = UINT8_MAX;
4252
6.31M
    if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frame]) {
4253
      // Skip the ref frame if the mask says skip and the ref is not used by
4254
      // compound ref.
4255
1.61M
      if (skip_ref_frame_mask & (1 << ref_frame) &&
4256
16.3k
          !is_ref_frame_used_by_compound_ref(ref_frame, skip_ref_frame_mask) &&
4257
14.2k
          !is_ref_frame_used_in_cache(ref_frame, x->mb_mode_cache)) {
4258
14.2k
        continue;
4259
14.2k
      }
4260
1.61M
      assert(get_ref_frame_yv12_buf(cm, ref_frame) != NULL);
4261
1.59M
      setup_buffer_ref_mvs_inter(cpi, x, ref_frame, bsize, yv12_mb);
4262
1.59M
    }
4263
6.30M
    if (cpi->sf.inter_sf.alt_ref_search_fp ||
4264
0
        cpi->sf.inter_sf.prune_single_ref ||
4265
6.30M
        cpi->sf.rt_sf.prune_inter_modes_wrt_gf_arf_based_on_sad) {
4266
      // Store the best pred_mv_sad across all past frames
4267
6.30M
      if (cpi->ref_frame_dist_info.ref_relative_dist[ref_frame - LAST_FRAME] <
4268
6.30M
          0)
4269
1.41M
        x->best_pred_mv_sad[0] =
4270
1.41M
            AOMMIN(x->best_pred_mv_sad[0], x->pred_mv_sad[ref_frame]);
4271
4.88M
      else
4272
        // Store the best pred_mv_sad across all future frames
4273
4.88M
        x->best_pred_mv_sad[1] =
4274
4.88M
            AOMMIN(x->best_pred_mv_sad[1], x->pred_mv_sad[ref_frame]);
4275
6.30M
    }
4276
6.30M
  }
4277
4278
903k
  if (!cpi->sf.rt_sf.use_real_time_ref_set && is_comp_ref_allowed(bsize)) {
4279
    // No second reference on RT ref set, so no need to initialize
4280
903k
    for (MV_REFERENCE_FRAME ref_frame = EXTREF_FRAME;
4281
19.8M
         ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
4282
18.9M
      mbmi_ext->mode_context[ref_frame] = 0;
4283
18.9M
      mbmi_ext->ref_mv_count[ref_frame] = UINT8_MAX;
4284
18.9M
      const MV_REFERENCE_FRAME *rf = ref_frame_map[ref_frame - REF_FRAMES];
4285
18.9M
      if (!((cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[0]]) &&
4286
17.9M
            (cpi->ref_frame_flags & av1_ref_frame_flag_list[rf[1]]))) {
4287
17.9M
        continue;
4288
17.9M
      }
4289
4290
980k
      if (skip_ref_frame_mask & (1 << ref_frame) &&
4291
26.4k
          !is_ref_frame_used_in_cache(ref_frame, x->mb_mode_cache)) {
4292
26.4k
        continue;
4293
26.4k
      }
4294
      // Ref mv list population is not required, when compound references are
4295
      // pruned.
4296
954k
      if (prune_ref_frame(cpi, x, ref_frame)) continue;
4297
4298
135k
      av1_find_mv_refs(cm, xd, mbmi, ref_frame, mbmi_ext->ref_mv_count,
4299
135k
                       xd->ref_mv_stack, xd->weight, NULL, mbmi_ext->global_mvs,
4300
135k
                       mbmi_ext->mode_context);
4301
      // TODO(Ravi): Populate mbmi_ext->ref_mv_stack[ref_frame][4] and
4302
      // mbmi_ext->weight[ref_frame][4] inside av1_find_mv_refs.
4303
135k
      av1_copy_usable_ref_mv_stack_and_weight(xd, mbmi_ext, ref_frame);
4304
135k
    }
4305
903k
  }
4306
4307
902k
  av1_count_overlappable_neighbors(cm, xd);
4308
902k
  const FRAME_UPDATE_TYPE update_type =
4309
902k
      get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
4310
902k
  int use_actual_frame_probs = 1;
4311
902k
  int prune_obmc;
4312
#if CONFIG_FPMT_TEST
4313
  use_actual_frame_probs =
4314
      (cpi->ppi->fpmt_unit_test_cfg == PARALLEL_SIMULATION_ENCODE) ? 0 : 1;
4315
  if (!use_actual_frame_probs) {
4316
    prune_obmc = cpi->ppi->temp_frame_probs.obmc_probs[update_type][bsize] <
4317
                 cpi->sf.inter_sf.prune_obmc_prob_thresh;
4318
  }
4319
#endif
4320
903k
  if (use_actual_frame_probs) {
4321
903k
    prune_obmc = cpi->ppi->frame_probs.obmc_probs[update_type][bsize] <
4322
903k
                 cpi->sf.inter_sf.prune_obmc_prob_thresh;
4323
903k
  }
4324
903k
  if (cpi->oxcf.motion_mode_cfg.enable_obmc && !prune_obmc) {
4325
0
    if (check_num_overlappable_neighbors(mbmi) &&
4326
0
        is_motion_variation_allowed_bsize(bsize)) {
4327
0
      int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
4328
0
      int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE >> 1, MAX_SB_SIZE >> 1,
4329
0
                                       MAX_SB_SIZE >> 1 };
4330
0
      int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE >> 1, MAX_SB_SIZE >> 1,
4331
0
                                        MAX_SB_SIZE >> 1 };
4332
0
      int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE };
4333
0
      av1_build_prediction_by_above_preds(cm, xd, args->above_pred_buf,
4334
0
                                          dst_width1, dst_height1,
4335
0
                                          args->above_pred_stride);
4336
0
      av1_build_prediction_by_left_preds(cm, xd, args->left_pred_buf,
4337
0
                                         dst_width2, dst_height2,
4338
0
                                         args->left_pred_stride);
4339
0
      const int num_planes = av1_num_planes(cm);
4340
0
      av1_setup_dst_planes(xd->plane, bsize, &cm->cur_frame->buf, mi_row,
4341
0
                           mi_col, 0, num_planes);
4342
0
      calc_target_weighted_pred(
4343
0
          cm, x, xd, args->above_pred_buf[0], args->above_pred_stride[0],
4344
0
          args->left_pred_buf[0], args->left_pred_stride[0]);
4345
0
    }
4346
0
  }
4347
4348
902k
  init_mode_skip_mask(mode_skip_mask, cpi, x, bsize);
4349
4350
  // Set params for mode evaluation
4351
902k
  set_mode_eval_params(cpi, x, MODE_EVAL);
4352
4353
902k
  x->comp_rd_stats_idx = 0;
4354
4355
8.12M
  for (int idx = 0; idx < REF_FRAMES; idx++) {
4356
7.21M
    args->best_single_sse_in_refs[idx] = INT32_MAX;
4357
7.21M
  }
4358
902k
}
4359
4360
static inline void init_single_inter_mode_search_state(
4361
903k
    InterModeSearchState *search_state) {
4362
2.70M
  for (int dir = 0; dir < 2; ++dir) {
4363
9.03M
    for (int mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4364
36.1M
      for (int ref_frame = 0; ref_frame < FWD_REFS; ++ref_frame) {
4365
28.9M
        SingleInterModeState *state;
4366
4367
28.9M
        state = &search_state->single_state[dir][mode][ref_frame];
4368
28.9M
        state->ref_frame = NONE_FRAME;
4369
28.9M
        state->rd = INT64_MAX;
4370
4371
28.9M
        state = &search_state->single_state_modelled[dir][mode][ref_frame];
4372
28.9M
        state->ref_frame = NONE_FRAME;
4373
28.9M
        state->rd = INT64_MAX;
4374
4375
28.9M
        search_state->single_rd_order[dir][mode][ref_frame] = NONE_FRAME;
4376
28.9M
      }
4377
7.22M
    }
4378
1.80M
  }
4379
4380
8.12M
  for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) {
4381
7.22M
    search_state->best_single_rd[ref_frame] = INT64_MAX;
4382
7.22M
    search_state->best_single_mode[ref_frame] = PRED_MODE_INVALID;
4383
7.22M
  }
4384
903k
  av1_zero(search_state->single_state_cnt);
4385
903k
  av1_zero(search_state->single_state_modelled_cnt);
4386
903k
}
4387
4388
static inline void init_inter_mode_search_state(
4389
    InterModeSearchState *search_state, const AV1_COMP *cpi,
4390
903k
    const MACROBLOCK *x, BLOCK_SIZE bsize, int64_t best_rd_so_far) {
4391
903k
  init_intra_mode_search_state(&search_state->intra_search_state);
4392
903k
  av1_invalid_rd_stats(&search_state->best_y_rdcost);
4393
4394
903k
  search_state->best_rd = best_rd_so_far;
4395
903k
  search_state->best_skip_rd[0] = INT64_MAX;
4396
903k
  search_state->best_skip_rd[1] = INT64_MAX;
4397
4398
903k
  av1_zero(search_state->best_mbmode);
4399
4400
903k
  search_state->best_rate_y = INT_MAX;
4401
4402
903k
  search_state->best_rate_uv = INT_MAX;
4403
4404
903k
  search_state->best_mode_skippable = 0;
4405
4406
903k
  search_state->best_skip2 = 0;
4407
4408
903k
  search_state->best_mode_index = THR_INVALID;
4409
4410
903k
  const MACROBLOCKD *const xd = &x->e_mbd;
4411
903k
  const MB_MODE_INFO *const mbmi = xd->mi[0];
4412
903k
  const unsigned char segment_id = mbmi->segment_id;
4413
4414
903k
  search_state->num_available_refs = 0;
4415
903k
  memset(search_state->dist_refs, -1, sizeof(search_state->dist_refs));
4416
903k
  memset(search_state->dist_order_refs, -1,
4417
903k
         sizeof(search_state->dist_order_refs));
4418
4419
7.22M
  for (int i = 0; i <= LAST_NEW_MV_INDEX; ++i)
4420
6.31M
    search_state->mode_threshold[i] = 0;
4421
903k
  const int *const rd_threshes = cpi->rd.threshes[segment_id][bsize];
4422
19.8M
  for (int i = LAST_NEW_MV_INDEX + 1; i < SINGLE_REF_MODE_END; ++i)
4423
18.9M
    search_state->mode_threshold[i] =
4424
18.9M
        ((int64_t)rd_threshes[i] * x->thresh_freq_fact[bsize][i]) >>
4425
18.9M
        RD_THRESH_FAC_FRAC_BITS;
4426
4427
903k
  search_state->best_intra_rd = INT64_MAX;
4428
4429
903k
  search_state->best_pred_sse = UINT_MAX;
4430
4431
903k
  av1_zero(search_state->single_newmv);
4432
903k
  av1_zero(search_state->single_newmv_rate);
4433
903k
  av1_zero(search_state->single_newmv_valid);
4434
4.51M
  for (int i = SINGLE_INTER_MODE_START; i < SINGLE_INTER_MODE_END; ++i) {
4435
14.4M
    for (int j = 0; j < MAX_REF_MV_SEARCH; ++j) {
4436
97.2M
      for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) {
4437
86.4M
        search_state->modelled_rd[i][j][ref_frame] = INT64_MAX;
4438
86.4M
        search_state->simple_rd[i][j][ref_frame] = INT64_MAX;
4439
86.4M
      }
4440
10.8M
    }
4441
3.60M
  }
4442
4443
3.61M
  for (int i = 0; i < REFERENCE_MODES; ++i) {
4444
2.70M
    search_state->best_pred_rd[i] = INT64_MAX;
4445
2.70M
  }
4446
4447
903k
  if (cpi->common.current_frame.reference_mode != SINGLE_REFERENCE) {
4448
116M
    for (int i = SINGLE_REF_MODE_END; i < THR_INTER_MODE_END; ++i)
4449
115M
      search_state->mode_threshold[i] =
4450
115M
          ((int64_t)rd_threshes[i] * x->thresh_freq_fact[bsize][i]) >>
4451
115M
          RD_THRESH_FAC_FRAC_BITS;
4452
4453
8.10M
    for (int i = COMP_INTER_MODE_START; i < COMP_INTER_MODE_END; ++i) {
4454
28.7M
      for (int j = 0; j < MAX_REF_MV_SEARCH; ++j) {
4455
194M
        for (int ref_frame = 0; ref_frame < REF_FRAMES; ++ref_frame) {
4456
172M
          search_state->modelled_rd[i][j][ref_frame] = INT64_MAX;
4457
172M
          search_state->simple_rd[i][j][ref_frame] = INT64_MAX;
4458
172M
        }
4459
21.5M
      }
4460
7.19M
    }
4461
4462
903k
    init_single_inter_mode_search_state(search_state);
4463
903k
  }
4464
903k
}
4465
4466
static bool mask_says_skip(const mode_skip_mask_t *mode_skip_mask,
4467
                           const MV_REFERENCE_FRAME *ref_frame,
4468
48.0M
                           const PREDICTION_MODE this_mode) {
4469
48.0M
  if (mode_skip_mask->pred_modes[ref_frame[0]] & (1 << this_mode)) {
4470
5.05M
    return true;
4471
5.05M
  }
4472
4473
42.9M
  return mode_skip_mask->ref_combo[ref_frame[0]][ref_frame[1] + 1];
4474
48.0M
}
4475
4476
static AOM_FORCE_INLINE int inter_mode_compatible_skip(
4477
    const AV1_COMP *cpi, const MACROBLOCK *x, BLOCK_SIZE bsize,
4478
131M
    PREDICTION_MODE curr_mode, const MV_REFERENCE_FRAME *ref_frames) {
4479
131M
  const int comp_pred = ref_frames[1] > INTRA_FRAME;
4480
131M
  if (comp_pred) {
4481
106M
    if (!is_comp_ref_allowed(bsize)) return 1;
4482
106M
    if (!(cpi->ref_frame_flags & av1_ref_frame_flag_list[ref_frames[1]])) {
4483
83.7M
      return 1;
4484
83.7M
    }
4485
4486
22.7M
    const AV1_COMMON *const cm = &cpi->common;
4487
22.7M
    if (frame_is_intra_only(cm)) return 1;
4488
4489
22.7M
    const CurrentFrame *const current_frame = &cm->current_frame;
4490
22.7M
    if (current_frame->reference_mode == SINGLE_REFERENCE) return 1;
4491
4492
22.7M
    const struct segmentation *const seg = &cm->seg;
4493
22.7M
    const unsigned char segment_id = x->e_mbd.mi[0]->segment_id;
4494
    // Do not allow compound prediction if the segment level reference frame
4495
    // feature is in use as in this case there can only be one reference.
4496
22.7M
    if (segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) return 1;
4497
22.7M
  }
4498
4499
48.0M
  if (ref_frames[0] > INTRA_FRAME && ref_frames[1] == INTRA_FRAME) {
4500
    // Mode must be compatible
4501
0
    if (!is_interintra_allowed_bsize(bsize)) return 1;
4502
0
    if (!is_interintra_allowed_mode(curr_mode)) return 1;
4503
0
  }
4504
4505
47.8M
  return 0;
4506
47.8M
}
4507
4508
static int fetch_picked_ref_frames_mask(const MACROBLOCK *const x,
4509
9.15k
                                        BLOCK_SIZE bsize, int mib_size) {
4510
9.15k
  const int sb_size_mask = mib_size - 1;
4511
9.15k
  const MACROBLOCKD *const xd = &x->e_mbd;
4512
9.15k
  const int mi_row = xd->mi_row;
4513
9.15k
  const int mi_col = xd->mi_col;
4514
9.15k
  const int mi_row_in_sb = mi_row & sb_size_mask;
4515
9.15k
  const int mi_col_in_sb = mi_col & sb_size_mask;
4516
9.15k
  const int mi_w = mi_size_wide[bsize];
4517
9.15k
  const int mi_h = mi_size_high[bsize];
4518
9.15k
  int picked_ref_frames_mask = 0;
4519
47.5k
  for (int i = mi_row_in_sb; i < mi_row_in_sb + mi_h; ++i) {
4520
145k
    for (int j = mi_col_in_sb; j < mi_col_in_sb + mi_w; ++j) {
4521
107k
      picked_ref_frames_mask |= x->picked_ref_frames_mask[i * 32 + j];
4522
107k
    }
4523
38.4k
  }
4524
9.15k
  return picked_ref_frames_mask;
4525
9.15k
}
4526
4527
// Check if reference frame pair of the current block matches with the given
4528
// block.
4529
static inline int match_ref_frame_pair(const MB_MODE_INFO *mbmi,
4530
1.79M
                                       const MV_REFERENCE_FRAME *ref_frames) {
4531
1.79M
  return ((ref_frames[0] == mbmi->ref_frame[0]) &&
4532
378k
          (ref_frames[1] == mbmi->ref_frame[1]));
4533
1.79M
}
4534
4535
// Case 1: return 0, means don't skip this mode
4536
// Case 2: return 1, means skip this mode completely
4537
// Case 3: return 2, means skip compound only, but still try single motion modes
4538
static AOM_FORCE_INLINE int inter_mode_search_order_independent_skip(
4539
    const AV1_COMP *cpi, const MACROBLOCK *x, mode_skip_mask_t *mode_skip_mask,
4540
    InterModeSearchState *search_state, int skip_ref_frame_mask,
4541
48.0M
    PREDICTION_MODE mode, const MV_REFERENCE_FRAME *ref_frame) {
4542
48.0M
  if (mask_says_skip(mode_skip_mask, ref_frame, mode)) {
4543
36.9M
    return 1;
4544
36.9M
  }
4545
4546
11.0M
  const int ref_type = av1_ref_frame_type(ref_frame);
4547
11.0M
  if (!cpi->sf.rt_sf.use_real_time_ref_set)
4548
11.1M
    if (prune_ref_frame(cpi, x, ref_type)) return 1;
4549
4550
  // This is only used in motion vector unit test.
4551
6.25M
  if (cpi->oxcf.unit_test_cfg.motion_vector_unit_test &&
4552
0
      ref_frame[0] == INTRA_FRAME)
4553
0
    return 1;
4554
4555
6.25M
  const AV1_COMMON *const cm = &cpi->common;
4556
6.25M
  if (skip_repeated_mv(cm, x, mode, ref_frame, search_state)) {
4557
72.3k
    return 1;
4558
72.3k
  }
4559
4560
  // Reuse the prediction mode in cache
4561
6.18M
  if (x->use_mb_mode_cache) {
4562
0
    const MB_MODE_INFO *cached_mi = x->mb_mode_cache;
4563
0
    const PREDICTION_MODE cached_mode = cached_mi->mode;
4564
0
    const MV_REFERENCE_FRAME *cached_frame = cached_mi->ref_frame;
4565
0
    const int cached_mode_is_single = cached_frame[1] <= INTRA_FRAME;
4566
4567
    // If the cached mode is intra, then we just need to match the mode.
4568
0
    if (is_mode_intra(cached_mode) && mode != cached_mode) {
4569
0
      return 1;
4570
0
    }
4571
4572
    // If the cached mode is single inter mode, then we match the mode and
4573
    // reference frame.
4574
0
    if (cached_mode_is_single) {
4575
0
      if (mode != cached_mode || ref_frame[0] != cached_frame[0]) {
4576
0
        return 1;
4577
0
      }
4578
0
    } else {
4579
      // If the cached mode is compound, then we need to consider several cases.
4580
0
      const int mode_is_single = ref_frame[1] <= INTRA_FRAME;
4581
0
      if (mode_is_single) {
4582
        // If the mode is single, we know the modes can't match. But we might
4583
        // still want to search it if compound mode depends on the current mode.
4584
0
        int skip_motion_mode_only = 0;
4585
0
        if (cached_mode == NEW_NEARMV || cached_mode == NEW_NEARESTMV) {
4586
0
          skip_motion_mode_only = (ref_frame[0] == cached_frame[0]);
4587
0
        } else if (cached_mode == NEAR_NEWMV || cached_mode == NEAREST_NEWMV) {
4588
0
          skip_motion_mode_only = (ref_frame[0] == cached_frame[1]);
4589
0
        } else if (cached_mode == NEW_NEWMV) {
4590
0
          skip_motion_mode_only = (ref_frame[0] == cached_frame[0] ||
4591
0
                                   ref_frame[0] == cached_frame[1]);
4592
0
        }
4593
4594
0
        return 1 + skip_motion_mode_only;
4595
0
      } else {
4596
        // If both modes are compound, then everything must match.
4597
0
        if (mode != cached_mode || ref_frame[0] != cached_frame[0] ||
4598
0
            ref_frame[1] != cached_frame[1]) {
4599
0
          return 1;
4600
0
        }
4601
0
      }
4602
0
    }
4603
0
  }
4604
4605
6.18M
  const MB_MODE_INFO *const mbmi = x->e_mbd.mi[0];
4606
  // If no valid mode has been found so far in PARTITION_NONE when finding a
4607
  // valid partition is required, do not skip mode.
4608
6.18M
  if (search_state->best_rd == INT64_MAX && mbmi->partition == PARTITION_NONE &&
4609
672k
      x->must_find_valid_partition)
4610
0
    return 0;
4611
4612
6.18M
  const SPEED_FEATURES *const sf = &cpi->sf;
4613
  // Prune NEARMV and NEAR_NEARMV based on q index and neighbor's reference
4614
  // frames
4615
6.18M
  if (sf->inter_sf.prune_nearmv_using_neighbors &&
4616
6.21M
      (mode == NEAR_NEARMV || mode == NEARMV)) {
4617
1.40M
    const MACROBLOCKD *const xd = &x->e_mbd;
4618
1.40M
    if (search_state->best_rd != INT64_MAX && xd->left_available &&
4619
1.11M
        xd->up_available) {
4620
897k
      const int thresholds[PRUNE_NEARMV_MAX][3] = { { 1, 0, 0 },
4621
897k
                                                    { 1, 1, 0 },
4622
897k
                                                    { 2, 1, 0 } };
4623
897k
      const int qindex_sub_range = x->qindex * 3 / QINDEX_RANGE;
4624
4625
897k
      assert(sf->inter_sf.prune_nearmv_using_neighbors <= PRUNE_NEARMV_MAX &&
4626
897k
             qindex_sub_range < 3);
4627
897k
      const int num_ref_frame_pair_match_thresh =
4628
897k
          thresholds[sf->inter_sf.prune_nearmv_using_neighbors - 1]
4629
897k
                    [qindex_sub_range];
4630
4631
897k
      assert(num_ref_frame_pair_match_thresh <= 2 &&
4632
897k
             num_ref_frame_pair_match_thresh >= 0);
4633
897k
      int num_ref_frame_pair_match = 0;
4634
4635
897k
      num_ref_frame_pair_match = match_ref_frame_pair(xd->left_mbmi, ref_frame);
4636
897k
      num_ref_frame_pair_match +=
4637
897k
          match_ref_frame_pair(xd->above_mbmi, ref_frame);
4638
4639
      // Pruning based on ref frame pair match with neighbors.
4640
897k
      if (num_ref_frame_pair_match < num_ref_frame_pair_match_thresh) return 1;
4641
897k
    }
4642
1.40M
  }
4643
4644
5.64M
  int skip_motion_mode = 0;
4645
5.64M
  if (mbmi->partition != PARTITION_NONE) {
4646
61.2k
    assert(ref_type > NONE_FRAME);
4647
61.2k
    int skip_ref = skip_ref_frame_mask & (1 << ref_type);
4648
61.2k
    if (ref_type <= ALTREF_FRAME && skip_ref) {
4649
      // Since the compound ref modes depends on the motion estimation result of
4650
      // two single ref modes (best mv of single ref modes as the start point),
4651
      // if current single ref mode is marked skip, we need to check if it will
4652
      // be used in compound ref modes.
4653
11.4k
      if (is_ref_frame_used_by_compound_ref(ref_type, skip_ref_frame_mask)) {
4654
        // Found a not skipped compound ref mode which contains current
4655
        // single ref. So this single ref can't be skipped completely
4656
        // Just skip its motion mode search, still try its simple
4657
        // transition mode.
4658
8.50k
        skip_motion_mode = 1;
4659
8.50k
        skip_ref = 0;
4660
8.50k
      }
4661
11.4k
    }
4662
    // If we are reusing the prediction from cache, and the current frame is
4663
    // required by the cache, then we cannot prune it.
4664
61.2k
    if (is_ref_frame_used_in_cache(ref_type, x->mb_mode_cache)) {
4665
0
      skip_ref = 0;
4666
      // If the cache only needs the current reference type for compound
4667
      // prediction, then we can skip motion mode search.
4668
0
      skip_motion_mode = (ref_type <= ALTREF_FRAME &&
4669
0
                          x->mb_mode_cache->ref_frame[1] > INTRA_FRAME);
4670
0
    }
4671
61.2k
    if (skip_ref) return 1;
4672
61.2k
  }
4673
4674
5.63M
  if (ref_frame[0] == INTRA_FRAME) {
4675
0
    if (mode != DC_PRED) {
4676
      // Disable intra modes other than DC_PRED for blocks with low variance
4677
      // Threshold for intra skipping based on source variance
4678
      // TODO(debargha): Specialize the threshold for super block sizes
4679
0
      const unsigned int skip_intra_var_thresh = 64;
4680
0
      if ((sf->rt_sf.mode_search_skip_flags & FLAG_SKIP_INTRA_LOWVAR) &&
4681
0
          x->source_variance < skip_intra_var_thresh)
4682
0
        return 1;
4683
0
    }
4684
0
  }
4685
4686
5.63M
  if (skip_motion_mode) return 2;
4687
4688
5.63M
  return 0;
4689
5.63M
}
4690
4691
static inline void init_mbmi(MB_MODE_INFO *mbmi, PREDICTION_MODE curr_mode,
4692
                             const MV_REFERENCE_FRAME *ref_frames,
4693
45.7M
                             const AV1_COMMON *cm) {
4694
45.7M
  PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
4695
45.7M
  mbmi->ref_mv_idx = 0;
4696
45.7M
  mbmi->mode = curr_mode;
4697
45.7M
  mbmi->uv_mode = UV_DC_PRED;
4698
45.7M
  mbmi->ref_frame[0] = ref_frames[0];
4699
45.7M
  mbmi->ref_frame[1] = ref_frames[1];
4700
45.7M
  pmi->palette_size[0] = 0;
4701
45.7M
  pmi->palette_size[1] = 0;
4702
45.7M
  mbmi->filter_intra_mode_info.use_filter_intra = 0;
4703
45.7M
  mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
4704
45.7M
  mbmi->motion_mode = SIMPLE_TRANSLATION;
4705
45.7M
  mbmi->interintra_mode = (INTERINTRA_MODE)(II_DC_PRED - 1);
4706
45.7M
  set_default_interp_filters(mbmi, cm->features.interp_filter);
4707
45.7M
}
4708
4709
static inline void collect_single_states(MACROBLOCK *x,
4710
                                         InterModeSearchState *search_state,
4711
193k
                                         const MB_MODE_INFO *const mbmi) {
4712
193k
  int i, j;
4713
193k
  const MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame[0];
4714
193k
  const PREDICTION_MODE this_mode = mbmi->mode;
4715
18.4E
  const int dir = ref_frame <= GOLDEN_FRAME ? 0 : 1;
4716
193k
  const int mode_offset = INTER_OFFSET(this_mode);
4717
193k
  const int ref_set = get_drl_refmv_count(x, mbmi->ref_frame, this_mode);
4718
4719
  // Simple rd
4720
193k
  int64_t simple_rd = search_state->simple_rd[this_mode][0][ref_frame];
4721
233k
  for (int ref_mv_idx = 1; ref_mv_idx < ref_set; ++ref_mv_idx) {
4722
39.2k
    const int64_t rd =
4723
39.2k
        search_state->simple_rd[this_mode][ref_mv_idx][ref_frame];
4724
39.2k
    if (rd < simple_rd) simple_rd = rd;
4725
39.2k
  }
4726
4727
  // Insertion sort of single_state
4728
193k
  const SingleInterModeState this_state_s = { simple_rd, ref_frame, 1 };
4729
193k
  SingleInterModeState *state_s = search_state->single_state[dir][mode_offset];
4730
193k
  i = search_state->single_state_cnt[dir][mode_offset];
4731
193k
  for (j = i; j > 0 && state_s[j - 1].rd > this_state_s.rd; --j)
4732
0
    state_s[j] = state_s[j - 1];
4733
193k
  state_s[j] = this_state_s;
4734
193k
  search_state->single_state_cnt[dir][mode_offset]++;
4735
4736
  // Modelled rd
4737
193k
  int64_t modelled_rd = search_state->modelled_rd[this_mode][0][ref_frame];
4738
233k
  for (int ref_mv_idx = 1; ref_mv_idx < ref_set; ++ref_mv_idx) {
4739
39.2k
    const int64_t rd =
4740
39.2k
        search_state->modelled_rd[this_mode][ref_mv_idx][ref_frame];
4741
39.2k
    if (rd < modelled_rd) modelled_rd = rd;
4742
39.2k
  }
4743
4744
  // Insertion sort of single_state_modelled
4745
193k
  const SingleInterModeState this_state_m = { modelled_rd, ref_frame, 1 };
4746
193k
  SingleInterModeState *state_m =
4747
193k
      search_state->single_state_modelled[dir][mode_offset];
4748
193k
  i = search_state->single_state_modelled_cnt[dir][mode_offset];
4749
193k
  for (j = i; j > 0 && state_m[j - 1].rd > this_state_m.rd; --j)
4750
0
    state_m[j] = state_m[j - 1];
4751
193k
  state_m[j] = this_state_m;
4752
193k
  search_state->single_state_modelled_cnt[dir][mode_offset]++;
4753
193k
}
4754
4755
static inline void analyze_single_states(const AV1_COMP *cpi,
4756
0
                                         InterModeSearchState *search_state) {
4757
0
  const int prune_level = cpi->sf.inter_sf.prune_comp_search_by_single_result;
4758
0
  assert(prune_level >= 1);
4759
0
  int i, j, dir, mode;
4760
4761
0
  for (dir = 0; dir < 2; ++dir) {
4762
0
    int64_t best_rd;
4763
0
    SingleInterModeState(*state)[FWD_REFS];
4764
0
    const int prune_factor = prune_level >= 2 ? 6 : 5;
4765
4766
    // Use the best rd of GLOBALMV or NEWMV to prune the unlikely
4767
    // reference frames for all the modes (NEARESTMV and NEARMV may not
4768
    // have same motion vectors). Always keep the best of each mode
4769
    // because it might form the best possible combination with other mode.
4770
0
    state = search_state->single_state[dir];
4771
0
    best_rd = AOMMIN(state[INTER_OFFSET(NEWMV)][0].rd,
4772
0
                     state[INTER_OFFSET(GLOBALMV)][0].rd);
4773
0
    for (mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4774
0
      for (i = 1; i < search_state->single_state_cnt[dir][mode]; ++i) {
4775
0
        if (state[mode][i].rd != INT64_MAX &&
4776
0
            (state[mode][i].rd >> 3) * prune_factor > best_rd) {
4777
0
          state[mode][i].valid = 0;
4778
0
        }
4779
0
      }
4780
0
    }
4781
4782
0
    state = search_state->single_state_modelled[dir];
4783
0
    best_rd = AOMMIN(state[INTER_OFFSET(NEWMV)][0].rd,
4784
0
                     state[INTER_OFFSET(GLOBALMV)][0].rd);
4785
0
    for (mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4786
0
      for (i = 1; i < search_state->single_state_modelled_cnt[dir][mode]; ++i) {
4787
0
        if (state[mode][i].rd != INT64_MAX &&
4788
0
            (state[mode][i].rd >> 3) * prune_factor > best_rd) {
4789
0
          state[mode][i].valid = 0;
4790
0
        }
4791
0
      }
4792
0
    }
4793
0
  }
4794
4795
  // Ordering by simple rd first, then by modelled rd
4796
0
  for (dir = 0; dir < 2; ++dir) {
4797
0
    for (mode = 0; mode < SINGLE_INTER_MODE_NUM; ++mode) {
4798
0
      const int state_cnt_s = search_state->single_state_cnt[dir][mode];
4799
0
      const int state_cnt_m =
4800
0
          search_state->single_state_modelled_cnt[dir][mode];
4801
0
      SingleInterModeState *state_s = search_state->single_state[dir][mode];
4802
0
      SingleInterModeState *state_m =
4803
0
          search_state->single_state_modelled[dir][mode];
4804
0
      int count = 0;
4805
0
      const int max_candidates = AOMMAX(state_cnt_s, state_cnt_m);
4806
0
      for (i = 0; i < state_cnt_s; ++i) {
4807
0
        if (state_s[i].rd == INT64_MAX) break;
4808
0
        if (state_s[i].valid) {
4809
0
          search_state->single_rd_order[dir][mode][count++] =
4810
0
              state_s[i].ref_frame;
4811
0
        }
4812
0
      }
4813
0
      if (count >= max_candidates) continue;
4814
4815
0
      for (i = 0; i < state_cnt_m && count < max_candidates; ++i) {
4816
0
        if (state_m[i].rd == INT64_MAX) break;
4817
0
        if (!state_m[i].valid) continue;
4818
0
        const int ref_frame = state_m[i].ref_frame;
4819
0
        int match = 0;
4820
        // Check if existing already
4821
0
        for (j = 0; j < count; ++j) {
4822
0
          if (search_state->single_rd_order[dir][mode][j] == ref_frame) {
4823
0
            match = 1;
4824
0
            break;
4825
0
          }
4826
0
        }
4827
0
        if (match) continue;
4828
        // Check if this ref_frame is removed in simple rd
4829
0
        int valid = 1;
4830
0
        for (j = 0; j < state_cnt_s; ++j) {
4831
0
          if (ref_frame == state_s[j].ref_frame) {
4832
0
            valid = state_s[j].valid;
4833
0
            break;
4834
0
          }
4835
0
        }
4836
0
        if (valid) {
4837
0
          search_state->single_rd_order[dir][mode][count++] = ref_frame;
4838
0
        }
4839
0
      }
4840
0
    }
4841
0
  }
4842
0
}
4843
4844
static int compound_skip_get_candidates(
4845
    const AV1_COMP *cpi, const InterModeSearchState *search_state,
4846
0
    const int dir, const PREDICTION_MODE mode) {
4847
0
  const int mode_offset = INTER_OFFSET(mode);
4848
0
  const SingleInterModeState *state =
4849
0
      search_state->single_state[dir][mode_offset];
4850
0
  const SingleInterModeState *state_modelled =
4851
0
      search_state->single_state_modelled[dir][mode_offset];
4852
4853
0
  int max_candidates = 0;
4854
0
  for (int i = 0; i < FWD_REFS; ++i) {
4855
0
    if (search_state->single_rd_order[dir][mode_offset][i] == NONE_FRAME) break;
4856
0
    max_candidates++;
4857
0
  }
4858
4859
0
  int candidates = max_candidates;
4860
0
  if (cpi->sf.inter_sf.prune_comp_search_by_single_result >= 2) {
4861
0
    candidates = AOMMIN(2, max_candidates);
4862
0
  }
4863
0
  if (cpi->sf.inter_sf.prune_comp_search_by_single_result >= 3) {
4864
0
    if (state[0].rd != INT64_MAX && state_modelled[0].rd != INT64_MAX &&
4865
0
        state[0].ref_frame == state_modelled[0].ref_frame)
4866
0
      candidates = 1;
4867
0
    if (mode == NEARMV || mode == GLOBALMV) candidates = 1;
4868
0
  }
4869
4870
0
  if (cpi->sf.inter_sf.prune_comp_search_by_single_result >= 4) {
4871
    // Limit the number of candidates to 1 in each direction for compound
4872
    // prediction
4873
0
    candidates = AOMMIN(1, candidates);
4874
0
  }
4875
0
  return candidates;
4876
0
}
4877
4878
static AOM_FORCE_INLINE int compound_skip_by_single_states(
4879
    const AV1_COMP *cpi, const InterModeSearchState *search_state,
4880
    const PREDICTION_MODE this_mode, const MV_REFERENCE_FRAME ref_frame,
4881
0
    const MV_REFERENCE_FRAME second_ref_frame, const MACROBLOCK *x) {
4882
0
  const MV_REFERENCE_FRAME refs[2] = { ref_frame, second_ref_frame };
4883
0
  const int mode[2] = { compound_ref0_mode(this_mode),
4884
0
                        compound_ref1_mode(this_mode) };
4885
0
  const int mode_offset[2] = { INTER_OFFSET(mode[0]), INTER_OFFSET(mode[1]) };
4886
0
  const int mode_dir[2] = { refs[0] <= GOLDEN_FRAME ? 0 : 1,
4887
0
                            refs[1] <= GOLDEN_FRAME ? 0 : 1 };
4888
0
  int ref_searched[2] = { 0, 0 };
4889
0
  int ref_mv_match[2] = { 1, 1 };
4890
0
  int i, j;
4891
4892
0
  for (i = 0; i < 2; ++i) {
4893
0
    const SingleInterModeState *state =
4894
0
        search_state->single_state[mode_dir[i]][mode_offset[i]];
4895
0
    const int state_cnt =
4896
0
        search_state->single_state_cnt[mode_dir[i]][mode_offset[i]];
4897
0
    for (j = 0; j < state_cnt; ++j) {
4898
0
      if (state[j].ref_frame == refs[i]) {
4899
0
        ref_searched[i] = 1;
4900
0
        break;
4901
0
      }
4902
0
    }
4903
0
  }
4904
4905
0
  const int ref_set = get_drl_refmv_count(x, refs, this_mode);
4906
0
  for (i = 0; i < 2; ++i) {
4907
0
    if (!ref_searched[i] || (mode[i] != NEARESTMV && mode[i] != NEARMV)) {
4908
0
      continue;
4909
0
    }
4910
0
    const MV_REFERENCE_FRAME single_refs[2] = { refs[i], NONE_FRAME };
4911
0
    for (int ref_mv_idx = 0; ref_mv_idx < ref_set; ref_mv_idx++) {
4912
0
      int_mv single_mv;
4913
0
      int_mv comp_mv;
4914
0
      get_this_mv(&single_mv, mode[i], 0, ref_mv_idx, 0, single_refs,
4915
0
                  &x->mbmi_ext);
4916
0
      get_this_mv(&comp_mv, this_mode, i, ref_mv_idx, 0, refs, &x->mbmi_ext);
4917
0
      if (single_mv.as_int != comp_mv.as_int) {
4918
0
        ref_mv_match[i] = 0;
4919
0
        break;
4920
0
      }
4921
0
    }
4922
0
  }
4923
4924
0
  for (i = 0; i < 2; ++i) {
4925
0
    if (!ref_searched[i] || !ref_mv_match[i]) continue;
4926
0
    const int candidates =
4927
0
        compound_skip_get_candidates(cpi, search_state, mode_dir[i], mode[i]);
4928
0
    const MV_REFERENCE_FRAME *ref_order =
4929
0
        search_state->single_rd_order[mode_dir[i]][mode_offset[i]];
4930
0
    int match = 0;
4931
0
    for (j = 0; j < candidates; ++j) {
4932
0
      if (refs[i] == ref_order[j]) {
4933
0
        match = 1;
4934
0
        break;
4935
0
      }
4936
0
    }
4937
0
    if (!match) return 1;
4938
0
  }
4939
4940
0
  return 0;
4941
0
}
4942
4943
// Check if ref frames of current block matches with given block.
4944
static inline void match_ref_frame(const MB_MODE_INFO *const mbmi,
4945
                                   const MV_REFERENCE_FRAME *ref_frames,
4946
0
                                   int *const is_ref_match) {
4947
0
  if (is_inter_block(mbmi)) {
4948
0
    is_ref_match[0] |= ref_frames[0] == mbmi->ref_frame[0];
4949
0
    is_ref_match[1] |= ref_frames[1] == mbmi->ref_frame[0];
4950
0
    if (has_second_ref(mbmi)) {
4951
0
      is_ref_match[0] |= ref_frames[0] == mbmi->ref_frame[1];
4952
0
      is_ref_match[1] |= ref_frames[1] == mbmi->ref_frame[1];
4953
0
    }
4954
0
  }
4955
0
}
4956
4957
// Prune compound mode using ref frames of neighbor blocks.
4958
static inline int compound_skip_using_neighbor_refs(
4959
    MACROBLOCKD *const xd, const PREDICTION_MODE this_mode,
4960
749k
    const MV_REFERENCE_FRAME *ref_frames, int prune_ext_comp_using_neighbors) {
4961
  // Exclude non-extended compound modes from pruning
4962
749k
  if (this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
4963
538k
      this_mode == NEW_NEWMV || this_mode == GLOBAL_GLOBALMV)
4964
480k
    return 0;
4965
4966
269k
  if (prune_ext_comp_using_neighbors >= 3) return 1;
4967
4968
18.4E
  int is_ref_match[2] = { 0 };  // 0 - match for forward refs
4969
                                // 1 - match for backward refs
4970
  // Check if ref frames of this block matches with left neighbor.
4971
18.4E
  if (xd->left_available)
4972
0
    match_ref_frame(xd->left_mbmi, ref_frames, is_ref_match);
4973
4974
  // Check if ref frames of this block matches with above neighbor.
4975
18.4E
  if (xd->up_available)
4976
0
    match_ref_frame(xd->above_mbmi, ref_frames, is_ref_match);
4977
4978
  // Combine ref frame match with neighbors in forward and backward refs.
4979
18.4E
  const int track_ref_match = is_ref_match[0] + is_ref_match[1];
4980
4981
  // Pruning based on ref frame match with neighbors.
4982
18.4E
  if (track_ref_match >= prune_ext_comp_using_neighbors) return 0;
4983
18.4E
  return 1;
4984
18.4E
}
4985
4986
// Update best single mode for the given reference frame based on simple rd.
4987
static inline void update_best_single_mode(InterModeSearchState *search_state,
4988
                                           const PREDICTION_MODE this_mode,
4989
                                           const MV_REFERENCE_FRAME ref_frame,
4990
4.38M
                                           int64_t this_rd) {
4991
4.38M
  if (this_rd < search_state->best_single_rd[ref_frame]) {
4992
1.76M
    search_state->best_single_rd[ref_frame] = this_rd;
4993
1.76M
    search_state->best_single_mode[ref_frame] = this_mode;
4994
1.76M
  }
4995
4.38M
}
4996
4997
// Prune compound mode using best single mode for the same reference.
4998
static inline int skip_compound_using_best_single_mode_ref(
4999
    const PREDICTION_MODE this_mode, const MV_REFERENCE_FRAME *ref_frames,
5000
    const PREDICTION_MODE *best_single_mode,
5001
480k
    int prune_comp_using_best_single_mode_ref) {
5002
  // Exclude non-extended compound modes from pruning
5003
480k
  if (this_mode == NEAREST_NEARESTMV || this_mode == NEAR_NEARMV ||
5004
268k
      this_mode == NEW_NEWMV || this_mode == GLOBAL_GLOBALMV)
5005
480k
    return 0;
5006
5007
480k
  assert(this_mode >= NEAREST_NEWMV && this_mode <= NEW_NEARMV);
5008
8
  const PREDICTION_MODE comp_mode_ref0 = compound_ref0_mode(this_mode);
5009
  // Get ref frame direction corresponding to NEWMV
5010
  // 0 - NEWMV corresponding to forward direction
5011
  // 1 - NEWMV corresponding to backward direction
5012
8
  const int newmv_dir = comp_mode_ref0 != NEWMV;
5013
5014
  // Avoid pruning the compound mode when ref frame corresponding to NEWMV
5015
  // have NEWMV as single mode winner.
5016
  // Example: For an extended-compound mode,
5017
  // {mode, {fwd_frame, bwd_frame}} = {NEAR_NEWMV, {LAST_FRAME, ALTREF_FRAME}}
5018
  // - Ref frame corresponding to NEWMV is ALTREF_FRAME
5019
  // - Avoid pruning this mode, if best single mode corresponding to ref frame
5020
  //   ALTREF_FRAME is NEWMV
5021
8
  const PREDICTION_MODE single_mode = best_single_mode[ref_frames[newmv_dir]];
5022
8
  if (single_mode == NEWMV) return 0;
5023
5024
  // Avoid pruning the compound mode when best single mode is not available
5025
8
  if (prune_comp_using_best_single_mode_ref == 1)
5026
0
    if (single_mode == MB_MODE_COUNT) return 0;
5027
8
  return 1;
5028
8
}
5029
5030
1.35M
static int compare_int64(const void *a, const void *b) {
5031
1.35M
  int64_t a64 = *((int64_t *)a);
5032
1.35M
  int64_t b64 = *((int64_t *)b);
5033
1.35M
  if (a64 < b64) {
5034
324k
    return -1;
5035
1.02M
  } else if (a64 == b64) {
5036
814k
    return 0;
5037
814k
  } else {
5038
212k
    return 1;
5039
212k
  }
5040
1.35M
}
5041
5042
static inline void update_search_state(
5043
    const AV1_COMP *cpi, InterModeSearchState *search_state,
5044
    RD_STATS *best_rd_stats_dst, PICK_MODE_CONTEXT *ctx,
5045
    const RD_STATS *new_best_rd_stats, const RD_STATS *new_best_rd_stats_y,
5046
    const RD_STATS *new_best_rd_stats_uv, THR_MODES new_best_mode,
5047
2.49M
    const MACROBLOCK *x, int txfm_search_done) {
5048
2.49M
  const MACROBLOCKD *xd = &x->e_mbd;
5049
2.49M
  const MB_MODE_INFO *mbmi = xd->mi[0];
5050
2.49M
  const int skip_ctx = av1_get_skip_txfm_context(xd);
5051
2.49M
  const int skip_txfm =
5052
2.49M
      mbmi->skip_txfm && !is_mode_intra(av1_mode_defs[new_best_mode].mode);
5053
5054
2.49M
  search_state->best_rd = new_best_rd_stats->rdcost;
5055
2.49M
  search_state->best_mode_index = new_best_mode;
5056
2.49M
  *best_rd_stats_dst = *new_best_rd_stats;
5057
2.49M
  search_state->best_mbmode = *mbmi;
5058
2.49M
  search_state->best_skip2 = skip_txfm;
5059
2.49M
  search_state->best_mode_skippable = new_best_rd_stats->skip_txfm;
5060
  // When !txfm_search_done, new_best_rd_stats won't provide correct rate_y and
5061
  // rate_uv because av1_txfm_search process is replaced by rd estimation.
5062
  // Therefore, we should avoid updating best_rate_y and best_rate_uv here.
5063
  // These two values will be updated when av1_txfm_search is called.
5064
2.49M
  if (txfm_search_done) {
5065
2.40M
    const int32_t skip_rate =
5066
2.40M
        x->mode_costs.skip_txfm_cost[skip_ctx]
5067
2.40M
                                    [new_best_rd_stats->skip_txfm || skip_txfm];
5068
2.40M
    const int32_t scaled_skip_rate =
5069
2.40M
        increase_motion_mode_rate(cpi, mbmi, skip_rate);
5070
2.40M
    search_state->best_rate_y = new_best_rd_stats_y->rate + scaled_skip_rate;
5071
2.40M
    search_state->best_rate_uv = new_best_rd_stats_uv->rate;
5072
2.40M
  }
5073
2.49M
  search_state->best_y_rdcost = *new_best_rd_stats_y;
5074
2.49M
  av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
5075
2.49M
}
5076
5077
// Find the best RD for a reference frame (among single reference modes)
5078
// and store +10% of it in the 0-th element in ref_frame_rd.
5079
136k
static inline void find_top_ref(int64_t ref_frame_rd[REF_FRAMES]) {
5080
136k
  assert(ref_frame_rd[0] == INT64_MAX);
5081
136k
  int64_t ref_copy[REF_FRAMES - 1];
5082
136k
  memcpy(ref_copy, ref_frame_rd + 1,
5083
136k
         sizeof(ref_frame_rd[0]) * (REF_FRAMES - 1));
5084
136k
  qsort(ref_copy, REF_FRAMES - 1, sizeof(int64_t), compare_int64);
5085
5086
136k
  int64_t cutoff = ref_copy[0];
5087
  // The cut-off is within 10% of the best.
5088
136k
  if (cutoff != INT64_MAX) {
5089
134k
    assert(cutoff < INT64_MAX / 200);
5090
134k
    cutoff = (110 * cutoff) / 100;
5091
134k
  }
5092
136k
  ref_frame_rd[0] = cutoff;
5093
136k
}
5094
5095
// Check if either frame is within the cutoff.
5096
static inline bool in_single_ref_cutoff(int64_t ref_frame_rd[REF_FRAMES],
5097
                                        MV_REFERENCE_FRAME frame1,
5098
1.03M
                                        MV_REFERENCE_FRAME frame2) {
5099
1.03M
  assert(frame2 > 0);
5100
1.03M
  return ref_frame_rd[frame1] <= ref_frame_rd[0] ||
5101
128k
         ref_frame_rd[frame2] <= ref_frame_rd[0];
5102
1.03M
}
5103
5104
static inline void evaluate_motion_mode_for_winner_candidates(
5105
    const AV1_COMP *const cpi, MACROBLOCK *const x, RD_STATS *const rd_cost,
5106
    HandleInterModeArgs *const args, TileDataEnc *const tile_data,
5107
    PICK_MODE_CONTEXT *const ctx,
5108
    struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE],
5109
    const motion_mode_best_st_candidate *const best_motion_mode_cands,
5110
    int do_tx_search, const BLOCK_SIZE bsize, int64_t *const best_est_rd,
5111
834k
    InterModeSearchState *const search_state, int64_t *yrd) {
5112
834k
  const AV1_COMMON *const cm = &cpi->common;
5113
834k
  const int num_planes = av1_num_planes(cm);
5114
834k
  MACROBLOCKD *const xd = &x->e_mbd;
5115
834k
  MB_MODE_INFO *const mbmi = xd->mi[0];
5116
834k
  InterModesInfo *const inter_modes_info = x->inter_modes_info;
5117
834k
  const int num_best_cand = best_motion_mode_cands->num_motion_mode_cand;
5118
5119
2.46M
  for (int cand = 0; cand < num_best_cand; cand++) {
5120
1.63M
    RD_STATS rd_stats;
5121
1.63M
    RD_STATS rd_stats_y;
5122
1.63M
    RD_STATS rd_stats_uv;
5123
1.63M
    av1_init_rd_stats(&rd_stats);
5124
1.63M
    av1_init_rd_stats(&rd_stats_y);
5125
1.63M
    av1_init_rd_stats(&rd_stats_uv);
5126
1.63M
    int rate_mv;
5127
5128
1.63M
    rate_mv = best_motion_mode_cands->motion_mode_cand[cand].rate_mv;
5129
1.63M
    args->skip_motion_mode =
5130
1.63M
        best_motion_mode_cands->motion_mode_cand[cand].skip_motion_mode;
5131
1.63M
    *mbmi = best_motion_mode_cands->motion_mode_cand[cand].mbmi;
5132
1.63M
    rd_stats.rate =
5133
1.63M
        best_motion_mode_cands->motion_mode_cand[cand].rate2_nocoeff;
5134
5135
    // Continue if the best candidate is compound.
5136
1.63M
    if (!is_inter_singleref_mode(mbmi->mode)) continue;
5137
5138
1.58M
    x->txfm_search_info.skip_txfm = 0;
5139
1.58M
    struct macroblockd_plane *pd = xd->plane;
5140
1.58M
    const BUFFER_SET orig_dst = {
5141
1.58M
      { pd[0].dst.buf, pd[1].dst.buf, pd[2].dst.buf },
5142
1.58M
      { pd[0].dst.stride, pd[1].dst.stride, pd[2].dst.stride },
5143
1.58M
    };
5144
5145
1.58M
    set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5146
    // Initialize motion mode to simple translation
5147
    // Calculation of switchable rate depends on it.
5148
1.58M
    mbmi->motion_mode = 0;
5149
1.58M
    const int is_comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
5150
4.46M
    for (int i = 0; i < num_planes; i++) {
5151
2.88M
      xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
5152
2.88M
      if (is_comp_pred) xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
5153
2.88M
    }
5154
5155
1.58M
    int64_t skip_rd[2] = { search_state->best_skip_rd[0],
5156
1.58M
                           search_state->best_skip_rd[1] };
5157
1.58M
    int64_t this_yrd = INT64_MAX;
5158
1.58M
    int64_t ret_value = motion_mode_rd(
5159
1.58M
        cpi, tile_data, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, args,
5160
1.58M
        search_state->best_rd, skip_rd, &rate_mv, &orig_dst, best_est_rd,
5161
1.58M
        do_tx_search, inter_modes_info, 1, &this_yrd);
5162
5163
1.58M
    if (ret_value != INT64_MAX) {
5164
113k
      rd_stats.rdcost = RDCOST(x->rdmult, rd_stats.rate, rd_stats.dist);
5165
113k
      const THR_MODES mode_enum = get_prediction_mode_idx(
5166
113k
          mbmi->mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5167
      // Collect mode stats for multiwinner mode processing
5168
113k
      store_winner_mode_stats(
5169
113k
          cpi, x, mbmi, &rd_stats, &rd_stats_y, &rd_stats_uv, mode_enum, NULL,
5170
113k
          bsize, rd_stats.rdcost, cpi->sf.winner_mode_sf.multi_winner_mode_type,
5171
113k
          do_tx_search);
5172
5173
113k
      if (rd_stats.rdcost < search_state->best_rd) {
5174
102k
        *yrd = this_yrd;
5175
102k
        update_search_state(cpi, search_state, rd_cost, ctx, &rd_stats,
5176
102k
                            &rd_stats_y, &rd_stats_uv, mode_enum, x,
5177
102k
                            do_tx_search);
5178
102k
        if (do_tx_search) search_state->best_skip_rd[0] = skip_rd[0];
5179
102k
      }
5180
113k
    }
5181
1.58M
  }
5182
834k
}
5183
5184
/*!\cond */
5185
// Arguments for speed feature pruning of inter mode search
5186
typedef struct {
5187
  int *skip_motion_mode;
5188
  mode_skip_mask_t *mode_skip_mask;
5189
  InterModeSearchState *search_state;
5190
  int skip_ref_frame_mask;
5191
  int reach_first_comp_mode;
5192
  int mode_thresh_mul_fact;
5193
  int num_single_modes_processed;
5194
  int prune_cpd_using_sr_stats_ready;
5195
} InterModeSFArgs;
5196
/*!\endcond */
5197
5198
static AOM_FORCE_INLINE int skip_inter_mode(AV1_COMP *cpi, MACROBLOCK *x,
5199
                                            const BLOCK_SIZE bsize,
5200
                                            int64_t *ref_frame_rd, int midx,
5201
                                            InterModeSFArgs *args,
5202
140M
                                            int is_low_temp_var) {
5203
140M
  const SPEED_FEATURES *const sf = &cpi->sf;
5204
140M
  MACROBLOCKD *const xd = &x->e_mbd;
5205
  // Get the actual prediction mode we are trying in this iteration
5206
140M
  const THR_MODES mode_enum = av1_default_mode_order[midx];
5207
140M
  const MODE_DEFINITION *mode_def = &av1_mode_defs[mode_enum];
5208
140M
  const PREDICTION_MODE this_mode = mode_def->mode;
5209
140M
  const MV_REFERENCE_FRAME *ref_frames = mode_def->ref_frame;
5210
140M
  const MV_REFERENCE_FRAME ref_frame = ref_frames[0];
5211
140M
  const MV_REFERENCE_FRAME second_ref_frame = ref_frames[1];
5212
140M
  const int comp_pred = second_ref_frame > INTRA_FRAME;
5213
5214
140M
  if (ref_frame == INTRA_FRAME) return 1;
5215
5216
140M
  const FRAME_UPDATE_TYPE update_type =
5217
140M
      get_frame_update_type(&cpi->ppi->gf_group, cpi->gf_frame_index);
5218
140M
  if (sf->inter_sf.skip_arf_compound && update_type == ARF_UPDATE &&
5219
10.7M
      comp_pred) {
5220
8.84M
    return 1;
5221
8.84M
  }
5222
5223
  // This is for real time encoding.
5224
131M
  if (is_low_temp_var && !comp_pred && ref_frame != LAST_FRAME &&
5225
0
      this_mode != NEARESTMV)
5226
0
    return 1;
5227
5228
  // Check if this mode should be skipped because it is incompatible with the
5229
  // current frame
5230
131M
  if (inter_mode_compatible_skip(cpi, x, bsize, this_mode, ref_frames))
5231
83.7M
    return 1;
5232
47.8M
  const int ret = inter_mode_search_order_independent_skip(
5233
47.8M
      cpi, x, args->mode_skip_mask, args->search_state,
5234
47.8M
      args->skip_ref_frame_mask, this_mode, mode_def->ref_frame);
5235
47.8M
  if (ret == 1) return 1;
5236
5.46M
  *(args->skip_motion_mode) = (ret == 2);
5237
5238
  // We've reached the first compound prediction mode, get stats from the
5239
  // single reference predictors to help with pruning.
5240
  // Disable this pruning logic if interpolation filter search was skipped for
5241
  // single prediction modes as it can result in aggressive pruning of compound
5242
  // prediction modes due to the absence of modelled_rd populated by
5243
  // av1_interpolation_filter_search().
5244
  // TODO(Remya): Check the impact of the sf
5245
  // 'prune_comp_search_by_single_result' if compound prediction modes are
5246
  // enabled in future for REALTIME encode.
5247
5.46M
  if (!sf->interp_sf.skip_interp_filter_search &&
5248
194k
      sf->inter_sf.prune_comp_search_by_single_result > 0 && comp_pred &&
5249
0
      args->reach_first_comp_mode == 0) {
5250
0
    analyze_single_states(cpi, args->search_state);
5251
0
    args->reach_first_comp_mode = 1;
5252
0
  }
5253
5254
  // Prune aggressively when best mode is skippable.
5255
5.46M
  int mul_fact = args->search_state->best_mode_skippable
5256
5.46M
                     ? args->mode_thresh_mul_fact
5257
5.46M
                     : (1 << MODE_THRESH_QBITS);
5258
5.46M
  int64_t mode_threshold =
5259
5.46M
      (args->search_state->mode_threshold[mode_enum] * mul_fact) >>
5260
5.46M
      MODE_THRESH_QBITS;
5261
5262
5.46M
  if (args->search_state->best_rd < mode_threshold) return 1;
5263
5264
  // Skip this compound mode based on the RD results from the single prediction
5265
  // modes
5266
5.42M
  if (!sf->interp_sf.skip_interp_filter_search &&
5267
193k
      sf->inter_sf.prune_comp_search_by_single_result > 0 && comp_pred) {
5268
0
    if (compound_skip_by_single_states(cpi, args->search_state, this_mode,
5269
0
                                       ref_frame, second_ref_frame, x))
5270
0
      return 1;
5271
0
  }
5272
5273
5.62M
  if (sf->inter_sf.prune_compound_using_single_ref && comp_pred) {
5274
    // After we done with single reference modes, find the 2nd best RD
5275
    // for a reference frame. Only search compound modes that have a reference
5276
    // frame at least as good as the 2nd best.
5277
1.03M
    if (!args->prune_cpd_using_sr_stats_ready &&
5278
136k
        args->num_single_modes_processed == NUM_SINGLE_REF_MODES) {
5279
136k
      find_top_ref(ref_frame_rd);
5280
136k
      args->prune_cpd_using_sr_stats_ready = 1;
5281
136k
    }
5282
1.03M
    if (args->prune_cpd_using_sr_stats_ready &&
5283
1.03M
        !in_single_ref_cutoff(ref_frame_rd, ref_frame, second_ref_frame))
5284
14.3k
      return 1;
5285
1.03M
  }
5286
5287
  // Skip NEW_NEARMV and NEAR_NEWMV extended compound modes
5288
5.40M
  if (sf->inter_sf.skip_ext_comp_nearmv_mode &&
5289
5.60M
      (this_mode == NEW_NEARMV || this_mode == NEAR_NEWMV)) {
5290
269k
    return 1;
5291
269k
  }
5292
5293
5.33M
  if (sf->inter_sf.prune_ext_comp_using_neighbors && comp_pred) {
5294
749k
    if (compound_skip_using_neighbor_refs(
5295
749k
            xd, this_mode, ref_frames,
5296
749k
            sf->inter_sf.prune_ext_comp_using_neighbors))
5297
269k
      return 1;
5298
749k
  }
5299
5300
5.06M
  if (sf->inter_sf.prune_comp_using_best_single_mode_ref && comp_pred) {
5301
480k
    if (skip_compound_using_best_single_mode_ref(
5302
480k
            this_mode, ref_frames, args->search_state->best_single_mode,
5303
480k
            sf->inter_sf.prune_comp_using_best_single_mode_ref))
5304
0
      return 1;
5305
480k
  }
5306
5307
4.87M
  if (sf->inter_sf.prune_nearest_near_mv_using_refmv_weight && !comp_pred) {
5308
4.39M
    const int8_t ref_frame_type = av1_ref_frame_type(ref_frames);
5309
4.39M
    if (skip_nearest_near_mv_using_refmv_weight(
5310
4.39M
            x, this_mode, ref_frame_type,
5311
4.39M
            args->search_state->best_mbmode.mode)) {
5312
      // Ensure the mode is pruned only when the current block has obtained a
5313
      // valid inter mode.
5314
205k
      assert(is_inter_mode(args->search_state->best_mbmode.mode));
5315
205k
      return 1;
5316
205k
    }
5317
4.39M
  }
5318
5319
4.66M
  if (sf->rt_sf.prune_inter_modes_with_golden_ref &&
5320
0
      ref_frame == GOLDEN_FRAME && !comp_pred) {
5321
0
    const int subgop_size = AOMMIN(cpi->ppi->gf_group.size, FIXED_GF_INTERVAL);
5322
0
    if (cpi->rc.frames_since_golden > (subgop_size >> 2) &&
5323
0
        args->search_state->best_mbmode.ref_frame[0] != GOLDEN_FRAME) {
5324
0
      if ((bsize > BLOCK_16X16 && this_mode == NEWMV) || this_mode == NEARMV)
5325
0
        return 1;
5326
0
    }
5327
0
  }
5328
5329
4.66M
  return 0;
5330
4.66M
}
5331
5332
static void record_best_compound(REFERENCE_MODE reference_mode,
5333
                                 RD_STATS *rd_stats, int comp_pred, int rdmult,
5334
                                 InterModeSearchState *search_state,
5335
1.84M
                                 int compmode_cost) {
5336
1.84M
  int64_t single_rd, hybrid_rd, single_rate, hybrid_rate;
5337
5338
1.84M
  if (reference_mode == REFERENCE_MODE_SELECT) {
5339
1.84M
    single_rate = rd_stats->rate - compmode_cost;
5340
1.84M
    hybrid_rate = rd_stats->rate;
5341
1.84M
  } else {
5342
39
    single_rate = rd_stats->rate;
5343
39
    hybrid_rate = rd_stats->rate + compmode_cost;
5344
39
  }
5345
5346
1.84M
  single_rd = RDCOST(rdmult, single_rate, rd_stats->dist);
5347
1.84M
  hybrid_rd = RDCOST(rdmult, hybrid_rate, rd_stats->dist);
5348
5349
1.84M
  if (!comp_pred) {
5350
1.79M
    if (single_rd < search_state->best_pred_rd[SINGLE_REFERENCE])
5351
1.74M
      search_state->best_pred_rd[SINGLE_REFERENCE] = single_rd;
5352
1.79M
  } else {
5353
53.0k
    if (single_rd < search_state->best_pred_rd[COMPOUND_REFERENCE])
5354
52.3k
      search_state->best_pred_rd[COMPOUND_REFERENCE] = single_rd;
5355
53.0k
  }
5356
1.84M
  if (hybrid_rd < search_state->best_pred_rd[REFERENCE_MODE_SELECT])
5357
1.79M
    search_state->best_pred_rd[REFERENCE_MODE_SELECT] = hybrid_rd;
5358
1.84M
}
5359
5360
// Does a transform search over a list of the best inter mode candidates.
5361
// This is called if the original mode search computed an RD estimate
5362
// for the transform search rather than doing a full search.
5363
static void tx_search_best_inter_candidates(
5364
    AV1_COMP *cpi, TileDataEnc *tile_data, MACROBLOCK *x,
5365
    int64_t best_rd_so_far, BLOCK_SIZE bsize,
5366
    struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE], int mi_row, int mi_col,
5367
    InterModeSearchState *search_state, RD_STATS *rd_cost,
5368
37.4k
    PICK_MODE_CONTEXT *ctx, int64_t *yrd) {
5369
37.4k
  AV1_COMMON *const cm = &cpi->common;
5370
37.4k
  MACROBLOCKD *const xd = &x->e_mbd;
5371
37.4k
  TxfmSearchInfo *txfm_info = &x->txfm_search_info;
5372
37.4k
  const ModeCosts *mode_costs = &x->mode_costs;
5373
37.4k
  const int num_planes = av1_num_planes(cm);
5374
37.4k
  const int skip_ctx = av1_get_skip_txfm_context(xd);
5375
37.4k
  MB_MODE_INFO *const mbmi = xd->mi[0];
5376
37.4k
  InterModesInfo *inter_modes_info = x->inter_modes_info;
5377
37.4k
  inter_modes_info_sort(inter_modes_info, inter_modes_info->rd_idx_pair_arr);
5378
37.4k
  search_state->best_rd = best_rd_so_far;
5379
37.4k
  search_state->best_mode_index = THR_INVALID;
5380
  // Initialize best mode stats for winner mode processing
5381
37.4k
  x->winner_mode_count = 0;
5382
37.4k
  store_winner_mode_stats(cpi, x, mbmi, NULL, NULL, NULL, THR_INVALID, NULL,
5383
37.4k
                          bsize, best_rd_so_far,
5384
37.4k
                          cpi->sf.winner_mode_sf.multi_winner_mode_type, 0);
5385
37.4k
  inter_modes_info->num =
5386
37.4k
      inter_modes_info->num < cpi->sf.rt_sf.num_inter_modes_for_tx_search
5387
37.4k
          ? inter_modes_info->num
5388
37.4k
          : cpi->sf.rt_sf.num_inter_modes_for_tx_search;
5389
37.4k
  const int64_t top_est_rd =
5390
37.4k
      inter_modes_info->num > 0
5391
37.4k
          ? inter_modes_info
5392
37.4k
                ->est_rd_arr[inter_modes_info->rd_idx_pair_arr[0].idx]
5393
37.4k
          : INT64_MAX;
5394
37.4k
  *yrd = INT64_MAX;
5395
37.4k
  int64_t best_rd_in_this_partition = INT64_MAX;
5396
37.4k
  int num_inter_mode_cands = inter_modes_info->num;
5397
37.4k
  int newmv_mode_evaled = 0;
5398
37.4k
  int max_allowed_cands = INT_MAX;
5399
37.4k
  if (cpi->sf.inter_sf.limit_inter_mode_cands) {
5400
    // The bound on the no. of inter mode candidates, beyond which the
5401
    // candidates are limited if a newmv mode got evaluated, is set as
5402
    // max_allowed_cands + 1.
5403
33.4k
    const int num_allowed_cands[5] = { INT_MAX, 10, 9, 6, 2 };
5404
33.4k
    assert(cpi->sf.inter_sf.limit_inter_mode_cands <= 4);
5405
33.4k
    max_allowed_cands =
5406
33.4k
        num_allowed_cands[cpi->sf.inter_sf.limit_inter_mode_cands];
5407
33.4k
  }
5408
5409
37.4k
  int num_mode_thresh = INT_MAX;
5410
37.4k
  if (cpi->sf.inter_sf.limit_txfm_eval_per_mode) {
5411
    // Bound the no. of transform searches per prediction mode beyond a
5412
    // threshold.
5413
35.4k
    const int num_mode_thresh_ary[4] = { INT_MAX, 4, 3, 0 };
5414
35.4k
    assert(cpi->sf.inter_sf.limit_txfm_eval_per_mode <= 3);
5415
35.4k
    num_mode_thresh =
5416
35.4k
        num_mode_thresh_ary[cpi->sf.inter_sf.limit_txfm_eval_per_mode];
5417
35.4k
  }
5418
5419
37.4k
  int num_tx_cands = 0;
5420
37.4k
  int num_tx_search_modes[INTER_MODE_END - INTER_MODE_START] = { 0 };
5421
  // Iterate over best inter mode candidates and perform tx search
5422
178k
  for (int j = 0; j < num_inter_mode_cands; ++j) {
5423
141k
    const int data_idx = inter_modes_info->rd_idx_pair_arr[j].idx;
5424
141k
    *mbmi = inter_modes_info->mbmi_arr[data_idx];
5425
141k
    const PREDICTION_MODE prediction_mode = mbmi->mode;
5426
141k
    int64_t curr_est_rd = inter_modes_info->est_rd_arr[data_idx];
5427
141k
    if (curr_est_rd * 0.80 > top_est_rd) break;
5428
5429
140k
    if (num_tx_cands > num_mode_thresh) {
5430
19.1k
      if ((prediction_mode != NEARESTMV &&
5431
10.7k
           num_tx_search_modes[prediction_mode - INTER_MODE_START] >= 1) ||
5432
11.4k
          (prediction_mode == NEARESTMV &&
5433
8.35k
           num_tx_search_modes[prediction_mode - INTER_MODE_START] >= 2))
5434
9.07k
        continue;
5435
19.1k
    }
5436
5437
131k
    txfm_info->skip_txfm = 0;
5438
131k
    set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5439
5440
    // Select prediction reference frames.
5441
131k
    const int is_comp_pred = mbmi->ref_frame[1] > INTRA_FRAME;
5442
371k
    for (int i = 0; i < num_planes; i++) {
5443
239k
      xd->plane[i].pre[0] = yv12_mb[mbmi->ref_frame[0]][i];
5444
239k
      if (is_comp_pred) xd->plane[i].pre[1] = yv12_mb[mbmi->ref_frame[1]][i];
5445
239k
    }
5446
5447
131k
    bool is_predictor_built = false;
5448
5449
    // Initialize RD stats
5450
131k
    RD_STATS rd_stats;
5451
131k
    RD_STATS rd_stats_y;
5452
131k
    RD_STATS rd_stats_uv;
5453
131k
    const int mode_rate = inter_modes_info->mode_rate_arr[data_idx];
5454
131k
    int64_t skip_rd = INT64_MAX;
5455
131k
    const int txfm_rd_gate_level = get_txfm_rd_gate_level(
5456
131k
        cm->seq_params->enable_masked_compound,
5457
131k
        cpi->sf.inter_sf.txfm_rd_gate_level, bsize, TX_SEARCH_DEFAULT,
5458
131k
        /*eval_motion_mode=*/0);
5459
131k
    if (txfm_rd_gate_level) {
5460
      // Check if the mode is good enough based on skip RD
5461
126k
      int64_t curr_sse = inter_modes_info->sse_arr[data_idx];
5462
126k
      skip_rd = RDCOST(x->rdmult, mode_rate, curr_sse);
5463
126k
      int eval_txfm = check_txfm_eval(x, bsize, search_state->best_skip_rd[0],
5464
126k
                                      skip_rd, txfm_rd_gate_level, 0);
5465
126k
      if (!eval_txfm) continue;
5466
126k
    }
5467
5468
    // Build the prediction for this mode
5469
101k
    if (!is_predictor_built) {
5470
101k
      av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize, 0,
5471
101k
                                    av1_num_planes(cm) - 1);
5472
101k
    }
5473
101k
    if (mbmi->motion_mode == OBMC_CAUSAL) {
5474
0
      av1_build_obmc_inter_predictors_sb(cm, xd);
5475
0
    }
5476
5477
101k
    num_tx_cands++;
5478
101k
    if (have_newmv_in_inter_mode(prediction_mode)) newmv_mode_evaled = 1;
5479
101k
    num_tx_search_modes[prediction_mode - INTER_MODE_START]++;
5480
101k
    int64_t this_yrd = INT64_MAX;
5481
    // Do the transform search
5482
101k
    if (!av1_txfm_search(cpi, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv,
5483
101k
                         mode_rate, search_state->best_rd)) {
5484
56.0k
      continue;
5485
56.0k
    } else {
5486
45.4k
      if (cpi->sf.inter_sf.inter_mode_rd_model_estimation == 1) {
5487
32.2k
        inter_mode_data_push(
5488
32.2k
            tile_data, mbmi->bsize, rd_stats.sse, rd_stats.dist,
5489
32.2k
            rd_stats_y.rate + rd_stats_uv.rate +
5490
32.2k
                mode_costs->skip_txfm_cost[skip_ctx][mbmi->skip_txfm]);
5491
32.2k
      }
5492
45.4k
      increase_motion_mode_rdstats(cpi, mbmi, &rd_stats, &rd_stats_y,
5493
45.4k
                                   &rd_stats_uv);
5494
45.4k
      const int *skip_txfm_cost_ptr = mode_costs->skip_txfm_cost[skip_ctx];
5495
45.4k
      const int skip_rate =
5496
45.4k
          rd_stats.skip_txfm ? skip_txfm_cost_ptr[1] : skip_txfm_cost_ptr[0];
5497
45.4k
      const int32_t scaled_skip_rate =
5498
45.4k
          increase_motion_mode_rate(cpi, mbmi, skip_rate);
5499
45.4k
      const int y_rate =
5500
45.4k
          scaled_skip_rate + (rd_stats.skip_txfm ? 0 : rd_stats_y.rate);
5501
45.4k
      this_yrd = RDCOST(x->rdmult, y_rate + mode_rate, rd_stats_y.dist);
5502
45.4k
    }
5503
5504
45.4k
    rd_stats.rdcost = RDCOST(x->rdmult, rd_stats.rate, rd_stats.dist);
5505
5506
45.4k
    const THR_MODES mode_enum = get_prediction_mode_idx(
5507
45.4k
        prediction_mode, mbmi->ref_frame[0], mbmi->ref_frame[1]);
5508
5509
    // Collect mode stats for multiwinner mode processing
5510
45.4k
    const int txfm_search_done = 1;
5511
45.4k
    store_winner_mode_stats(cpi, x, mbmi, &rd_stats, &rd_stats_y, &rd_stats_uv,
5512
45.4k
                            mode_enum, NULL, bsize, rd_stats.rdcost,
5513
45.4k
                            cpi->sf.winner_mode_sf.multi_winner_mode_type,
5514
45.4k
                            txfm_search_done);
5515
5516
45.4k
    if (rd_stats.rdcost < best_rd_in_this_partition) {
5517
45.4k
      best_rd_in_this_partition = rd_stats.rdcost;
5518
45.4k
      *yrd = this_yrd;
5519
45.4k
    }
5520
5521
45.4k
    if (rd_stats.rdcost < search_state->best_rd) {
5522
45.4k
      update_search_state(cpi, search_state, rd_cost, ctx, &rd_stats,
5523
45.4k
                          &rd_stats_y, &rd_stats_uv, mode_enum, x,
5524
45.4k
                          txfm_search_done);
5525
45.4k
      search_state->best_skip_rd[0] = skip_rd;
5526
      // Limit the total number of modes to be evaluated if the first is valid
5527
      // and transform skip or compound
5528
45.4k
      if (cpi->sf.inter_sf.inter_mode_txfm_breakout) {
5529
43.1k
        if (!j && (search_state->best_mbmode.skip_txfm || rd_stats.skip_txfm)) {
5530
          // Evaluate more candidates at high quantizers where occurrence of
5531
          // transform skip is high.
5532
3.07k
          const int max_cands_cap[5] = { 2, 3, 5, 7, 9 };
5533
3.07k
          const int qindex_band = (5 * x->qindex) >> QINDEX_BITS;
5534
3.07k
          num_inter_mode_cands =
5535
3.07k
              AOMMIN(max_cands_cap[qindex_band], inter_modes_info->num);
5536
40.0k
        } else if (!j && has_second_ref(&search_state->best_mbmode)) {
5537
1.17k
          const int aggr = cpi->sf.inter_sf.inter_mode_txfm_breakout - 1;
5538
          // Evaluate more candidates at low quantizers where occurrence of
5539
          // single reference mode is high.
5540
1.17k
          const int max_cands_cap_cmp[2][4] = { { 10, 7, 5, 4 },
5541
1.17k
                                                { 10, 7, 5, 3 } };
5542
1.17k
          const int qindex_band_cmp = (4 * x->qindex) >> QINDEX_BITS;
5543
1.17k
          num_inter_mode_cands = AOMMIN(
5544
1.17k
              max_cands_cap_cmp[aggr][qindex_band_cmp], inter_modes_info->num);
5545
1.17k
        }
5546
43.1k
      }
5547
45.4k
    }
5548
    // If the number of candidates evaluated exceeds max_allowed_cands, break if
5549
    // a newmv mode was evaluated already.
5550
45.4k
    if ((num_tx_cands > max_allowed_cands) && newmv_mode_evaled) break;
5551
45.4k
  }
5552
37.4k
}
5553
5554
// Indicates number of winner simple translation modes to be used
5555
static const unsigned int num_winner_motion_modes[3] = { 0, 10, 3 };
5556
5557
// Adds a motion mode to the candidate list for motion_mode_for_winner_cand
5558
// speed feature. This list consists of modes that have only searched
5559
// SIMPLE_TRANSLATION. The final list will be used to search other motion
5560
// modes after the initial RD search.
5561
static void handle_winner_cand(
5562
    MB_MODE_INFO *const mbmi,
5563
    motion_mode_best_st_candidate *best_motion_mode_cands,
5564
    int max_winner_motion_mode_cand, int64_t this_rd,
5565
1.72M
    motion_mode_candidate *motion_mode_cand, int skip_motion_mode) {
5566
  // Number of current motion mode candidates in list
5567
1.72M
  const int num_motion_mode_cand = best_motion_mode_cands->num_motion_mode_cand;
5568
1.72M
  int valid_motion_mode_cand_loc = num_motion_mode_cand;
5569
5570
  // find the best location to insert new motion mode candidate
5571
1.81M
  for (int j = 0; j < num_motion_mode_cand; j++) {
5572
957k
    if (this_rd < best_motion_mode_cands->motion_mode_cand[j].rd_cost) {
5573
869k
      valid_motion_mode_cand_loc = j;
5574
869k
      break;
5575
869k
    }
5576
957k
  }
5577
5578
  // Insert motion mode if location is found
5579
1.72M
  if (valid_motion_mode_cand_loc < max_winner_motion_mode_cand) {
5580
1.71M
    if (num_motion_mode_cand > 0 &&
5581
890k
        valid_motion_mode_cand_loc < max_winner_motion_mode_cand - 1)
5582
876k
      memmove(
5583
876k
          &best_motion_mode_cands
5584
876k
               ->motion_mode_cand[valid_motion_mode_cand_loc + 1],
5585
876k
          &best_motion_mode_cands->motion_mode_cand[valid_motion_mode_cand_loc],
5586
876k
          (AOMMIN(num_motion_mode_cand, max_winner_motion_mode_cand - 1) -
5587
876k
           valid_motion_mode_cand_loc) *
5588
876k
              sizeof(best_motion_mode_cands->motion_mode_cand[0]));
5589
1.71M
    motion_mode_cand->mbmi = *mbmi;
5590
1.71M
    motion_mode_cand->rd_cost = this_rd;
5591
1.71M
    motion_mode_cand->skip_motion_mode = skip_motion_mode;
5592
1.71M
    best_motion_mode_cands->motion_mode_cand[valid_motion_mode_cand_loc] =
5593
1.71M
        *motion_mode_cand;
5594
1.71M
    best_motion_mode_cands->num_motion_mode_cand =
5595
1.71M
        AOMMIN(max_winner_motion_mode_cand,
5596
1.71M
               best_motion_mode_cands->num_motion_mode_cand + 1);
5597
1.71M
  }
5598
1.72M
}
5599
5600
/*!\brief Search intra modes in interframes
5601
 *
5602
 * \ingroup intra_mode_search
5603
 *
5604
 * This function searches for the best intra mode when the current frame is an
5605
 * interframe. This function however does *not* handle luma palette mode.
5606
 * Palette mode is currently handled by \ref av1_search_palette_mode.
5607
 *
5608
 * This function will first iterate through the luma mode candidates to find the
5609
 * best luma intra mode. Once the best luma mode it's found, it will then search
5610
 * for the best chroma mode. Because palette mode is currently not handled by
5611
 * here, a cache of uv mode is stored in
5612
 * InterModeSearchState::intra_search_state so it can be reused later by \ref
5613
 * av1_search_palette_mode.
5614
 *
5615
 * \param[in,out] search_state      Struct keep track of the prediction mode
5616
 *                                  search state in interframe.
5617
 *
5618
 * \param[in]     cpi               Top-level encoder structure.
5619
 * \param[in,out] x                 Pointer to struct holding all the data for
5620
 *                                  the current prediction block.
5621
 * \param[out]    rd_cost           Stores the best rd_cost among all the
5622
 *                                  prediction modes searched.
5623
 * \param[in]     bsize             Current block size.
5624
 * \param[in,out] ctx               Structure to hold the number of 4x4 blks to
5625
 *                                  copy the tx_type and txfm_skip arrays.
5626
 *                                  for only the Y plane.
5627
 * \param[in]     sf_args           Stores the list of intra mode candidates
5628
 *                                  to be searched.
5629
 * \param[in]     intra_ref_frame_cost  The entropy cost for signaling that the
5630
 *                                      current ref frame is an intra frame.
5631
 * \param[in]     yrd_threshold     The rdcost threshold for luma intra mode to
5632
 *                                  terminate chroma intra mode search.
5633
 *
5634
 * \remark If a new best mode is found, search_state and rd_costs are updated
5635
 * correspondingly. While x is also modified, it is only used as a temporary
5636
 * buffer, and the final decisions are stored in search_state.
5637
 */
5638
static inline void search_intra_modes_in_interframe(
5639
    InterModeSearchState *search_state, const AV1_COMP *cpi, MACROBLOCK *x,
5640
    RD_STATS *rd_cost, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
5641
    const InterModeSFArgs *sf_args, unsigned int intra_ref_frame_cost,
5642
903k
    int64_t yrd_threshold) {
5643
903k
  const AV1_COMMON *const cm = &cpi->common;
5644
903k
  const SPEED_FEATURES *const sf = &cpi->sf;
5645
903k
  const IntraModeCfg *const intra_mode_cfg = &cpi->oxcf.intra_mode_cfg;
5646
903k
  MACROBLOCKD *const xd = &x->e_mbd;
5647
903k
  MB_MODE_INFO *const mbmi = xd->mi[0];
5648
903k
  IntraModeSearchState *intra_search_state = &search_state->intra_search_state;
5649
5650
903k
  int is_best_y_mode_intra = 0;
5651
903k
  RD_STATS best_intra_rd_stats_y;
5652
903k
  int64_t best_rd_y = INT64_MAX;
5653
903k
  int best_mode_cost_y = -1;
5654
903k
  MB_MODE_INFO best_mbmi = *xd->mi[0];
5655
903k
  THR_MODES best_mode_enum = THR_INVALID;
5656
903k
  uint8_t best_tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
5657
903k
  const int num_4x4 = bsize_to_num_blk(bsize);
5658
5659
  // Performs luma search
5660
903k
  int64_t best_model_rd = INT64_MAX;
5661
903k
  int64_t top_intra_model_rd[TOP_INTRA_MODEL_COUNT];
5662
4.51M
  for (int i = 0; i < TOP_INTRA_MODEL_COUNT; i++) {
5663
3.61M
    top_intra_model_rd[i] = INT64_MAX;
5664
3.61M
  }
5665
5666
903k
  if (cpi->oxcf.algo_cfg.sharpness) {
5667
0
    int bh = mi_size_high[bsize];
5668
0
    int bw = mi_size_wide[bsize];
5669
0
    if (bh > 4 || bw > 4) return;
5670
0
  }
5671
5672
903k
  mbmi->skip_txfm = 0;
5673
5674
44.5M
  for (int mode_idx = 0; mode_idx < LUMA_MODE_COUNT; ++mode_idx) {
5675
43.8M
    if (sf->intra_sf.skip_intra_in_interframe &&
5676
43.8M
        search_state->intra_search_state.skip_intra_modes)
5677
187k
      break;
5678
43.6M
    set_y_mode_and_delta_angle(
5679
43.6M
        mode_idx, mbmi, sf->intra_sf.prune_luma_odd_delta_angles_in_intra);
5680
43.6M
    assert(mbmi->mode < INTRA_MODE_END);
5681
5682
    // Use intra_y_mode_mask speed feature to skip intra mode evaluation.
5683
43.6M
    if (sf_args->mode_skip_mask->pred_modes[INTRA_FRAME] & (1 << mbmi->mode))
5684
650k
      continue;
5685
5686
43.0M
    const THR_MODES mode_enum =
5687
43.0M
        get_prediction_mode_idx(mbmi->mode, INTRA_FRAME, NONE_FRAME);
5688
43.0M
    if ((!intra_mode_cfg->enable_smooth_intra ||
5689
43.0M
         cpi->sf.intra_sf.disable_smooth_intra) &&
5690
43.0M
        (mbmi->mode == SMOOTH_PRED || mbmi->mode == SMOOTH_H_PRED ||
5691
41.6M
         mbmi->mode == SMOOTH_V_PRED))
5692
2.11M
      continue;
5693
40.9M
    if (!intra_mode_cfg->enable_paeth_intra && mbmi->mode == PAETH_PRED)
5694
0
      continue;
5695
40.9M
    if (av1_is_directional_mode(mbmi->mode) &&
5696
39.4M
        !(av1_use_angle_delta(bsize) && intra_mode_cfg->enable_angle_delta) &&
5697
0
        mbmi->angle_delta[PLANE_TYPE_Y] != 0)
5698
0
      continue;
5699
40.9M
    const PREDICTION_MODE this_mode = mbmi->mode;
5700
5701
40.9M
    assert(av1_mode_defs[mode_enum].ref_frame[0] == INTRA_FRAME);
5702
40.9M
    assert(av1_mode_defs[mode_enum].ref_frame[1] == NONE_FRAME);
5703
40.9M
    init_mbmi(mbmi, this_mode, av1_mode_defs[mode_enum].ref_frame, cm);
5704
40.9M
    x->txfm_search_info.skip_txfm = 0;
5705
5706
40.9M
    if (this_mode != DC_PRED) {
5707
      // Only search the oblique modes if the best so far is
5708
      // one of the neighboring directional modes
5709
40.1M
      if ((sf->rt_sf.mode_search_skip_flags & FLAG_SKIP_INTRA_BESTINTER) &&
5710
0
          (this_mode >= D45_PRED && this_mode <= PAETH_PRED)) {
5711
0
        if (search_state->best_mode_index != THR_INVALID &&
5712
0
            search_state->best_mbmode.ref_frame[0] > INTRA_FRAME)
5713
0
          continue;
5714
0
      }
5715
40.1M
      if (sf->rt_sf.mode_search_skip_flags & FLAG_SKIP_INTRA_DIRMISMATCH) {
5716
0
        if (conditional_skipintra(
5717
0
                this_mode, search_state->intra_search_state.best_intra_mode))
5718
0
          continue;
5719
0
      }
5720
40.1M
    }
5721
5722
40.9M
    RD_STATS intra_rd_stats_y;
5723
40.9M
    int mode_cost_y;
5724
40.9M
    int64_t intra_rd_y = INT64_MAX;
5725
40.9M
    const int is_luma_result_valid = av1_handle_intra_y_mode(
5726
40.9M
        intra_search_state, cpi, x, bsize, intra_ref_frame_cost, ctx,
5727
40.9M
        &intra_rd_stats_y, search_state->best_rd, &mode_cost_y, &intra_rd_y,
5728
40.9M
        &best_model_rd, top_intra_model_rd);
5729
5730
40.9M
    if (intra_rd_y < INT64_MAX) {
5731
1.09M
      adjust_cost(cpi, x, &intra_rd_y, /*is_inter_pred=*/false);
5732
1.09M
    }
5733
5734
40.9M
    if (is_luma_result_valid && intra_rd_y < yrd_threshold) {
5735
786k
      is_best_y_mode_intra = 1;
5736
786k
      if (intra_rd_y < best_rd_y) {
5737
564k
        best_intra_rd_stats_y = intra_rd_stats_y;
5738
564k
        best_mode_cost_y = mode_cost_y;
5739
564k
        best_rd_y = intra_rd_y;
5740
564k
        best_mbmi = *mbmi;
5741
564k
        best_mode_enum = mode_enum;
5742
564k
        av1_copy_array(best_tx_type_map, xd->tx_type_map, num_4x4);
5743
564k
      }
5744
786k
    }
5745
40.9M
  }
5746
5747
903k
  if (!is_best_y_mode_intra) {
5748
342k
    return;
5749
342k
  }
5750
5751
903k
  assert(best_rd_y < INT64_MAX);
5752
5753
  // Restores the best luma mode
5754
561k
  *mbmi = best_mbmi;
5755
561k
  av1_copy_array(xd->tx_type_map, best_tx_type_map, num_4x4);
5756
5757
  // Performs chroma search
5758
561k
  RD_STATS intra_rd_stats, intra_rd_stats_uv;
5759
561k
  av1_init_rd_stats(&intra_rd_stats);
5760
561k
  av1_init_rd_stats(&intra_rd_stats_uv);
5761
561k
  const int num_planes = av1_num_planes(cm);
5762
561k
  if (num_planes > 1) {
5763
246k
    const int intra_uv_mode_valid = av1_search_intra_uv_modes_in_interframe(
5764
246k
        intra_search_state, cpi, x, bsize, &intra_rd_stats,
5765
246k
        &best_intra_rd_stats_y, &intra_rd_stats_uv, search_state->best_rd);
5766
5767
246k
    if (!intra_uv_mode_valid) {
5768
2.62k
      return;
5769
2.62k
    }
5770
246k
  }
5771
5772
  // Merge the luma and chroma rd stats
5773
561k
  assert(best_mode_cost_y >= 0);
5774
559k
  intra_rd_stats.rate = best_intra_rd_stats_y.rate + best_mode_cost_y;
5775
559k
  if (!xd->lossless[mbmi->segment_id] && block_signals_txsize(bsize)) {
5776
    // av1_pick_uniform_tx_size_type_yrd above includes the cost of the tx_size
5777
    // in the tokenonly rate, but for intra blocks, tx_size is always coded
5778
    // (prediction granularity), so we account for it in the full rate,
5779
    // not the tokenonly rate.
5780
526k
    best_intra_rd_stats_y.rate -= tx_size_cost(x, bsize, mbmi->tx_size);
5781
526k
  }
5782
5783
559k
  const ModeCosts *mode_costs = &x->mode_costs;
5784
559k
  const PREDICTION_MODE mode = mbmi->mode;
5785
559k
  if (num_planes > 1 && xd->is_chroma_ref) {
5786
244k
    const int uv_mode_cost =
5787
244k
        mode_costs->intra_uv_mode_cost[is_cfl_allowed(xd)][mode][mbmi->uv_mode];
5788
244k
    intra_rd_stats.rate +=
5789
244k
        intra_rd_stats_uv.rate +
5790
244k
        intra_mode_info_cost_uv(cpi, x, mbmi, bsize, uv_mode_cost);
5791
244k
  }
5792
5793
  // Intra block is always coded as non-skip
5794
559k
  intra_rd_stats.skip_txfm = 0;
5795
559k
  intra_rd_stats.dist = best_intra_rd_stats_y.dist + intra_rd_stats_uv.dist;
5796
  // Add in the cost of the no skip flag.
5797
559k
  const int skip_ctx = av1_get_skip_txfm_context(xd);
5798
559k
  intra_rd_stats.rate += mode_costs->skip_txfm_cost[skip_ctx][0];
5799
  // Calculate the final RD estimate for this mode.
5800
559k
  const int64_t this_rd =
5801
559k
      RDCOST(x->rdmult, intra_rd_stats.rate, intra_rd_stats.dist);
5802
  // Keep record of best intra rd
5803
559k
  if (this_rd < search_state->best_intra_rd) {
5804
558k
    search_state->best_intra_rd = this_rd;
5805
558k
    intra_search_state->best_intra_mode = mode;
5806
558k
  }
5807
5808
2.23M
  for (int i = 0; i < REFERENCE_MODES; ++i) {
5809
1.67M
    search_state->best_pred_rd[i] =
5810
1.67M
        AOMMIN(search_state->best_pred_rd[i], this_rd);
5811
1.67M
  }
5812
5813
559k
  intra_rd_stats.rdcost = this_rd;
5814
5815
559k
  adjust_rdcost(cpi, x, &intra_rd_stats, /*is_inter_pred=*/false);
5816
5817
  // Collect mode stats for multiwinner mode processing
5818
559k
  const int txfm_search_done = 1;
5819
559k
  store_winner_mode_stats(
5820
559k
      cpi, x, mbmi, &intra_rd_stats, &best_intra_rd_stats_y, &intra_rd_stats_uv,
5821
559k
      best_mode_enum, NULL, bsize, intra_rd_stats.rdcost,
5822
559k
      cpi->sf.winner_mode_sf.multi_winner_mode_type, txfm_search_done);
5823
559k
  if (intra_rd_stats.rdcost < search_state->best_rd) {
5824
550k
    update_search_state(cpi, search_state, rd_cost, ctx, &intra_rd_stats,
5825
550k
                        &best_intra_rd_stats_y, &intra_rd_stats_uv,
5826
550k
                        best_mode_enum, x, txfm_search_done);
5827
550k
  }
5828
559k
}
5829
5830
// Initialize the table that stores best RD Costs of transform no-split.
5831
static inline void init_top_tx_no_split_rd_for_inter_modes(
5832
902k
    MACROBLOCK *x, int prune_inter_tx_split_rd_eval_lvl) {
5833
902k
  if (!prune_inter_tx_split_rd_eval_lvl) return;
5834
5835
4.51M
  for (int i = 0; i < MAX_TX_BLOCKS_IN_MAX_SB; i++) {
5836
18.0M
    for (int j = 0; j < TOP_INTER_TX_NO_SPLIT_COUNT; j++) {
5837
14.4M
      x->top_inter_tx_no_split_rd[i][j] = INT64_MAX;
5838
14.4M
    }
5839
3.60M
  }
5840
902k
}
5841
5842
#if !CONFIG_REALTIME_ONLY
5843
// Prepare inter_cost and intra_cost from TPL stats, which are used as ML
5844
// features in intra mode pruning.
5845
static inline void calculate_cost_from_tpl_data(const AV1_COMP *cpi,
5846
                                                MACROBLOCK *x, BLOCK_SIZE bsize,
5847
                                                int mi_row, int mi_col,
5848
                                                int64_t *inter_cost,
5849
902k
                                                int64_t *intra_cost) {
5850
902k
  const AV1_COMMON *const cm = &cpi->common;
5851
  // Only consider full SB.
5852
902k
  const BLOCK_SIZE sb_size = cm->seq_params->sb_size;
5853
902k
  const int tpl_bsize_1d = cpi->ppi->tpl_data.tpl_bsize_1d;
5854
902k
  const int len = (block_size_wide[sb_size] / tpl_bsize_1d) *
5855
902k
                  (block_size_high[sb_size] / tpl_bsize_1d);
5856
902k
  SuperBlockEnc *sb_enc = &x->sb_enc;
5857
902k
  if (sb_enc->tpl_data_count == len) {
5858
209k
    const BLOCK_SIZE tpl_bsize = convert_length_to_bsize(tpl_bsize_1d);
5859
209k
    const int tpl_stride = sb_enc->tpl_stride;
5860
209k
    const int tplw = mi_size_wide[tpl_bsize];
5861
209k
    const int tplh = mi_size_high[tpl_bsize];
5862
209k
    const int nw = mi_size_wide[bsize] / tplw;
5863
209k
    const int nh = mi_size_high[bsize] / tplh;
5864
209k
    if (nw >= 1 && nh >= 1) {
5865
1.42k
      const int of_h = mi_row % mi_size_high[sb_size];
5866
1.42k
      const int of_w = mi_col % mi_size_wide[sb_size];
5867
1.42k
      const int start = of_h / tplh * tpl_stride + of_w / tplw;
5868
5869
4.64k
      for (int k = 0; k < nh; k++) {
5870
12.2k
        for (int l = 0; l < nw; l++) {
5871
9.04k
          *inter_cost += sb_enc->tpl_inter_cost[start + k * tpl_stride + l];
5872
9.04k
          *intra_cost += sb_enc->tpl_intra_cost[start + k * tpl_stride + l];
5873
9.04k
        }
5874
3.22k
      }
5875
1.42k
      *inter_cost /= nw * nh;
5876
1.42k
      *intra_cost /= nw * nh;
5877
1.42k
    }
5878
209k
  }
5879
902k
}
5880
#endif  // !CONFIG_REALTIME_ONLY
5881
5882
// When the speed feature skip_intra_in_interframe > 0, enable ML model to prune
5883
// intra mode search.
5884
static inline void skip_intra_modes_in_interframe(
5885
    AV1_COMMON *const cm, struct macroblock *x, BLOCK_SIZE bsize,
5886
    InterModeSearchState *search_state, const SPEED_FEATURES *const sf,
5887
903k
    int64_t inter_cost, int64_t intra_cost) {
5888
903k
  MACROBLOCKD *const xd = &x->e_mbd;
5889
903k
  const int comp_pred = search_state->best_mbmode.ref_frame[1] > INTRA_FRAME;
5890
903k
  if (sf->rt_sf.prune_intra_mode_based_on_mv_range &&
5891
0
      bsize > sf->part_sf.max_intra_bsize && !comp_pred) {
5892
0
    const MV best_mv = search_state->best_mbmode.mv[0].as_mv;
5893
0
    const int mv_thresh = 16 << sf->rt_sf.prune_intra_mode_based_on_mv_range;
5894
0
    if (abs(best_mv.row) < mv_thresh && abs(best_mv.col) < mv_thresh &&
5895
0
        x->source_variance > 128) {
5896
0
      search_state->intra_search_state.skip_intra_modes = 1;
5897
0
      return;
5898
0
    }
5899
0
  }
5900
5901
903k
  const unsigned int src_var_thresh_intra_skip = 1;
5902
903k
  const int skip_intra_in_interframe = sf->intra_sf.skip_intra_in_interframe;
5903
903k
  if (!(skip_intra_in_interframe &&
5904
903k
        (x->source_variance > src_var_thresh_intra_skip)))
5905
2.46k
    return;
5906
5907
  // Prune intra search based on best inter mode being transfrom skip.
5908
901k
  if ((skip_intra_in_interframe >= 2) && search_state->best_mbmode.skip_txfm) {
5909
185k
    const int qindex_thresh[2] = { 200, MAXQ };
5910
18.4E
    const int ind = (skip_intra_in_interframe >= 3) ? 1 : 0;
5911
185k
    if (!have_newmv_in_inter_mode(search_state->best_mbmode.mode) &&
5912
147k
        (x->qindex <= qindex_thresh[ind])) {
5913
147k
      search_state->intra_search_state.skip_intra_modes = 1;
5914
147k
      return;
5915
147k
    } else if ((skip_intra_in_interframe >= 4) &&
5916
38.5k
               (inter_cost < 0 || intra_cost < 0)) {
5917
38.3k
      search_state->intra_search_state.skip_intra_modes = 1;
5918
38.3k
      return;
5919
38.3k
    }
5920
185k
  }
5921
  // Use ML model to prune intra search.
5922
716k
  if (inter_cost >= 0 && intra_cost >= 0) {
5923
1.13k
    const NN_CONFIG *nn_config = (AOMMIN(cm->width, cm->height) <= 480)
5924
1.13k
                                     ? &av1_intrap_nn_config
5925
1.13k
                                     : &av1_intrap_hd_nn_config;
5926
1.13k
    float nn_features[6];
5927
1.13k
    float scores[2] = { 0.0f };
5928
5929
1.13k
    nn_features[0] = (float)search_state->best_mbmode.skip_txfm;
5930
1.13k
    nn_features[1] = (float)mi_size_wide_log2[bsize];
5931
1.13k
    nn_features[2] = (float)mi_size_high_log2[bsize];
5932
1.13k
    nn_features[3] = (float)intra_cost;
5933
1.13k
    nn_features[4] = (float)inter_cost;
5934
1.13k
    const int ac_q = av1_ac_quant_QTX(x->qindex, 0, xd->bd);
5935
1.13k
    const int ac_q_max = av1_ac_quant_QTX(255, 0, xd->bd);
5936
1.13k
    nn_features[5] = (float)(ac_q_max / ac_q);
5937
5938
1.13k
    av1_nn_predict(nn_features, nn_config, 1, scores);
5939
5940
    // For two parameters, the max prob returned from av1_nn_softmax equals
5941
    // 1.0 / (1.0 + e^(-|diff_score|)). Here use scores directly to avoid the
5942
    // calling of av1_nn_softmax.
5943
1.13k
    const float thresh[5] = { 1.4f, 1.4f, 1.4f, 1.4f, 1.4f };
5944
1.13k
    assert(skip_intra_in_interframe <= 5);
5945
1.13k
    if (scores[1] > scores[0] + thresh[skip_intra_in_interframe - 1]) {
5946
0
      search_state->intra_search_state.skip_intra_modes = 1;
5947
0
    }
5948
1.13k
  }
5949
716k
}
5950
5951
static inline bool skip_interp_filter_search(const AV1_COMP *cpi,
5952
4.86M
                                             int is_single_pred) {
5953
4.86M
  const MODE encoding_mode = cpi->oxcf.mode;
5954
4.86M
  if (encoding_mode == REALTIME) {
5955
0
    return (cpi->common.current_frame.reference_mode == SINGLE_REFERENCE &&
5956
0
            (cpi->sf.interp_sf.skip_interp_filter_search ||
5957
0
             cpi->sf.winner_mode_sf.winner_mode_ifs));
5958
4.86M
  } else if (encoding_mode == GOOD) {
5959
    // Skip interpolation filter search for single prediction modes.
5960
4.86M
    return (cpi->sf.interp_sf.skip_interp_filter_search && is_single_pred);
5961
4.86M
  }
5962
160
  return false;
5963
4.86M
}
5964
5965
static inline int get_block_temp_var(const AV1_COMP *cpi, const MACROBLOCK *x,
5966
903k
                                     BLOCK_SIZE bsize) {
5967
903k
  const AV1_COMMON *const cm = &cpi->common;
5968
903k
  const SPEED_FEATURES *const sf = &cpi->sf;
5969
5970
903k
  if (sf->part_sf.partition_search_type != VAR_BASED_PARTITION ||
5971
0
      !sf->rt_sf.short_circuit_low_temp_var ||
5972
903k
      !sf->rt_sf.prune_inter_modes_using_temp_var) {
5973
903k
    return 0;
5974
903k
  }
5975
5976
18.4E
  const int mi_row = x->e_mbd.mi_row;
5977
18.4E
  const int mi_col = x->e_mbd.mi_col;
5978
18.4E
  int is_low_temp_var = 0;
5979
5980
18.4E
  if (cm->seq_params->sb_size == BLOCK_64X64)
5981
0
    is_low_temp_var = av1_get_force_skip_low_temp_var_small_sb(
5982
0
        &x->part_search_info.variance_low[0], mi_row, mi_col, bsize);
5983
18.4E
  else
5984
18.4E
    is_low_temp_var = av1_get_force_skip_low_temp_var(
5985
18.4E
        &x->part_search_info.variance_low[0], mi_row, mi_col, bsize);
5986
5987
18.4E
  return is_low_temp_var;
5988
903k
}
5989
5990
// TODO(chiyotsai@google.com): See the todo for av1_rd_pick_intra_mode_sb.
5991
void av1_rd_pick_inter_mode(struct AV1_COMP *cpi, struct TileDataEnc *tile_data,
5992
                            struct macroblock *x, struct RD_STATS *rd_cost,
5993
                            BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx,
5994
903k
                            int64_t best_rd_so_far) {
5995
903k
  AV1_COMMON *const cm = &cpi->common;
5996
903k
  const FeatureFlags *const features = &cm->features;
5997
903k
  const int num_planes = av1_num_planes(cm);
5998
903k
  const SPEED_FEATURES *const sf = &cpi->sf;
5999
903k
  MACROBLOCKD *const xd = &x->e_mbd;
6000
903k
  MB_MODE_INFO *const mbmi = xd->mi[0];
6001
903k
  TxfmSearchInfo *txfm_info = &x->txfm_search_info;
6002
903k
  int i;
6003
903k
  const ModeCosts *mode_costs = &x->mode_costs;
6004
903k
  const int *comp_inter_cost =
6005
903k
      mode_costs->comp_inter_cost[av1_get_reference_mode_context(xd)];
6006
6007
903k
  InterModeSearchState search_state;
6008
903k
  init_inter_mode_search_state(&search_state, cpi, x, bsize, best_rd_so_far);
6009
903k
  INTERINTRA_MODE interintra_modes[REF_FRAMES] = {
6010
903k
    INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES,
6011
903k
    INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES, INTERINTRA_MODES
6012
903k
  };
6013
6014
903k
  init_top_tx_no_split_rd_for_inter_modes(
6015
903k
      x, sf->tx_sf.prune_inter_tx_split_rd_eval_lvl);
6016
6017
903k
  HandleInterModeArgs args = { { NULL },
6018
903k
                               { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE },
6019
903k
                               { NULL },
6020
903k
                               { MAX_SB_SIZE >> 1, MAX_SB_SIZE >> 1,
6021
903k
                                 MAX_SB_SIZE >> 1 },
6022
903k
                               NULL,
6023
903k
                               NULL,
6024
903k
                               NULL,
6025
903k
                               search_state.modelled_rd,
6026
903k
                               INT_MAX,
6027
903k
                               INT_MAX,
6028
903k
                               search_state.simple_rd,
6029
903k
                               0,
6030
903k
                               false,
6031
903k
                               interintra_modes,
6032
903k
                               { { { 0 }, { { 0 } }, { 0 }, 0, 0, 0, 0 } },
6033
903k
                               { { 0, 0 } },
6034
903k
                               { 0 },
6035
903k
                               0,
6036
903k
                               0,
6037
903k
                               -1,
6038
903k
                               -1,
6039
903k
                               -1,
6040
903k
                               { 0 },
6041
903k
                               { 0 },
6042
903k
                               UINT_MAX };
6043
  // Currently, is_low_temp_var is used in real time encoding.
6044
903k
  const int is_low_temp_var = get_block_temp_var(cpi, x, bsize);
6045
6046
27.0M
  for (i = 0; i < MODE_CTX_REF_FRAMES; ++i) args.cmp_mode[i] = -1;
6047
  // Indicates the appropriate number of simple translation winner modes for
6048
  // exhaustive motion mode evaluation
6049
903k
  const int max_winner_motion_mode_cand =
6050
903k
      num_winner_motion_modes[sf->winner_mode_sf.motion_mode_for_winner_cand];
6051
903k
  assert(max_winner_motion_mode_cand <= MAX_WINNER_MOTION_MODES);
6052
903k
  motion_mode_candidate motion_mode_cand;
6053
903k
  motion_mode_best_st_candidate best_motion_mode_cands;
6054
  // Initializing the number of motion mode candidates to zero.
6055
903k
  best_motion_mode_cands.num_motion_mode_cand = 0;
6056
9.93M
  for (i = 0; i < MAX_WINNER_MOTION_MODES; ++i)
6057
9.02M
    best_motion_mode_cands.motion_mode_cand[i].rd_cost = INT64_MAX;
6058
6059
8.12M
  for (i = 0; i < REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX;
6060
6061
903k
  av1_invalid_rd_stats(rd_cost);
6062
6063
8.12M
  for (i = 0; i < REF_FRAMES; ++i) {
6064
7.21M
    x->warp_sample_info[i].num = -1;
6065
7.21M
  }
6066
6067
  // Ref frames that are selected by square partition blocks.
6068
903k
  int picked_ref_frames_mask = 0;
6069
903k
  if (sf->inter_sf.prune_ref_frame_for_rect_partitions &&
6070
902k
      mbmi->partition != PARTITION_NONE) {
6071
    // prune_ref_frame_for_rect_partitions = 1 implies prune only extended
6072
    // partition blocks. prune_ref_frame_for_rect_partitions >=2
6073
    // implies prune for vert, horiz and extended partition blocks.
6074
10.0k
    if ((mbmi->partition != PARTITION_VERT &&
6075
282
         mbmi->partition != PARTITION_HORZ) ||
6076
10.0k
        sf->inter_sf.prune_ref_frame_for_rect_partitions >= 2) {
6077
9.15k
      picked_ref_frames_mask =
6078
9.15k
          fetch_picked_ref_frames_mask(x, bsize, cm->seq_params->mib_size);
6079
9.15k
    }
6080
10.0k
  }
6081
6082
#if CONFIG_COLLECT_COMPONENT_TIMING
6083
  start_timing(cpi, set_params_rd_pick_inter_mode_time);
6084
#endif
6085
  // Skip ref frames that never selected by square blocks.
6086
903k
  const int skip_ref_frame_mask =
6087
903k
      picked_ref_frames_mask ? ~picked_ref_frames_mask : 0;
6088
903k
  mode_skip_mask_t mode_skip_mask;
6089
903k
  unsigned int ref_costs_single[REF_FRAMES];
6090
903k
  unsigned int ref_costs_comp[REF_FRAMES][REF_FRAMES];
6091
903k
  struct buf_2d yv12_mb[REF_FRAMES][MAX_MB_PLANE];
6092
  // init params, set frame modes, speed features
6093
903k
  set_params_rd_pick_inter_mode(cpi, x, &args, bsize, &mode_skip_mask,
6094
903k
                                skip_ref_frame_mask, ref_costs_single,
6095
903k
                                ref_costs_comp, yv12_mb);
6096
#if CONFIG_COLLECT_COMPONENT_TIMING
6097
  end_timing(cpi, set_params_rd_pick_inter_mode_time);
6098
#endif
6099
6100
903k
  int64_t best_est_rd = INT64_MAX;
6101
903k
  const InterModeRdModel *md = &tile_data->inter_mode_rd_models[bsize];
6102
  // If do_tx_search is 0, only estimated RD should be computed.
6103
  // If do_tx_search is 1, all modes have TX search performed.
6104
903k
  const int do_tx_search =
6105
903k
      !((sf->inter_sf.inter_mode_rd_model_estimation == 1 && md->ready) ||
6106
876k
        (sf->inter_sf.inter_mode_rd_model_estimation == 2 &&
6107
673k
         num_pels_log2_lookup[bsize] > 8));
6108
903k
  InterModesInfo *inter_modes_info = x->inter_modes_info;
6109
903k
  inter_modes_info->num = 0;
6110
6111
  // Temporary buffers used by handle_inter_mode().
6112
903k
  uint8_t *const tmp_buf = get_buf_by_bd(xd, x->tmp_pred_bufs[0]);
6113
6114
  // The best RD found for the reference frame, among single reference modes.
6115
  // Note that the 0-th element will contain a cut-off that is later used
6116
  // to determine if we should skip a compound mode.
6117
903k
  int64_t ref_frame_rd[REF_FRAMES] = { INT64_MAX, INT64_MAX, INT64_MAX,
6118
903k
                                       INT64_MAX, INT64_MAX, INT64_MAX,
6119
903k
                                       INT64_MAX, INT64_MAX };
6120
6121
  // Prepared stats used later to check if we could skip intra mode eval.
6122
903k
  int64_t inter_cost = -1;
6123
903k
  int64_t intra_cost = -1;
6124
  // Need to tweak the threshold for hdres speed 0 & 1.
6125
903k
  const int mi_row = xd->mi_row;
6126
903k
  const int mi_col = xd->mi_col;
6127
6128
  // Obtain the relevant tpl stats for pruning inter modes
6129
903k
  PruneInfoFromTpl inter_cost_info_from_tpl;
6130
903k
#if !CONFIG_REALTIME_ONLY
6131
903k
  if (sf->inter_sf.prune_inter_modes_based_on_tpl) {
6132
    // x->tpl_keep_ref_frame[id] = 1 => no pruning in
6133
    // prune_ref_by_selective_ref_frame()
6134
    // x->tpl_keep_ref_frame[id] = 0  => ref frame can be pruned in
6135
    // prune_ref_by_selective_ref_frame()
6136
    // Populating valid_refs[idx] = 1 ensures that
6137
    // 'inter_cost_info_from_tpl.best_inter_cost' does not correspond to a
6138
    // pruned ref frame.
6139
901k
    int valid_refs[INTER_REFS_PER_FRAME];
6140
7.21M
    for (MV_REFERENCE_FRAME frame = LAST_FRAME; frame < REF_FRAMES; frame++) {
6141
6.31M
      const MV_REFERENCE_FRAME refs[2] = { frame, NONE_FRAME };
6142
6.31M
      valid_refs[frame - 1] =
6143
6.31M
          x->tpl_keep_ref_frame[frame] ||
6144
6.04M
          !prune_ref_by_selective_ref_frame(
6145
6.04M
              cpi, x, refs, cm->cur_frame->ref_display_order_hint);
6146
6.31M
    }
6147
901k
    av1_zero(inter_cost_info_from_tpl);
6148
901k
    get_block_level_tpl_stats(cpi, bsize, mi_row, mi_col, valid_refs,
6149
901k
                              &inter_cost_info_from_tpl);
6150
901k
  }
6151
6152
903k
  const int do_pruning =
6153
903k
      (AOMMIN(cm->width, cm->height) > 480 && cpi->speed <= 1) ? 0 : 1;
6154
903k
  if (do_pruning && sf->intra_sf.skip_intra_in_interframe &&
6155
903k
      cpi->oxcf.algo_cfg.enable_tpl_model)
6156
903k
    calculate_cost_from_tpl_data(cpi, x, bsize, mi_row, mi_col, &inter_cost,
6157
903k
                                 &intra_cost);
6158
903k
#endif  // !CONFIG_REALTIME_ONLY
6159
6160
  // Initialize best mode stats for winner mode processing.
6161
903k
  const int max_winner_mode_count =
6162
903k
      winner_mode_count_allowed[sf->winner_mode_sf.multi_winner_mode_type];
6163
903k
  zero_winner_mode_stats(bsize, max_winner_mode_count, x->winner_mode_stats);
6164
903k
  x->winner_mode_count = 0;
6165
903k
  store_winner_mode_stats(cpi, x, mbmi, NULL, NULL, NULL, THR_INVALID, NULL,
6166
903k
                          bsize, best_rd_so_far,
6167
903k
                          sf->winner_mode_sf.multi_winner_mode_type, 0);
6168
6169
903k
  int mode_thresh_mul_fact = (1 << MODE_THRESH_QBITS);
6170
903k
  if (sf->inter_sf.prune_inter_modes_if_skippable) {
6171
    // Higher multiplication factor values for lower quantizers.
6172
902k
    mode_thresh_mul_fact = mode_threshold_mul_factor[x->qindex];
6173
902k
  }
6174
6175
  // Initialize arguments for mode loop speed features
6176
903k
  InterModeSFArgs sf_args = { &args.skip_motion_mode,
6177
903k
                              &mode_skip_mask,
6178
903k
                              &search_state,
6179
903k
                              skip_ref_frame_mask,
6180
903k
                              0,
6181
903k
                              mode_thresh_mul_fact,
6182
903k
                              0,
6183
903k
                              0 };
6184
903k
  int64_t best_inter_yrd = INT64_MAX;
6185
6186
  // This is the main loop of this function. It loops over all possible inter
6187
  // modes and calls handle_inter_mode() to compute the RD for each.
6188
  // Here midx is just an iterator index that should not be used by itself
6189
  // except to keep track of the number of modes searched. It should be used
6190
  // with av1_default_mode_order to get the enum that defines the mode, which
6191
  // can be used with av1_mode_defs to get the prediction mode and the ref
6192
  // frames.
6193
  // TODO(yunqing, any): Setting mode_start and mode_end outside for-loop brings
6194
  // good speedup for real time case. If we decide to use compound mode in real
6195
  // time, maybe we can modify av1_default_mode_order table.
6196
903k
  THR_MODES mode_start = THR_INTER_MODE_START;
6197
903k
  THR_MODES mode_end = THR_INTER_MODE_END;
6198
903k
  const CurrentFrame *const current_frame = &cm->current_frame;
6199
903k
  if (current_frame->reference_mode == SINGLE_REFERENCE) {
6200
0
    mode_start = SINGLE_REF_MODE_START;
6201
0
    mode_end = SINGLE_REF_MODE_END;
6202
0
  }
6203
903k
  init_comp_avg_est_rd(x, sf->inter_sf.skip_cmp_using_top_cmp_avg_est_rd_lvl);
6204
141M
  for (THR_MODES midx = mode_start; midx < mode_end; ++midx) {
6205
    // Get the actual prediction mode we are trying in this iteration
6206
140M
    const THR_MODES mode_enum = av1_default_mode_order[midx];
6207
140M
    const MODE_DEFINITION *mode_def = &av1_mode_defs[mode_enum];
6208
140M
    const PREDICTION_MODE this_mode = mode_def->mode;
6209
140M
    const MV_REFERENCE_FRAME *ref_frames = mode_def->ref_frame;
6210
6211
140M
    const MV_REFERENCE_FRAME ref_frame = ref_frames[0];
6212
140M
    const MV_REFERENCE_FRAME second_ref_frame = ref_frames[1];
6213
140M
    const int is_single_pred =
6214
140M
        ref_frame > INTRA_FRAME && second_ref_frame == NONE_FRAME;
6215
140M
    const int comp_pred = second_ref_frame > INTRA_FRAME;
6216
6217
140M
    txfm_info->skip_txfm = 0;
6218
140M
    sf_args.num_single_modes_processed += is_single_pred;
6219
#if CONFIG_COLLECT_COMPONENT_TIMING
6220
    start_timing(cpi, skip_inter_mode_time);
6221
#endif
6222
    // Apply speed features to decide if this inter mode can be skipped
6223
140M
    const int is_skip_inter_mode = skip_inter_mode(
6224
140M
        cpi, x, bsize, ref_frame_rd, midx, &sf_args, is_low_temp_var);
6225
#if CONFIG_COLLECT_COMPONENT_TIMING
6226
    end_timing(cpi, skip_inter_mode_time);
6227
#endif
6228
140M
    if (is_skip_inter_mode) continue;
6229
6230
4.82M
    init_mbmi(mbmi, this_mode, ref_frames, cm);
6231
4.82M
    set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
6232
6233
    // Select prediction reference frames.
6234
14.0M
    for (i = 0; i < num_planes; i++) {
6235
9.24M
      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
6236
9.24M
      if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
6237
9.24M
    }
6238
6239
4.82M
    mbmi->angle_delta[PLANE_TYPE_Y] = 0;
6240
4.82M
    mbmi->angle_delta[PLANE_TYPE_UV] = 0;
6241
4.82M
    mbmi->filter_intra_mode_info.use_filter_intra = 0;
6242
4.82M
    mbmi->ref_mv_idx = 0;
6243
6244
4.82M
    const int64_t ref_best_rd = search_state.best_rd;
6245
4.82M
    RD_STATS rd_stats, rd_stats_y, rd_stats_uv;
6246
4.82M
    av1_init_rd_stats(&rd_stats);
6247
6248
4.82M
    const int ref_frame_cost = comp_pred
6249
4.82M
                                   ? ref_costs_comp[ref_frame][second_ref_frame]
6250
4.82M
                                   : ref_costs_single[ref_frame];
6251
4.82M
    const int compmode_cost =
6252
18.4E
        is_comp_ref_allowed(mbmi->bsize) ? comp_inter_cost[comp_pred] : 0;
6253
4.82M
    const int real_compmode_cost =
6254
4.82M
        cm->current_frame.reference_mode == REFERENCE_MODE_SELECT
6255
4.86M
            ? compmode_cost
6256
18.4E
            : 0;
6257
    // Point to variables that are maintained between loop iterations
6258
4.82M
    args.single_newmv = search_state.single_newmv;
6259
4.82M
    args.single_newmv_rate = search_state.single_newmv_rate;
6260
4.82M
    args.single_newmv_valid = search_state.single_newmv_valid;
6261
4.82M
    args.single_comp_cost = real_compmode_cost;
6262
4.82M
    args.ref_frame_cost = ref_frame_cost;
6263
4.82M
    args.best_pred_sse = search_state.best_pred_sse;
6264
4.82M
    args.skip_ifs = skip_interp_filter_search(cpi, is_single_pred);
6265
4.82M
    int64_t skip_rd[2] = { search_state.best_skip_rd[0],
6266
4.82M
                           search_state.best_skip_rd[1] };
6267
4.82M
    int64_t this_yrd = INT64_MAX;
6268
#if CONFIG_COLLECT_COMPONENT_TIMING
6269
    start_timing(cpi, handle_inter_mode_time);
6270
#endif
6271
4.82M
    int64_t this_rd = handle_inter_mode(
6272
4.82M
        cpi, tile_data, x, bsize, &rd_stats, &rd_stats_y, &rd_stats_uv, &args,
6273
4.82M
        ref_best_rd, tmp_buf, &x->comp_rd_buffer, &best_est_rd, do_tx_search,
6274
4.82M
        inter_modes_info, &motion_mode_cand, skip_rd, &inter_cost_info_from_tpl,
6275
4.82M
        &this_yrd);
6276
#if CONFIG_COLLECT_COMPONENT_TIMING
6277
    end_timing(cpi, handle_inter_mode_time);
6278
#endif
6279
4.86M
    if (current_frame->reference_mode != SINGLE_REFERENCE) {
6280
4.86M
      if (!args.skip_ifs &&
6281
674k
          sf->inter_sf.prune_comp_search_by_single_result > 0 &&
6282
674k
          is_inter_singleref_mode(this_mode)) {
6283
193k
        collect_single_states(x, &search_state, mbmi);
6284
193k
      }
6285
6286
4.86M
      if (sf->inter_sf.prune_comp_using_best_single_mode_ref > 0 &&
6287
4.86M
          is_inter_singleref_mode(this_mode))
6288
4.38M
        update_best_single_mode(&search_state, this_mode, ref_frame, this_rd);
6289
4.86M
    }
6290
6291
4.82M
    if (this_rd == INT64_MAX) continue;
6292
6293
1.80M
    if (mbmi->skip_txfm) {
6294
274k
      rd_stats_y.rate = 0;
6295
274k
      rd_stats_uv.rate = 0;
6296
274k
    }
6297
6298
1.84M
    if (sf->inter_sf.prune_compound_using_single_ref && is_single_pred &&
6299
1.79M
        this_rd < ref_frame_rd[ref_frame]) {
6300
1.76M
      ref_frame_rd[ref_frame] = this_rd;
6301
1.76M
    }
6302
6303
1.80M
    adjust_cost(cpi, x, &this_rd, /*is_inter_pred=*/true);
6304
1.80M
    adjust_rdcost(cpi, x, &rd_stats, /*is_inter_pred=*/true);
6305
6306
    // Did this mode help, i.e., is it the new best mode
6307
1.80M
    if (this_rd < search_state.best_rd) {
6308
1.79M
      assert(IMPLIES(comp_pred,
6309
1.79M
                     cm->current_frame.reference_mode != SINGLE_REFERENCE));
6310
1.79M
      search_state.best_pred_sse = x->pred_sse[ref_frame];
6311
1.79M
      best_inter_yrd = this_yrd;
6312
1.79M
      update_search_state(cpi, &search_state, rd_cost, ctx, &rd_stats,
6313
1.79M
                          &rd_stats_y, &rd_stats_uv, mode_enum, x,
6314
1.79M
                          do_tx_search);
6315
1.79M
      if (do_tx_search) search_state.best_skip_rd[0] = skip_rd[0];
6316
      // skip_rd[0] is the best total rd for a skip mode so far.
6317
      // skip_rd[1] is the best total rd for a skip mode so far in luma.
6318
      // When do_tx_search = 1, both skip_rd[0] and skip_rd[1] are updated.
6319
      // When do_tx_search = 0, skip_rd[1] is updated.
6320
1.79M
      search_state.best_skip_rd[1] = skip_rd[1];
6321
1.79M
    }
6322
1.80M
    if (sf->winner_mode_sf.motion_mode_for_winner_cand) {
6323
      // Add this mode to motion mode candidate list for motion mode search
6324
      // if using motion_mode_for_winner_cand speed feature
6325
1.72M
      handle_winner_cand(mbmi, &best_motion_mode_cands,
6326
1.72M
                         max_winner_motion_mode_cand, this_rd,
6327
1.72M
                         &motion_mode_cand, args.skip_motion_mode);
6328
1.72M
    }
6329
6330
    /* keep record of best compound/single-only prediction */
6331
1.80M
    record_best_compound(cm->current_frame.reference_mode, &rd_stats, comp_pred,
6332
1.80M
                         x->rdmult, &search_state, compmode_cost);
6333
1.80M
  }
6334
6335
#if CONFIG_COLLECT_COMPONENT_TIMING
6336
  start_timing(cpi, evaluate_motion_mode_for_winner_candidates_time);
6337
#endif
6338
903k
  if (sf->winner_mode_sf.motion_mode_for_winner_cand) {
6339
    // For the single ref winner candidates, evaluate other motion modes (non
6340
    // simple translation).
6341
834k
    evaluate_motion_mode_for_winner_candidates(
6342
834k
        cpi, x, rd_cost, &args, tile_data, ctx, yv12_mb,
6343
834k
        &best_motion_mode_cands, do_tx_search, bsize, &best_est_rd,
6344
834k
        &search_state, &best_inter_yrd);
6345
834k
  }
6346
#if CONFIG_COLLECT_COMPONENT_TIMING
6347
  end_timing(cpi, evaluate_motion_mode_for_winner_candidates_time);
6348
#endif
6349
6350
#if CONFIG_COLLECT_COMPONENT_TIMING
6351
  start_timing(cpi, do_tx_search_time);
6352
#endif
6353
903k
  if (do_tx_search != 1) {
6354
    // A full tx search has not yet been done, do tx search for
6355
    // top mode candidates
6356
37.4k
    tx_search_best_inter_candidates(cpi, tile_data, x, best_rd_so_far, bsize,
6357
37.4k
                                    yv12_mb, mi_row, mi_col, &search_state,
6358
37.4k
                                    rd_cost, ctx, &best_inter_yrd);
6359
37.4k
  }
6360
#if CONFIG_COLLECT_COMPONENT_TIMING
6361
  end_timing(cpi, do_tx_search_time);
6362
#endif
6363
6364
#if CONFIG_COLLECT_COMPONENT_TIMING
6365
  start_timing(cpi, handle_intra_mode_time);
6366
#endif
6367
  // Gate intra mode evaluation if best of inter is skip except when source
6368
  // variance is extremely low and also based on max intra bsize.
6369
903k
  skip_intra_modes_in_interframe(cm, x, bsize, &search_state, sf, inter_cost,
6370
903k
                                 intra_cost);
6371
6372
903k
  const unsigned int intra_ref_frame_cost = ref_costs_single[INTRA_FRAME];
6373
903k
  search_intra_modes_in_interframe(&search_state, cpi, x, rd_cost, bsize, ctx,
6374
903k
                                   &sf_args, intra_ref_frame_cost,
6375
903k
                                   best_inter_yrd);
6376
#if CONFIG_COLLECT_COMPONENT_TIMING
6377
  end_timing(cpi, handle_intra_mode_time);
6378
#endif
6379
6380
#if CONFIG_COLLECT_COMPONENT_TIMING
6381
  start_timing(cpi, refine_winner_mode_tx_time);
6382
#endif
6383
903k
  int winner_mode_count =
6384
903k
      sf->winner_mode_sf.multi_winner_mode_type ? x->winner_mode_count : 1;
6385
  // In effect only when fast tx search speed features are enabled.
6386
903k
  refine_winner_mode_tx(
6387
903k
      cpi, x, rd_cost, bsize, ctx, &search_state.best_mode_index,
6388
903k
      &search_state.best_mbmode, yv12_mb, search_state.best_rate_y,
6389
903k
      search_state.best_rate_uv, &search_state.best_skip2, winner_mode_count);
6390
#if CONFIG_COLLECT_COMPONENT_TIMING
6391
  end_timing(cpi, refine_winner_mode_tx_time);
6392
#endif
6393
6394
  // Initialize default mode evaluation params
6395
903k
  set_mode_eval_params(cpi, x, DEFAULT_EVAL);
6396
6397
  // Only try palette mode when the best mode so far is an intra mode.
6398
903k
  const int try_palette =
6399
903k
      cpi->oxcf.tool_cfg.enable_palette &&
6400
903k
      av1_allow_palette(features->allow_screen_content_tools, mbmi->bsize) &&
6401
0
      !is_inter_mode(search_state.best_mbmode.mode) && rd_cost->rate != INT_MAX;
6402
903k
  RD_STATS this_rd_cost;
6403
903k
  int this_skippable = 0;
6404
903k
  if (try_palette) {
6405
#if CONFIG_COLLECT_COMPONENT_TIMING
6406
    start_timing(cpi, av1_search_palette_mode_time);
6407
#endif
6408
0
    this_skippable = av1_search_palette_mode(
6409
0
        &search_state.intra_search_state, cpi, x, bsize, intra_ref_frame_cost,
6410
0
        ctx, &this_rd_cost, search_state.best_rd);
6411
#if CONFIG_COLLECT_COMPONENT_TIMING
6412
    end_timing(cpi, av1_search_palette_mode_time);
6413
#endif
6414
0
    if (this_rd_cost.rdcost < search_state.best_rd) {
6415
0
      search_state.best_mode_index = THR_DC;
6416
0
      mbmi->mv[0].as_int = 0;
6417
0
      rd_cost->rate = this_rd_cost.rate;
6418
0
      rd_cost->dist = this_rd_cost.dist;
6419
0
      rd_cost->rdcost = this_rd_cost.rdcost;
6420
0
      search_state.best_rd = rd_cost->rdcost;
6421
0
      search_state.best_mbmode = *mbmi;
6422
0
      search_state.best_skip2 = 0;
6423
0
      search_state.best_mode_skippable = this_skippable;
6424
0
      av1_copy_array(ctx->tx_type_map, xd->tx_type_map, ctx->num_4x4_blk);
6425
0
    }
6426
0
  }
6427
6428
903k
  search_state.best_mbmode.skip_mode = 0;
6429
903k
  if (cm->current_frame.skip_mode_info.skip_mode_flag &&
6430
223k
      cpi->oxcf.algo_cfg.sharpness != 3 && is_comp_ref_allowed(bsize)) {
6431
223k
    const struct segmentation *const seg = &cm->seg;
6432
223k
    unsigned char segment_id = mbmi->segment_id;
6433
223k
    if (!segfeature_active(seg, segment_id, SEG_LVL_REF_FRAME)) {
6434
223k
      rd_pick_skip_mode(rd_cost, &search_state, cpi, x, bsize, yv12_mb);
6435
223k
    }
6436
223k
  }
6437
6438
  // Make sure that the ref_mv_idx is only nonzero when we're
6439
  // using a mode which can support ref_mv_idx
6440
903k
  if (search_state.best_mbmode.ref_mv_idx != 0 &&
6441
32.4k
      !(search_state.best_mbmode.mode == NEWMV ||
6442
7.86k
        search_state.best_mbmode.mode == NEW_NEWMV ||
6443
7.42k
        have_nearmv_in_inter_mode(search_state.best_mbmode.mode))) {
6444
0
    search_state.best_mbmode.ref_mv_idx = 0;
6445
0
  }
6446
6447
903k
  if (search_state.best_mode_index == THR_INVALID ||
6448
892k
      search_state.best_rd >= best_rd_so_far) {
6449
12.6k
    rd_cost->rate = INT_MAX;
6450
12.6k
    rd_cost->rdcost = INT64_MAX;
6451
12.6k
    return;
6452
12.6k
  }
6453
6454
891k
  const InterpFilter interp_filter = features->interp_filter;
6455
891k
  assert((interp_filter == SWITCHABLE) ||
6456
891k
         (interp_filter ==
6457
891k
          search_state.best_mbmode.interp_filters.as_filters.y_filter) ||
6458
891k
         !is_inter_block(&search_state.best_mbmode));
6459
891k
  assert((interp_filter == SWITCHABLE) ||
6460
891k
         (interp_filter ==
6461
891k
          search_state.best_mbmode.interp_filters.as_filters.x_filter) ||
6462
891k
         !is_inter_block(&search_state.best_mbmode));
6463
6464
891k
  if (!cpi->rc.is_src_frame_alt_ref && sf->inter_sf.adaptive_rd_thresh) {
6465
852k
    av1_update_rd_thresh_fact(
6466
852k
        cm, x->thresh_freq_fact, sf->inter_sf.adaptive_rd_thresh, bsize,
6467
852k
        search_state.best_mode_index, mode_start, mode_end, THR_DC, MAX_MODES);
6468
852k
  }
6469
6470
  // macroblock modes
6471
891k
  *mbmi = search_state.best_mbmode;
6472
891k
  txfm_info->skip_txfm |= search_state.best_skip2;
6473
6474
  // Note: this section is needed since the mode may have been forced to
6475
  // GLOBALMV by the all-zero mode handling of ref-mv.
6476
891k
  if (mbmi->mode == GLOBALMV || mbmi->mode == GLOBAL_GLOBALMV) {
6477
    // Correct the interp filters for GLOBALMV
6478
1.19k
    if (is_nontrans_global_motion(xd, xd->mi[0])) {
6479
1.19k
      int_interpfilters filters =
6480
1.19k
          av1_broadcast_interp_filter(av1_unswitchable_filter(interp_filter));
6481
1.19k
      assert(mbmi->interp_filters.as_int == filters.as_int);
6482
1.19k
      (void)filters;
6483
1.19k
    }
6484
1.19k
  }
6485
6486
891k
  txfm_info->skip_txfm |= search_state.best_mode_skippable;
6487
6488
891k
  assert(search_state.best_mode_index != THR_INVALID);
6489
6490
#if CONFIG_INTERNAL_STATS
6491
  store_coding_context(x, ctx, search_state.best_mode_index,
6492
                       search_state.best_mode_skippable);
6493
#else
6494
891k
  store_coding_context(x, ctx, search_state.best_mode_skippable);
6495
891k
#endif  // CONFIG_INTERNAL_STATS
6496
6497
891k
  if (mbmi->palette_mode_info.palette_size[1] > 0) {
6498
0
    assert(try_palette);
6499
0
    av1_restore_uv_color_map(cpi, x);
6500
0
  }
6501
891k
}
6502
6503
void av1_rd_pick_inter_mode_sb_seg_skip(const AV1_COMP *cpi,
6504
                                        TileDataEnc *tile_data, MACROBLOCK *x,
6505
                                        int mi_row, int mi_col,
6506
                                        RD_STATS *rd_cost, BLOCK_SIZE bsize,
6507
                                        PICK_MODE_CONTEXT *ctx,
6508
0
                                        int64_t best_rd_so_far) {
6509
0
  const AV1_COMMON *const cm = &cpi->common;
6510
0
  const FeatureFlags *const features = &cm->features;
6511
0
  MACROBLOCKD *const xd = &x->e_mbd;
6512
0
  MB_MODE_INFO *const mbmi = xd->mi[0];
6513
0
  unsigned char segment_id = mbmi->segment_id;
6514
0
  const int comp_pred = 0;
6515
0
  int i;
6516
0
  unsigned int ref_costs_single[REF_FRAMES];
6517
0
  unsigned int ref_costs_comp[REF_FRAMES][REF_FRAMES];
6518
0
  const ModeCosts *mode_costs = &x->mode_costs;
6519
0
  const int *comp_inter_cost =
6520
0
      mode_costs->comp_inter_cost[av1_get_reference_mode_context(xd)];
6521
0
  InterpFilter best_filter = SWITCHABLE;
6522
0
  int64_t this_rd = INT64_MAX;
6523
0
  int rate2 = 0;
6524
0
  const int64_t distortion2 = 0;
6525
0
  (void)mi_row;
6526
0
  (void)mi_col;
6527
0
  (void)tile_data;
6528
6529
0
  av1_collect_neighbors_ref_counts(xd);
6530
6531
0
  estimate_ref_frame_costs(cm, xd, mode_costs, segment_id, ref_costs_single,
6532
0
                           ref_costs_comp);
6533
6534
0
  for (i = 0; i < REF_FRAMES; ++i) x->pred_sse[i] = INT_MAX;
6535
0
  for (i = LAST_FRAME; i < REF_FRAMES; ++i) x->pred_mv_sad[i] = INT_MAX;
6536
6537
0
  rd_cost->rate = INT_MAX;
6538
6539
0
  assert(segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP));
6540
6541
0
  mbmi->palette_mode_info.palette_size[0] = 0;
6542
0
  mbmi->palette_mode_info.palette_size[1] = 0;
6543
0
  mbmi->filter_intra_mode_info.use_filter_intra = 0;
6544
0
  mbmi->mode = GLOBALMV;
6545
0
  mbmi->motion_mode = SIMPLE_TRANSLATION;
6546
0
  mbmi->uv_mode = UV_DC_PRED;
6547
0
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME))
6548
0
    mbmi->ref_frame[0] = get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
6549
0
  else
6550
0
    mbmi->ref_frame[0] = LAST_FRAME;
6551
0
  mbmi->ref_frame[1] = NONE_FRAME;
6552
0
  mbmi->mv[0].as_int =
6553
0
      gm_get_motion_vector(&cm->global_motion[mbmi->ref_frame[0]],
6554
0
                           features->allow_high_precision_mv, bsize, mi_col,
6555
0
                           mi_row, features->cur_frame_force_integer_mv)
6556
0
          .as_int;
6557
0
  mbmi->tx_size = max_txsize_lookup[bsize];
6558
0
  x->txfm_search_info.skip_txfm = 1;
6559
6560
0
  mbmi->ref_mv_idx = 0;
6561
6562
0
  mbmi->motion_mode = SIMPLE_TRANSLATION;
6563
0
  av1_count_overlappable_neighbors(cm, xd);
6564
0
  if (is_motion_variation_allowed_bsize(bsize) && !has_second_ref(mbmi)) {
6565
0
    int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
6566
0
    mbmi->num_proj_ref = av1_findSamples(cm, xd, pts, pts_inref);
6567
    // Select the samples according to motion vector difference
6568
0
    if (mbmi->num_proj_ref > 1) {
6569
0
      mbmi->num_proj_ref = av1_selectSamples(&mbmi->mv[0].as_mv, pts, pts_inref,
6570
0
                                             mbmi->num_proj_ref, bsize);
6571
0
    }
6572
0
  }
6573
6574
0
  const InterpFilter interp_filter = features->interp_filter;
6575
0
  set_default_interp_filters(mbmi, interp_filter);
6576
6577
0
  if (interp_filter != SWITCHABLE) {
6578
0
    best_filter = interp_filter;
6579
0
  } else {
6580
0
    best_filter = EIGHTTAP_REGULAR;
6581
0
    if (av1_is_interp_needed(xd)) {
6582
0
      int rs;
6583
0
      int best_rs = INT_MAX;
6584
0
      for (i = 0; i < SWITCHABLE_FILTERS; ++i) {
6585
0
        mbmi->interp_filters = av1_broadcast_interp_filter(i);
6586
0
        rs = av1_get_switchable_rate(x, xd, interp_filter,
6587
0
                                     cm->seq_params->enable_dual_filter);
6588
0
        if (rs < best_rs) {
6589
0
          best_rs = rs;
6590
0
          best_filter = mbmi->interp_filters.as_filters.y_filter;
6591
0
        }
6592
0
      }
6593
0
    }
6594
0
  }
6595
  // Set the appropriate filter
6596
0
  mbmi->interp_filters = av1_broadcast_interp_filter(best_filter);
6597
0
  rate2 += av1_get_switchable_rate(x, xd, interp_filter,
6598
0
                                   cm->seq_params->enable_dual_filter);
6599
6600
0
  if (cm->current_frame.reference_mode == REFERENCE_MODE_SELECT)
6601
0
    rate2 += comp_inter_cost[comp_pred];
6602
6603
  // Estimate the reference frame signaling cost and add it
6604
  // to the rolling cost variable.
6605
0
  rate2 += ref_costs_single[LAST_FRAME];
6606
0
  this_rd = RDCOST(x->rdmult, rate2, distortion2);
6607
6608
0
  rd_cost->rate = rate2;
6609
0
  rd_cost->dist = distortion2;
6610
0
  rd_cost->rdcost = this_rd;
6611
6612
0
  if (this_rd >= best_rd_so_far) {
6613
0
    rd_cost->rate = INT_MAX;
6614
0
    rd_cost->rdcost = INT64_MAX;
6615
0
    return;
6616
0
  }
6617
6618
0
  assert((interp_filter == SWITCHABLE) ||
6619
0
         (interp_filter == mbmi->interp_filters.as_filters.y_filter));
6620
6621
0
  if (cpi->sf.inter_sf.adaptive_rd_thresh) {
6622
0
    av1_update_rd_thresh_fact(cm, x->thresh_freq_fact,
6623
0
                              cpi->sf.inter_sf.adaptive_rd_thresh, bsize,
6624
0
                              THR_GLOBALMV, THR_INTER_MODE_START,
6625
0
                              THR_INTER_MODE_END, THR_DC, MAX_MODES);
6626
0
  }
6627
6628
#if CONFIG_INTERNAL_STATS
6629
  store_coding_context(x, ctx, THR_GLOBALMV, 0);
6630
#else
6631
0
  store_coding_context(x, ctx, 0);
6632
0
#endif  // CONFIG_INTERNAL_STATS
6633
0
}
6634
6635
/*!\cond */
6636
struct calc_target_weighted_pred_ctxt {
6637
  const OBMCBuffer *obmc_buffer;
6638
  const uint8_t *tmp;
6639
  int tmp_stride;
6640
  int overlap;
6641
};
6642
/*!\endcond */
6643
6644
static inline void calc_target_weighted_pred_above(
6645
    MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size,
6646
0
    int dir, MB_MODE_INFO *nb_mi, void *fun_ctxt, const int num_planes) {
6647
0
  (void)nb_mi;
6648
0
  (void)num_planes;
6649
0
  (void)rel_mi_row;
6650
0
  (void)dir;
6651
6652
0
  struct calc_target_weighted_pred_ctxt *ctxt =
6653
0
      (struct calc_target_weighted_pred_ctxt *)fun_ctxt;
6654
6655
0
  const int bw = xd->width << MI_SIZE_LOG2;
6656
0
  const uint8_t *const mask1d = av1_get_obmc_mask(ctxt->overlap);
6657
6658
0
  int32_t *wsrc = ctxt->obmc_buffer->wsrc + (rel_mi_col * MI_SIZE);
6659
0
  int32_t *mask = ctxt->obmc_buffer->mask + (rel_mi_col * MI_SIZE);
6660
0
  const uint8_t *tmp = ctxt->tmp + rel_mi_col * MI_SIZE;
6661
0
  const int is_hbd = is_cur_buf_hbd(xd);
6662
6663
0
  if (!is_hbd) {
6664
0
    for (int row = 0; row < ctxt->overlap; ++row) {
6665
0
      const uint8_t m0 = mask1d[row];
6666
0
      const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
6667
0
      for (int col = 0; col < op_mi_size * MI_SIZE; ++col) {
6668
0
        wsrc[col] = m1 * tmp[col];
6669
0
        mask[col] = m0;
6670
0
      }
6671
0
      wsrc += bw;
6672
0
      mask += bw;
6673
0
      tmp += ctxt->tmp_stride;
6674
0
    }
6675
0
  } else {
6676
0
    const uint16_t *tmp16 = CONVERT_TO_SHORTPTR(tmp);
6677
6678
0
    for (int row = 0; row < ctxt->overlap; ++row) {
6679
0
      const uint8_t m0 = mask1d[row];
6680
0
      const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
6681
0
      for (int col = 0; col < op_mi_size * MI_SIZE; ++col) {
6682
0
        wsrc[col] = m1 * tmp16[col];
6683
0
        mask[col] = m0;
6684
0
      }
6685
0
      wsrc += bw;
6686
0
      mask += bw;
6687
0
      tmp16 += ctxt->tmp_stride;
6688
0
    }
6689
0
  }
6690
0
}
6691
6692
static inline void calc_target_weighted_pred_left(
6693
    MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size,
6694
0
    int dir, MB_MODE_INFO *nb_mi, void *fun_ctxt, const int num_planes) {
6695
0
  (void)nb_mi;
6696
0
  (void)num_planes;
6697
0
  (void)rel_mi_col;
6698
0
  (void)dir;
6699
6700
0
  struct calc_target_weighted_pred_ctxt *ctxt =
6701
0
      (struct calc_target_weighted_pred_ctxt *)fun_ctxt;
6702
6703
0
  const int bw = xd->width << MI_SIZE_LOG2;
6704
0
  const uint8_t *const mask1d = av1_get_obmc_mask(ctxt->overlap);
6705
6706
0
  int32_t *wsrc = ctxt->obmc_buffer->wsrc + (rel_mi_row * MI_SIZE * bw);
6707
0
  int32_t *mask = ctxt->obmc_buffer->mask + (rel_mi_row * MI_SIZE * bw);
6708
0
  const uint8_t *tmp = ctxt->tmp + (rel_mi_row * MI_SIZE * ctxt->tmp_stride);
6709
0
  const int is_hbd = is_cur_buf_hbd(xd);
6710
6711
0
  if (!is_hbd) {
6712
0
    for (int row = 0; row < op_mi_size * MI_SIZE; ++row) {
6713
0
      for (int col = 0; col < ctxt->overlap; ++col) {
6714
0
        const uint8_t m0 = mask1d[col];
6715
0
        const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
6716
0
        wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
6717
0
                    (tmp[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
6718
0
        mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
6719
0
      }
6720
0
      wsrc += bw;
6721
0
      mask += bw;
6722
0
      tmp += ctxt->tmp_stride;
6723
0
    }
6724
0
  } else {
6725
0
    const uint16_t *tmp16 = CONVERT_TO_SHORTPTR(tmp);
6726
6727
0
    for (int row = 0; row < op_mi_size * MI_SIZE; ++row) {
6728
0
      for (int col = 0; col < ctxt->overlap; ++col) {
6729
0
        const uint8_t m0 = mask1d[col];
6730
0
        const uint8_t m1 = AOM_BLEND_A64_MAX_ALPHA - m0;
6731
0
        wsrc[col] = (wsrc[col] >> AOM_BLEND_A64_ROUND_BITS) * m0 +
6732
0
                    (tmp16[col] << AOM_BLEND_A64_ROUND_BITS) * m1;
6733
0
        mask[col] = (mask[col] >> AOM_BLEND_A64_ROUND_BITS) * m0;
6734
0
      }
6735
0
      wsrc += bw;
6736
0
      mask += bw;
6737
0
      tmp16 += ctxt->tmp_stride;
6738
0
    }
6739
0
  }
6740
0
}
6741
6742
// This function has a structure similar to av1_build_obmc_inter_prediction
6743
//
6744
// The OBMC predictor is computed as:
6745
//
6746
//  PObmc(x,y) =
6747
//    AOM_BLEND_A64(Mh(x),
6748
//                  AOM_BLEND_A64(Mv(y), P(x,y), PAbove(x,y)),
6749
//                  PLeft(x, y))
6750
//
6751
// Scaling up by AOM_BLEND_A64_MAX_ALPHA ** 2 and omitting the intermediate
6752
// rounding, this can be written as:
6753
//
6754
//  AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * Pobmc(x,y) =
6755
//    Mh(x) * Mv(y) * P(x,y) +
6756
//      Mh(x) * Cv(y) * Pabove(x,y) +
6757
//      AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
6758
//
6759
// Where :
6760
//
6761
//  Cv(y) = AOM_BLEND_A64_MAX_ALPHA - Mv(y)
6762
//  Ch(y) = AOM_BLEND_A64_MAX_ALPHA - Mh(y)
6763
//
6764
// This function computes 'wsrc' and 'mask' as:
6765
//
6766
//  wsrc(x, y) =
6767
//    AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA * src(x, y) -
6768
//      Mh(x) * Cv(y) * Pabove(x,y) +
6769
//      AOM_BLEND_A64_MAX_ALPHA * Ch(x) * PLeft(x, y)
6770
//
6771
//  mask(x, y) = Mh(x) * Mv(y)
6772
//
6773
// These can then be used to efficiently approximate the error for any
6774
// predictor P in the context of the provided neighbouring predictors by
6775
// computing:
6776
//
6777
//  error(x, y) =
6778
//    wsrc(x, y) - mask(x, y) * P(x, y) / (AOM_BLEND_A64_MAX_ALPHA ** 2)
6779
//
6780
static inline void calc_target_weighted_pred(
6781
    const AV1_COMMON *cm, const MACROBLOCK *x, const MACROBLOCKD *xd,
6782
    const uint8_t *above, int above_stride, const uint8_t *left,
6783
0
    int left_stride) {
6784
0
  const BLOCK_SIZE bsize = xd->mi[0]->bsize;
6785
0
  const int bw = xd->width << MI_SIZE_LOG2;
6786
0
  const int bh = xd->height << MI_SIZE_LOG2;
6787
0
  const OBMCBuffer *obmc_buffer = &x->obmc_buffer;
6788
0
  int32_t *mask_buf = obmc_buffer->mask;
6789
0
  int32_t *wsrc_buf = obmc_buffer->wsrc;
6790
6791
0
  const int is_hbd = is_cur_buf_hbd(xd);
6792
0
  const int src_scale = AOM_BLEND_A64_MAX_ALPHA * AOM_BLEND_A64_MAX_ALPHA;
6793
6794
  // plane 0 should not be sub-sampled
6795
0
  assert(xd->plane[0].subsampling_x == 0);
6796
0
  assert(xd->plane[0].subsampling_y == 0);
6797
6798
0
  av1_zero_array(wsrc_buf, bw * bh);
6799
0
  for (int i = 0; i < bw * bh; ++i) mask_buf[i] = AOM_BLEND_A64_MAX_ALPHA;
6800
6801
  // handle above row
6802
0
  if (xd->up_available) {
6803
0
    const int overlap =
6804
0
        AOMMIN(block_size_high[bsize], block_size_high[BLOCK_64X64]) >> 1;
6805
0
    struct calc_target_weighted_pred_ctxt ctxt = { obmc_buffer, above,
6806
0
                                                   above_stride, overlap };
6807
0
    foreach_overlappable_nb_above(cm, (MACROBLOCKD *)xd,
6808
0
                                  max_neighbor_obmc[mi_size_wide_log2[bsize]],
6809
0
                                  calc_target_weighted_pred_above, &ctxt);
6810
0
  }
6811
6812
0
  for (int i = 0; i < bw * bh; ++i) {
6813
0
    wsrc_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
6814
0
    mask_buf[i] *= AOM_BLEND_A64_MAX_ALPHA;
6815
0
  }
6816
6817
  // handle left column
6818
0
  if (xd->left_available) {
6819
0
    const int overlap =
6820
0
        AOMMIN(block_size_wide[bsize], block_size_wide[BLOCK_64X64]) >> 1;
6821
0
    struct calc_target_weighted_pred_ctxt ctxt = { obmc_buffer, left,
6822
0
                                                   left_stride, overlap };
6823
0
    foreach_overlappable_nb_left(cm, (MACROBLOCKD *)xd,
6824
0
                                 max_neighbor_obmc[mi_size_high_log2[bsize]],
6825
0
                                 calc_target_weighted_pred_left, &ctxt);
6826
0
  }
6827
6828
0
  if (!is_hbd) {
6829
0
    const uint8_t *src = x->plane[0].src.buf;
6830
6831
0
    for (int row = 0; row < bh; ++row) {
6832
0
      for (int col = 0; col < bw; ++col) {
6833
0
        wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
6834
0
      }
6835
0
      wsrc_buf += bw;
6836
0
      src += x->plane[0].src.stride;
6837
0
    }
6838
0
  } else {
6839
0
    const uint16_t *src = CONVERT_TO_SHORTPTR(x->plane[0].src.buf);
6840
6841
0
    for (int row = 0; row < bh; ++row) {
6842
0
      for (int col = 0; col < bw; ++col) {
6843
0
        wsrc_buf[col] = src[col] * src_scale - wsrc_buf[col];
6844
0
      }
6845
0
      wsrc_buf += bw;
6846
0
      src += x->plane[0].src.stride;
6847
0
    }
6848
0
  }
6849
0
}