Coverage Report

Created: 2026-06-14 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/aom/av1/common/reconinter.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 <stdio.h>
14
#include <limits.h>
15
16
#include "config/aom_config.h"
17
#include "config/aom_dsp_rtcd.h"
18
#include "config/aom_scale_rtcd.h"
19
20
#include "aom/aom_integer.h"
21
#include "aom_dsp/blend.h"
22
#include "aom_ports/aom_once.h"
23
24
#include "av1/common/av1_common_int.h"
25
#include "av1/common/blockd.h"
26
#include "av1/common/mvref_common.h"
27
#include "av1/common/obmc.h"
28
#include "av1/common/reconinter.h"
29
#include "av1/common/reconintra.h"
30
31
// This function will determine whether or not to create a warped
32
// prediction.
33
static int allow_warp(const MB_MODE_INFO *const mbmi,
34
                      const WarpTypesAllowed *const warp_types,
35
                      const WarpedMotionParams *const gm_params,
36
                      int build_for_obmc, const struct scale_factors *const sf,
37
185k
                      WarpedMotionParams *final_warp_params) {
38
  // Note: As per the spec, we must test the fixed point scales here, which are
39
  // at a higher precision (1 << 14) than the xs and ys in subpel_params (that
40
  // have 1 << 10 precision).
41
185k
  if (av1_is_scaled(sf)) return 0;
42
43
177k
  if (final_warp_params != NULL) *final_warp_params = default_warp_params;
44
45
177k
  if (build_for_obmc) return 0;
46
47
177k
  if (warp_types->local_warp_allowed && !mbmi->wm_params.invalid) {
48
6.36k
    if (final_warp_params != NULL) *final_warp_params = mbmi->wm_params;
49
6.36k
    return 1;
50
171k
  } else if (warp_types->global_warp_allowed && !gm_params->invalid) {
51
12.5k
    if (final_warp_params != NULL) *final_warp_params = *gm_params;
52
12.5k
    return 1;
53
12.5k
  }
54
55
158k
  return 0;
56
177k
}
57
58
void av1_init_warp_params(InterPredParams *inter_pred_params,
59
                          const WarpTypesAllowed *warp_types, int ref,
60
404k
                          const MACROBLOCKD *xd, const MB_MODE_INFO *mi) {
61
404k
  if (inter_pred_params->block_height < 8 || inter_pred_params->block_width < 8)
62
199k
    return;
63
64
205k
  if (xd->cur_frame_force_integer_mv) return;
65
66
185k
  if (allow_warp(mi, warp_types, &xd->global_motion[mi->ref_frame[ref]], 0,
67
185k
                 inter_pred_params->scale_factors,
68
185k
                 &inter_pred_params->warp_params)) {
69
#if CONFIG_REALTIME_ONLY && !CONFIG_AV1_DECODER
70
    aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_FEATURE,
71
                       "Warped motion is disabled in realtime only build.");
72
#endif  // CONFIG_REALTIME_ONLY && !CONFIG_AV1_DECODER
73
18.9k
    inter_pred_params->mode = WARP_PRED;
74
18.9k
  }
75
185k
}
76
77
void av1_make_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
78
                              int dst_stride,
79
                              InterPredParams *inter_pred_params,
80
419k
                              const SubpelParams *subpel_params) {
81
419k
  assert(IMPLIES(inter_pred_params->conv_params.is_compound,
82
419k
                 inter_pred_params->conv_params.dst != NULL));
83
84
419k
  if (inter_pred_params->mode == TRANSLATION_PRED) {
85
400k
#if CONFIG_AV1_HIGHBITDEPTH
86
400k
    if (inter_pred_params->use_hbd_buf) {
87
194k
      highbd_inter_predictor(src, src_stride, dst, dst_stride, subpel_params,
88
194k
                             inter_pred_params->block_width,
89
194k
                             inter_pred_params->block_height,
90
194k
                             &inter_pred_params->conv_params,
91
194k
                             inter_pred_params->interp_filter_params,
92
194k
                             inter_pred_params->bit_depth);
93
205k
    } else {
94
205k
      inter_predictor(src, src_stride, dst, dst_stride, subpel_params,
95
205k
                      inter_pred_params->block_width,
96
205k
                      inter_pred_params->block_height,
97
205k
                      &inter_pred_params->conv_params,
98
205k
                      inter_pred_params->interp_filter_params);
99
205k
    }
100
#else
101
    inter_predictor(src, src_stride, dst, dst_stride, subpel_params,
102
                    inter_pred_params->block_width,
103
                    inter_pred_params->block_height,
104
                    &inter_pred_params->conv_params,
105
                    inter_pred_params->interp_filter_params);
106
#endif
107
400k
  }
108
18.9k
#if !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
109
  // TODO(jingning): av1_warp_plane() can be further cleaned up.
110
18.9k
  else if (inter_pred_params->mode == WARP_PRED) {
111
18.9k
    av1_warp_plane(
112
18.9k
        &inter_pred_params->warp_params, inter_pred_params->use_hbd_buf,
113
18.9k
        inter_pred_params->bit_depth, inter_pred_params->ref_frame_buf.buf0,
114
18.9k
        inter_pred_params->ref_frame_buf.width,
115
18.9k
        inter_pred_params->ref_frame_buf.height,
116
18.9k
        inter_pred_params->ref_frame_buf.stride, dst,
117
18.9k
        inter_pred_params->pix_col, inter_pred_params->pix_row,
118
18.9k
        inter_pred_params->block_width, inter_pred_params->block_height,
119
18.9k
        dst_stride, inter_pred_params->subsampling_x,
120
18.9k
        inter_pred_params->subsampling_y, &inter_pred_params->conv_params);
121
18.9k
  }
122
0
#endif  // !CONFIG_REALTIME_ONLY || CONFIG_AV1_DECODER
123
0
  else {
124
0
    assert(0 && "Unsupported inter_pred_params->mode");
125
0
  }
126
419k
}
127
128
static const uint8_t wedge_master_oblique_odd[MASK_MASTER_SIZE] = {
129
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
130
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  6,  18,
131
  37, 53, 60, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
132
  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
133
};
134
static const uint8_t wedge_master_oblique_even[MASK_MASTER_SIZE] = {
135
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
136
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  4,  11, 27,
137
  46, 58, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
138
  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
139
};
140
static const uint8_t wedge_master_vertical[MASK_MASTER_SIZE] = {
141
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
142
  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  2,  7,  21,
143
  43, 57, 62, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
144
  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
145
};
146
147
static inline void shift_copy(const uint8_t *src, uint8_t *dst, int shift,
148
128
                              int width) {
149
128
  if (shift >= 0) {
150
66
    memcpy(dst + shift, src, width - shift);
151
66
    memset(dst, src[0], shift);
152
66
  } else {
153
62
    shift = -shift;
154
62
    memcpy(dst, src + shift, width - shift);
155
62
    memset(dst + width - shift, src[width - 1], shift);
156
62
  }
157
128
}
158
159
/* clang-format off */
160
DECLARE_ALIGNED(16, static uint8_t,
161
                wedge_signflip_lookup[BLOCK_SIZES_ALL][MAX_WEDGE_TYPES]) = {
162
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
163
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
164
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
165
  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
166
  { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
167
  { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
168
  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
169
  { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
170
  { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
171
  { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, },
172
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
173
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
174
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
175
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
176
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
177
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
178
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
179
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
180
  { 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, },
181
  { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, },
182
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
183
  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },  // not used
184
};
185
/* clang-format on */
186
187
// [negative][direction]
188
DECLARE_ALIGNED(
189
    16, static uint8_t,
190
    wedge_mask_obl[2][WEDGE_DIRECTIONS][MASK_MASTER_SIZE * MASK_MASTER_SIZE]);
191
192
// 4 * MAX_WEDGE_SQUARE is an easy to compute and fairly tight upper bound
193
// on the sum of all mask sizes up to an including MAX_WEDGE_SQUARE.
194
DECLARE_ALIGNED(16, static uint8_t,
195
                wedge_mask_buf[2 * MAX_WEDGE_TYPES * 4 * MAX_WEDGE_SQUARE]);
196
197
DECLARE_ALIGNED(16, static uint8_t,
198
                smooth_interintra_mask_buf[INTERINTRA_MODES][BLOCK_SIZES_ALL]
199
                                          [MAX_WEDGE_SQUARE]);
200
201
static wedge_masks_type wedge_masks[BLOCK_SIZES_ALL][2];
202
203
static const wedge_code_type wedge_codebook_16_hgtw[16] = {
204
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
205
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
206
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 4 },
207
  { WEDGE_HORIZONTAL, 4, 6 }, { WEDGE_VERTICAL, 4, 4 },
208
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
209
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
210
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
211
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
212
};
213
214
static const wedge_code_type wedge_codebook_16_hltw[16] = {
215
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
216
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
217
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 4, 4 },
218
  { WEDGE_VERTICAL, 6, 4 },   { WEDGE_HORIZONTAL, 4, 4 },
219
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
220
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
221
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
222
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
223
};
224
225
static const wedge_code_type wedge_codebook_16_heqw[16] = {
226
  { WEDGE_OBLIQUE27, 4, 4 },  { WEDGE_OBLIQUE63, 4, 4 },
227
  { WEDGE_OBLIQUE117, 4, 4 }, { WEDGE_OBLIQUE153, 4, 4 },
228
  { WEDGE_HORIZONTAL, 4, 2 }, { WEDGE_HORIZONTAL, 4, 6 },
229
  { WEDGE_VERTICAL, 2, 4 },   { WEDGE_VERTICAL, 6, 4 },
230
  { WEDGE_OBLIQUE27, 4, 2 },  { WEDGE_OBLIQUE27, 4, 6 },
231
  { WEDGE_OBLIQUE153, 4, 2 }, { WEDGE_OBLIQUE153, 4, 6 },
232
  { WEDGE_OBLIQUE63, 2, 4 },  { WEDGE_OBLIQUE63, 6, 4 },
233
  { WEDGE_OBLIQUE117, 2, 4 }, { WEDGE_OBLIQUE117, 6, 4 },
234
};
235
236
const wedge_params_type av1_wedge_params_lookup[BLOCK_SIZES_ALL] = {
237
  { 0, NULL, NULL, NULL },
238
  { 0, NULL, NULL, NULL },
239
  { 0, NULL, NULL, NULL },
240
  { MAX_WEDGE_TYPES, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_8X8],
241
    wedge_masks[BLOCK_8X8] },
242
  { MAX_WEDGE_TYPES, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X16],
243
    wedge_masks[BLOCK_8X16] },
244
  { MAX_WEDGE_TYPES, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_16X8],
245
    wedge_masks[BLOCK_16X8] },
246
  { MAX_WEDGE_TYPES, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_16X16],
247
    wedge_masks[BLOCK_16X16] },
248
  { MAX_WEDGE_TYPES, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_16X32],
249
    wedge_masks[BLOCK_16X32] },
250
  { MAX_WEDGE_TYPES, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X16],
251
    wedge_masks[BLOCK_32X16] },
252
  { MAX_WEDGE_TYPES, wedge_codebook_16_heqw, wedge_signflip_lookup[BLOCK_32X32],
253
    wedge_masks[BLOCK_32X32] },
254
  { 0, NULL, NULL, NULL },
255
  { 0, NULL, NULL, NULL },
256
  { 0, NULL, NULL, NULL },
257
  { 0, NULL, NULL, NULL },
258
  { 0, NULL, NULL, NULL },
259
  { 0, NULL, NULL, NULL },
260
  { 0, NULL, NULL, NULL },
261
  { 0, NULL, NULL, NULL },
262
  { MAX_WEDGE_TYPES, wedge_codebook_16_hgtw, wedge_signflip_lookup[BLOCK_8X32],
263
    wedge_masks[BLOCK_8X32] },
264
  { MAX_WEDGE_TYPES, wedge_codebook_16_hltw, wedge_signflip_lookup[BLOCK_32X8],
265
    wedge_masks[BLOCK_32X8] },
266
  { 0, NULL, NULL, NULL },
267
  { 0, NULL, NULL, NULL },
268
};
269
270
static const uint8_t *get_wedge_mask_inplace(int wedge_index, int neg,
271
576
                                             BLOCK_SIZE sb_type) {
272
576
  const uint8_t *master;
273
576
  const int bh = block_size_high[sb_type];
274
576
  const int bw = block_size_wide[sb_type];
275
576
  const wedge_code_type *a =
276
576
      av1_wedge_params_lookup[sb_type].codebook + wedge_index;
277
576
  int woff, hoff;
278
576
  const uint8_t wsignflip =
279
576
      av1_wedge_params_lookup[sb_type].signflip[wedge_index];
280
281
576
  assert(wedge_index >= 0 && wedge_index < get_wedge_types_lookup(sb_type));
282
576
  woff = (a->x_offset * bw) >> 3;
283
576
  hoff = (a->y_offset * bh) >> 3;
284
576
  master = wedge_mask_obl[neg ^ wsignflip][a->direction] +
285
576
           MASK_MASTER_STRIDE * (MASK_MASTER_SIZE / 2 - hoff) +
286
576
           MASK_MASTER_SIZE / 2 - woff;
287
576
  return master;
288
576
}
289
290
const uint8_t *av1_get_compound_type_mask(
291
3.55k
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type) {
292
3.55k
  (void)sb_type;
293
3.55k
  switch (comp_data->type) {
294
2.67k
    case COMPOUND_WEDGE:
295
2.67k
      return av1_get_contiguous_soft_mask(comp_data->wedge_index,
296
2.67k
                                          comp_data->wedge_sign, sb_type);
297
882
    default: return comp_data->seg_mask;
298
3.55k
  }
299
3.55k
}
300
301
static inline void diffwtd_mask_d16(uint8_t *mask, int which_inverse,
302
                                    int mask_base, const CONV_BUF_TYPE *src0,
303
                                    int src0_stride, const CONV_BUF_TYPE *src1,
304
                                    int src1_stride, int h, int w,
305
302
                                    ConvolveParams *conv_params, int bd) {
306
302
  int round =
307
302
      2 * FILTER_BITS - conv_params->round_0 - conv_params->round_1 + (bd - 8);
308
302
  int i, j, m, diff;
309
4.35k
  for (i = 0; i < h; ++i) {
310
103k
    for (j = 0; j < w; ++j) {
311
99.3k
      diff = abs(src0[i * src0_stride + j] - src1[i * src1_stride + j]);
312
99.3k
      diff = ROUND_POWER_OF_TWO(diff, round);
313
99.3k
      m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
314
99.3k
      mask[i * w + j] = which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
315
99.3k
    }
316
4.04k
  }
317
302
}
318
319
void av1_build_compound_diffwtd_mask_d16_c(
320
    uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const CONV_BUF_TYPE *src0,
321
    int src0_stride, const CONV_BUF_TYPE *src1, int src1_stride, int h, int w,
322
302
    ConvolveParams *conv_params, int bd) {
323
302
  switch (mask_type) {
324
217
    case DIFFWTD_38:
325
217
      diffwtd_mask_d16(mask, 0, 38, src0, src0_stride, src1, src1_stride, h, w,
326
217
                       conv_params, bd);
327
217
      break;
328
85
    case DIFFWTD_38_INV:
329
85
      diffwtd_mask_d16(mask, 1, 38, src0, src0_stride, src1, src1_stride, h, w,
330
85
                       conv_params, bd);
331
85
      break;
332
0
    default: assert(0);
333
302
  }
334
302
}
335
336
static inline void diffwtd_mask(uint8_t *mask, int which_inverse, int mask_base,
337
                                const uint8_t *src0, int src0_stride,
338
                                const uint8_t *src1, int src1_stride, int h,
339
0
                                int w) {
340
0
  int i, j, m, diff;
341
0
  for (i = 0; i < h; ++i) {
342
0
    for (j = 0; j < w; ++j) {
343
0
      diff =
344
0
          abs((int)src0[i * src0_stride + j] - (int)src1[i * src1_stride + j]);
345
0
      m = clamp(mask_base + (diff / DIFF_FACTOR), 0, AOM_BLEND_A64_MAX_ALPHA);
346
0
      mask[i * w + j] = which_inverse ? AOM_BLEND_A64_MAX_ALPHA - m : m;
347
0
    }
348
0
  }
349
0
}
350
351
void av1_build_compound_diffwtd_mask_c(uint8_t *mask,
352
                                       DIFFWTD_MASK_TYPE mask_type,
353
                                       const uint8_t *src0, int src0_stride,
354
                                       const uint8_t *src1, int src1_stride,
355
0
                                       int h, int w) {
356
0
  switch (mask_type) {
357
0
    case DIFFWTD_38:
358
0
      diffwtd_mask(mask, 0, 38, src0, src0_stride, src1, src1_stride, h, w);
359
0
      break;
360
0
    case DIFFWTD_38_INV:
361
0
      diffwtd_mask(mask, 1, 38, src0, src0_stride, src1, src1_stride, h, w);
362
0
      break;
363
0
    default: assert(0);
364
0
  }
365
0
}
366
367
#if CONFIG_AV1_HIGHBITDEPTH
368
static AOM_FORCE_INLINE void diffwtd_mask_highbd(
369
    uint8_t *mask, int which_inverse, int mask_base, const uint16_t *src0,
370
    int src0_stride, const uint16_t *src1, int src1_stride, int h, int w,
371
0
    const unsigned int bd) {
372
0
  assert(bd >= 8);
373
0
  if (bd == 8) {
374
0
    if (which_inverse) {
375
0
      for (int i = 0; i < h; ++i) {
376
0
        for (int j = 0; j < w; ++j) {
377
0
          int diff = abs((int)src0[j] - (int)src1[j]) / DIFF_FACTOR;
378
0
          unsigned int m = negative_to_zero(mask_base + diff);
379
0
          m = AOMMIN(m, AOM_BLEND_A64_MAX_ALPHA);
380
0
          mask[j] = AOM_BLEND_A64_MAX_ALPHA - m;
381
0
        }
382
0
        src0 += src0_stride;
383
0
        src1 += src1_stride;
384
0
        mask += w;
385
0
      }
386
0
    } else {
387
0
      for (int i = 0; i < h; ++i) {
388
0
        for (int j = 0; j < w; ++j) {
389
0
          int diff = abs((int)src0[j] - (int)src1[j]) / DIFF_FACTOR;
390
0
          unsigned int m = negative_to_zero(mask_base + diff);
391
0
          m = AOMMIN(m, AOM_BLEND_A64_MAX_ALPHA);
392
0
          mask[j] = m;
393
0
        }
394
0
        src0 += src0_stride;
395
0
        src1 += src1_stride;
396
0
        mask += w;
397
0
      }
398
0
    }
399
0
  } else {
400
0
    const unsigned int bd_shift = bd - 8;
401
0
    if (which_inverse) {
402
0
      for (int i = 0; i < h; ++i) {
403
0
        for (int j = 0; j < w; ++j) {
404
0
          int diff =
405
0
              (abs((int)src0[j] - (int)src1[j]) >> bd_shift) / DIFF_FACTOR;
406
0
          unsigned int m = negative_to_zero(mask_base + diff);
407
0
          m = AOMMIN(m, AOM_BLEND_A64_MAX_ALPHA);
408
0
          mask[j] = AOM_BLEND_A64_MAX_ALPHA - m;
409
0
        }
410
0
        src0 += src0_stride;
411
0
        src1 += src1_stride;
412
0
        mask += w;
413
0
      }
414
0
    } else {
415
0
      for (int i = 0; i < h; ++i) {
416
0
        for (int j = 0; j < w; ++j) {
417
0
          int diff =
418
0
              (abs((int)src0[j] - (int)src1[j]) >> bd_shift) / DIFF_FACTOR;
419
0
          unsigned int m = negative_to_zero(mask_base + diff);
420
0
          m = AOMMIN(m, AOM_BLEND_A64_MAX_ALPHA);
421
0
          mask[j] = m;
422
0
        }
423
0
        src0 += src0_stride;
424
0
        src1 += src1_stride;
425
0
        mask += w;
426
0
      }
427
0
    }
428
0
  }
429
0
}
430
431
void av1_build_compound_diffwtd_mask_highbd_c(
432
    uint8_t *mask, DIFFWTD_MASK_TYPE mask_type, const uint8_t *src0,
433
    int src0_stride, const uint8_t *src1, int src1_stride, int h, int w,
434
0
    int bd) {
435
0
  switch (mask_type) {
436
0
    case DIFFWTD_38:
437
0
      diffwtd_mask_highbd(mask, 0, 38, CONVERT_TO_SHORTPTR(src0), src0_stride,
438
0
                          CONVERT_TO_SHORTPTR(src1), src1_stride, h, w, bd);
439
0
      break;
440
0
    case DIFFWTD_38_INV:
441
0
      diffwtd_mask_highbd(mask, 1, 38, CONVERT_TO_SHORTPTR(src0), src0_stride,
442
0
                          CONVERT_TO_SHORTPTR(src1), src1_stride, h, w, bd);
443
0
      break;
444
0
    default: assert(0);
445
0
  }
446
0
}
447
#endif  // CONFIG_AV1_HIGHBITDEPTH
448
449
2
static inline void init_wedge_master_masks(void) {
450
2
  int i, j;
451
2
  const int w = MASK_MASTER_SIZE;
452
2
  const int h = MASK_MASTER_SIZE;
453
2
  const int stride = MASK_MASTER_STRIDE;
454
  // Note: index [0] stores the masters, and [1] its complement.
455
  // Generate prototype by shifting the masters
456
2
  int shift = h / 4;
457
66
  for (i = 0; i < h; i += 2) {
458
64
    shift_copy(wedge_master_oblique_even,
459
64
               &wedge_mask_obl[0][WEDGE_OBLIQUE63][i * stride], shift,
460
64
               MASK_MASTER_SIZE);
461
64
    shift--;
462
64
    shift_copy(wedge_master_oblique_odd,
463
64
               &wedge_mask_obl[0][WEDGE_OBLIQUE63][(i + 1) * stride], shift,
464
64
               MASK_MASTER_SIZE);
465
64
    memcpy(&wedge_mask_obl[0][WEDGE_VERTICAL][i * stride],
466
64
           wedge_master_vertical,
467
64
           MASK_MASTER_SIZE * sizeof(wedge_master_vertical[0]));
468
64
    memcpy(&wedge_mask_obl[0][WEDGE_VERTICAL][(i + 1) * stride],
469
64
           wedge_master_vertical,
470
64
           MASK_MASTER_SIZE * sizeof(wedge_master_vertical[0]));
471
64
  }
472
473
130
  for (i = 0; i < h; ++i) {
474
8.32k
    for (j = 0; j < w; ++j) {
475
8.19k
      const int msk = wedge_mask_obl[0][WEDGE_OBLIQUE63][i * stride + j];
476
8.19k
      wedge_mask_obl[0][WEDGE_OBLIQUE27][j * stride + i] = msk;
477
8.19k
      wedge_mask_obl[0][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
478
8.19k
          wedge_mask_obl[0][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] =
479
8.19k
              (1 << WEDGE_WEIGHT_BITS) - msk;
480
8.19k
      wedge_mask_obl[1][WEDGE_OBLIQUE63][i * stride + j] =
481
8.19k
          wedge_mask_obl[1][WEDGE_OBLIQUE27][j * stride + i] =
482
8.19k
              (1 << WEDGE_WEIGHT_BITS) - msk;
483
8.19k
      wedge_mask_obl[1][WEDGE_OBLIQUE117][i * stride + w - 1 - j] =
484
8.19k
          wedge_mask_obl[1][WEDGE_OBLIQUE153][(w - 1 - j) * stride + i] = msk;
485
8.19k
      const int mskx = wedge_mask_obl[0][WEDGE_VERTICAL][i * stride + j];
486
8.19k
      wedge_mask_obl[0][WEDGE_HORIZONTAL][j * stride + i] = mskx;
487
8.19k
      wedge_mask_obl[1][WEDGE_VERTICAL][i * stride + j] =
488
8.19k
          wedge_mask_obl[1][WEDGE_HORIZONTAL][j * stride + i] =
489
8.19k
              (1 << WEDGE_WEIGHT_BITS) - mskx;
490
8.19k
    }
491
128
  }
492
2
}
493
494
2
static inline void init_wedge_masks(void) {
495
2
  uint8_t *dst = wedge_mask_buf;
496
2
  BLOCK_SIZE bsize;
497
2
  memset(wedge_masks, 0, sizeof(wedge_masks));
498
46
  for (bsize = BLOCK_4X4; bsize < BLOCK_SIZES_ALL; ++bsize) {
499
44
    const wedge_params_type *wedge_params = &av1_wedge_params_lookup[bsize];
500
44
    const int wtypes = wedge_params->wedge_types;
501
44
    if (wtypes == 0) continue;
502
18
    const uint8_t *mask;
503
18
    const int bw = block_size_wide[bsize];
504
18
    const int bh = block_size_high[bsize];
505
18
    int w;
506
306
    for (w = 0; w < wtypes; ++w) {
507
288
      mask = get_wedge_mask_inplace(w, 0, bsize);
508
288
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw /* dst_stride */, bw,
509
288
                        bh);
510
288
      wedge_params->masks[0][w] = dst;
511
288
      dst += bw * bh;
512
513
288
      mask = get_wedge_mask_inplace(w, 1, bsize);
514
288
      aom_convolve_copy(mask, MASK_MASTER_STRIDE, dst, bw /* dst_stride */, bw,
515
288
                        bh);
516
288
      wedge_params->masks[1][w] = dst;
517
288
      dst += bw * bh;
518
288
    }
519
18
    assert(sizeof(wedge_mask_buf) >= (size_t)(dst - wedge_mask_buf));
520
18
  }
521
2
}
522
523
/* clang-format off */
524
static const uint8_t ii_weights1d[MAX_SB_SIZE] = {
525
  60, 58, 56, 54, 52, 50, 48, 47, 45, 44, 42, 41, 39, 38, 37, 35, 34, 33, 32,
526
  31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 22, 21, 20, 19, 19, 18, 18, 17, 16,
527
  16, 15, 15, 14, 14, 13, 13, 12, 12, 12, 11, 11, 10, 10, 10,  9,  9,  9,  8,
528
  8,  8,  8,  7,  7,  7,  7,  6,  6,  6,  6,  6,  5,  5,  5,  5,  5,  4,  4,
529
  4,  4,  4,  4,  4,  4,  3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  2,  2,
530
  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,
531
  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1
532
};
533
static uint8_t ii_size_scales[BLOCK_SIZES_ALL] = {
534
    32, 16, 16, 16, 8, 8, 8, 4,
535
    4,  4,  2,  2,  2, 1, 1, 1,
536
    8,  8,  4,  4,  2, 2
537
};
538
/* clang-format on */
539
540
static inline void build_smooth_interintra_mask(uint8_t *mask, int stride,
541
                                                BLOCK_SIZE plane_bsize,
542
1.91k
                                                INTERINTRA_MODE mode) {
543
1.91k
  int i, j;
544
1.91k
  const int bw = block_size_wide[plane_bsize];
545
1.91k
  const int bh = block_size_high[plane_bsize];
546
1.91k
  const int size_scale = ii_size_scales[plane_bsize];
547
548
1.91k
  switch (mode) {
549
648
    case II_V_PRED:
550
7.65k
      for (i = 0; i < bh; ++i) {
551
7.00k
        memset(mask, ii_weights1d[i * size_scale], bw * sizeof(mask[0]));
552
7.00k
        mask += stride;
553
7.00k
      }
554
648
      break;
555
556
273
    case II_H_PRED:
557
4.08k
      for (i = 0; i < bh; ++i) {
558
55.7k
        for (j = 0; j < bw; ++j) mask[j] = ii_weights1d[j * size_scale];
559
3.80k
        mask += stride;
560
3.80k
      }
561
273
      break;
562
563
934
    case II_SMOOTH_PRED:
564
8.59k
      for (i = 0; i < bh; ++i) {
565
53.1k
        for (j = 0; j < bw; ++j)
566
45.5k
          mask[j] = ii_weights1d[(i < j ? i : j) * size_scale];
567
7.65k
        mask += stride;
568
7.65k
      }
569
934
      break;
570
571
59
    case II_DC_PRED:
572
59
    default:
573
1.14k
      for (i = 0; i < bh; ++i) {
574
1.08k
        memset(mask, 32, bw * sizeof(mask[0]));
575
1.08k
        mask += stride;
576
1.08k
      }
577
59
      break;
578
1.91k
  }
579
1.91k
}
580
581
2
static inline void init_smooth_interintra_masks(void) {
582
10
  for (int m = 0; m < INTERINTRA_MODES; ++m) {
583
184
    for (int bs = 0; bs < BLOCK_SIZES_ALL; ++bs) {
584
176
      const int bw = block_size_wide[bs];
585
176
      const int bh = block_size_high[bs];
586
176
      if (bw > MAX_WEDGE_SIZE || bh > MAX_WEDGE_SIZE) continue;
587
112
      build_smooth_interintra_mask(smooth_interintra_mask_buf[m][bs], bw, bs,
588
112
                                   m);
589
112
    }
590
8
  }
591
2
}
592
593
// Equation of line: f(x, y) = a[0]*(x - a[2]*w/8) + a[1]*(y - a[3]*h/8) = 0
594
2
static void init_all_wedge_masks(void) {
595
2
  init_wedge_master_masks();
596
2
  init_wedge_masks();
597
2
  init_smooth_interintra_masks();
598
2
}
599
600
18.5k
void av1_init_wedge_masks(void) { aom_once(init_all_wedge_masks); }
601
602
static inline void build_masked_compound_no_round(
603
    uint8_t *dst, int dst_stride, const CONV_BUF_TYPE *src0, int src0_stride,
604
    const CONV_BUF_TYPE *src1, int src1_stride,
605
    const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h,
606
3.55k
    int w, InterPredParams *inter_pred_params) {
607
3.55k
  const int ssy = inter_pred_params->subsampling_y;
608
3.55k
  const int ssx = inter_pred_params->subsampling_x;
609
3.55k
  const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type);
610
3.55k
  const int mask_stride = block_size_wide[sb_type];
611
3.55k
#if CONFIG_AV1_HIGHBITDEPTH
612
3.55k
  if (inter_pred_params->use_hbd_buf) {
613
2.24k
    aom_highbd_blend_a64_d16_mask(dst, dst_stride, src0, src0_stride, src1,
614
2.24k
                                  src1_stride, mask, mask_stride, w, h, ssx,
615
2.24k
                                  ssy, &inter_pred_params->conv_params,
616
2.24k
                                  inter_pred_params->bit_depth);
617
2.24k
  } else {
618
1.31k
    aom_lowbd_blend_a64_d16_mask(dst, dst_stride, src0, src0_stride, src1,
619
1.31k
                                 src1_stride, mask, mask_stride, w, h, ssx, ssy,
620
1.31k
                                 &inter_pred_params->conv_params);
621
1.31k
  }
622
#else
623
  aom_lowbd_blend_a64_d16_mask(dst, dst_stride, src0, src0_stride, src1,
624
                               src1_stride, mask, mask_stride, w, h, ssx, ssy,
625
                               &inter_pred_params->conv_params);
626
#endif
627
3.55k
}
628
629
void av1_make_masked_inter_predictor(const uint8_t *pre, int pre_stride,
630
                                     uint8_t *dst, int dst_stride,
631
                                     InterPredParams *inter_pred_params,
632
3.55k
                                     const SubpelParams *subpel_params) {
633
3.55k
  const INTERINTER_COMPOUND_DATA *comp_data = &inter_pred_params->mask_comp;
634
3.55k
  BLOCK_SIZE sb_type = inter_pred_params->sb_type;
635
636
  // We're going to call av1_make_inter_predictor to generate a prediction into
637
  // a temporary buffer, then will blend that temporary buffer with that from
638
  // the other reference.
639
3.55k
  DECLARE_ALIGNED(32, uint8_t, tmp_buf[2 * MAX_SB_SQUARE]);
640
3.55k
  uint8_t *tmp_dst =
641
3.55k
      inter_pred_params->use_hbd_buf ? CONVERT_TO_BYTEPTR(tmp_buf) : tmp_buf;
642
643
3.55k
  const int tmp_buf_stride = MAX_SB_SIZE;
644
3.55k
  CONV_BUF_TYPE *org_dst = inter_pred_params->conv_params.dst;
645
3.55k
  int org_dst_stride = inter_pred_params->conv_params.dst_stride;
646
3.55k
  CONV_BUF_TYPE *tmp_buf16 = (CONV_BUF_TYPE *)tmp_buf;
647
3.55k
  inter_pred_params->conv_params.dst = tmp_buf16;
648
3.55k
  inter_pred_params->conv_params.dst_stride = tmp_buf_stride;
649
3.55k
  assert(inter_pred_params->conv_params.do_average == 0);
650
651
  // This will generate a prediction in tmp_buf for the second reference
652
3.55k
  av1_make_inter_predictor(pre, pre_stride, tmp_dst, MAX_SB_SIZE,
653
3.55k
                           inter_pred_params, subpel_params);
654
655
3.55k
  if (!inter_pred_params->conv_params.plane &&
656
1.20k
      comp_data->type == COMPOUND_DIFFWTD) {
657
302
    av1_build_compound_diffwtd_mask_d16(
658
302
        comp_data->seg_mask, comp_data->mask_type, org_dst, org_dst_stride,
659
302
        tmp_buf16, tmp_buf_stride, inter_pred_params->block_height,
660
302
        inter_pred_params->block_width, &inter_pred_params->conv_params,
661
302
        inter_pred_params->bit_depth);
662
302
  }
663
3.55k
  build_masked_compound_no_round(
664
3.55k
      dst, dst_stride, org_dst, org_dst_stride, tmp_buf16, tmp_buf_stride,
665
3.55k
      comp_data, sb_type, inter_pred_params->block_height,
666
3.55k
      inter_pred_params->block_width, inter_pred_params);
667
3.55k
}
668
669
void av1_dist_wtd_comp_weight_assign(const AV1_COMMON *cm,
670
                                     const MB_MODE_INFO *mbmi, int *fwd_offset,
671
                                     int *bck_offset,
672
                                     int *use_dist_wtd_comp_avg,
673
413k
                                     int is_compound) {
674
413k
  assert(fwd_offset != NULL && bck_offset != NULL);
675
413k
  if (!is_compound || mbmi->compound_idx) {
676
399k
    *fwd_offset = 8;
677
399k
    *bck_offset = 8;
678
399k
    *use_dist_wtd_comp_avg = 0;
679
399k
    return;
680
399k
  }
681
682
13.8k
  *use_dist_wtd_comp_avg = 1;
683
13.8k
  const RefCntBuffer *const bck_buf = get_ref_frame_buf(cm, mbmi->ref_frame[0]);
684
13.8k
  const RefCntBuffer *const fwd_buf = get_ref_frame_buf(cm, mbmi->ref_frame[1]);
685
13.8k
  const int cur_frame_index = cm->cur_frame->order_hint;
686
13.8k
  int bck_frame_index = 0, fwd_frame_index = 0;
687
688
13.8k
  if (bck_buf != NULL) bck_frame_index = bck_buf->order_hint;
689
13.8k
  if (fwd_buf != NULL) fwd_frame_index = fwd_buf->order_hint;
690
691
13.8k
  int d0 = clamp(abs(get_relative_dist(&cm->seq_params->order_hint_info,
692
13.8k
                                       fwd_frame_index, cur_frame_index)),
693
13.8k
                 0, MAX_FRAME_DISTANCE);
694
13.8k
  int d1 = clamp(abs(get_relative_dist(&cm->seq_params->order_hint_info,
695
13.8k
                                       cur_frame_index, bck_frame_index)),
696
13.8k
                 0, MAX_FRAME_DISTANCE);
697
698
13.8k
  const int order = d0 <= d1;
699
700
13.8k
  if (d0 == 0 || d1 == 0) {
701
2.09k
    *fwd_offset = quant_dist_lookup_table[3][order];
702
2.09k
    *bck_offset = quant_dist_lookup_table[3][1 - order];
703
2.09k
    return;
704
2.09k
  }
705
706
11.7k
  int i;
707
18.9k
  for (i = 0; i < 3; ++i) {
708
17.5k
    int c0 = quant_dist_weight[i][order];
709
17.5k
    int c1 = quant_dist_weight[i][!order];
710
17.5k
    int d0_c0 = d0 * c0;
711
17.5k
    int d1_c1 = d1 * c1;
712
17.5k
    if ((d0 > d1 && d0_c0 < d1_c1) || (d0 <= d1 && d0_c0 > d1_c1)) break;
713
17.5k
  }
714
715
11.7k
  *fwd_offset = quant_dist_lookup_table[i][order];
716
11.7k
  *bck_offset = quant_dist_lookup_table[i][1 - order];
717
11.7k
}
718
719
void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize,
720
                          const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
721
9.47M
                          const int plane_start, const int plane_end) {
722
  // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
723
  // the static analysis warnings.
724
36.9M
  for (int i = plane_start; i < AOMMIN(plane_end, MAX_MB_PLANE); ++i) {
725
27.4M
    struct macroblockd_plane *const pd = &planes[i];
726
27.4M
    const int is_uv = i > 0;
727
27.4M
    setup_pred_plane(&pd->dst, bsize, src->buffers[i], src->crop_widths[is_uv],
728
27.4M
                     src->crop_heights[is_uv], src->strides[is_uv], mi_row,
729
27.4M
                     mi_col, NULL, pd->subsampling_x, pd->subsampling_y);
730
27.4M
  }
731
9.47M
}
732
733
void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
734
                          const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
735
                          const struct scale_factors *sf,
736
53.9k
                          const int num_planes) {
737
53.9k
  if (src != NULL) {
738
    // We use AOMMIN(num_planes, MAX_MB_PLANE) instead of num_planes to quiet
739
    // the static analysis warnings.
740
196k
    for (int i = 0; i < AOMMIN(num_planes, MAX_MB_PLANE); ++i) {
741
142k
      struct macroblockd_plane *const pd = &xd->plane[i];
742
142k
      const int is_uv = i > 0;
743
142k
      setup_pred_plane(&pd->pre[idx], xd->mi[0]->bsize, src->buffers[i],
744
142k
                       src->crop_widths[is_uv], src->crop_heights[is_uv],
745
142k
                       src->strides[is_uv], mi_row, mi_col, sf,
746
142k
                       pd->subsampling_x, pd->subsampling_y);
747
142k
    }
748
53.9k
  }
749
53.9k
}
750
751
// obmc_mask_N[overlap_position]
752
static const uint8_t obmc_mask_1[1] = { 64 };
753
DECLARE_ALIGNED(2, static const uint8_t, obmc_mask_2[2]) = { 45, 64 };
754
755
DECLARE_ALIGNED(4, static const uint8_t, obmc_mask_4[4]) = { 39, 50, 59, 64 };
756
757
static const uint8_t obmc_mask_8[8] = { 36, 42, 48, 53, 57, 61, 64, 64 };
758
759
static const uint8_t obmc_mask_16[16] = { 34, 37, 40, 43, 46, 49, 52, 54,
760
                                          56, 58, 60, 61, 64, 64, 64, 64 };
761
762
static const uint8_t obmc_mask_32[32] = { 33, 35, 36, 38, 40, 41, 43, 44,
763
                                          45, 47, 48, 50, 51, 52, 53, 55,
764
                                          56, 57, 58, 59, 60, 60, 61, 62,
765
                                          64, 64, 64, 64, 64, 64, 64, 64 };
766
767
static const uint8_t obmc_mask_64[64] = {
768
  33, 34, 35, 35, 36, 37, 38, 39, 40, 40, 41, 42, 43, 44, 44, 44,
769
  45, 46, 47, 47, 48, 49, 50, 51, 51, 51, 52, 52, 53, 54, 55, 56,
770
  56, 56, 57, 57, 58, 58, 59, 60, 60, 60, 60, 60, 61, 62, 62, 62,
771
  62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
772
};
773
774
8.55k
const uint8_t *av1_get_obmc_mask(int length) {
775
8.55k
  switch (length) {
776
0
    case 1: return obmc_mask_1;
777
456
    case 2: return obmc_mask_2;
778
6.29k
    case 4: return obmc_mask_4;
779
1.74k
    case 8: return obmc_mask_8;
780
51
    case 16: return obmc_mask_16;
781
11
    case 32: return obmc_mask_32;
782
0
    case 64: return obmc_mask_64;
783
0
    default: assert(0); return NULL;
784
8.55k
  }
785
8.55k
}
786
787
static inline void increment_int_ptr(MACROBLOCKD *xd, int rel_mi_row,
788
                                     int rel_mi_col, uint8_t op_mi_size,
789
                                     int dir, MB_MODE_INFO *mi, void *fun_ctxt,
790
18.9k
                                     const int num_planes) {
791
18.9k
  (void)xd;
792
18.9k
  (void)rel_mi_row;
793
18.9k
  (void)rel_mi_col;
794
18.9k
  (void)op_mi_size;
795
18.9k
  (void)dir;
796
18.9k
  (void)mi;
797
18.9k
  ++*(uint8_t *)fun_ctxt;
798
18.9k
  (void)num_planes;
799
18.9k
}
800
801
58.8k
void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd) {
802
58.8k
  MB_MODE_INFO *mbmi = xd->mi[0];
803
804
58.8k
  mbmi->overlappable_neighbors = 0;
805
806
58.8k
  if (!is_motion_variation_allowed_bsize(mbmi->bsize)) return;
807
808
27.9k
  foreach_overlappable_nb_above(cm, xd, INT_MAX, increment_int_ptr,
809
27.9k
                                &mbmi->overlappable_neighbors);
810
27.9k
  if (mbmi->overlappable_neighbors) return;
811
20.0k
  foreach_overlappable_nb_left(cm, xd, INT_MAX, increment_int_ptr,
812
20.0k
                               &mbmi->overlappable_neighbors);
813
20.0k
}
814
815
// HW does not support < 4x4 prediction. To limit the bandwidth requirement, if
816
// block-size of current plane is smaller than 8x8, always only blend with the
817
// left neighbor(s) (skip blending with the above side).
818
#define DISABLE_CHROMA_U8X8_OBMC 0  // 0: one-sided obmc; 1: disable
819
820
int av1_skip_u4x4_pred_in_obmc(BLOCK_SIZE bsize,
821
17.8k
                               const struct macroblockd_plane *pd, int dir) {
822
17.8k
  assert(is_motion_variation_allowed_bsize(bsize));
823
824
17.8k
  const BLOCK_SIZE bsize_plane =
825
17.8k
      get_plane_block_size(bsize, pd->subsampling_x, pd->subsampling_y);
826
17.8k
  switch (bsize_plane) {
827
#if DISABLE_CHROMA_U8X8_OBMC
828
    case BLOCK_4X4:
829
    case BLOCK_8X4:
830
    case BLOCK_4X8: return 1;
831
#else
832
8
    case BLOCK_4X4:
833
8
    case BLOCK_8X4:
834
1.67k
    case BLOCK_4X8: return dir == 0;
835
0
#endif
836
16.2k
    default: return 0;
837
17.8k
  }
838
17.8k
}
839
840
#if CONFIG_AV1_DECODER
841
2.97k
static void modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi) {
842
2.97k
  mbmi->ref_frame[1] = NONE_FRAME;
843
2.97k
  mbmi->interinter_comp.type = COMPOUND_AVERAGE;
844
2.97k
}
845
#endif  // CONFIG_AV1_DECODER
846
847
struct obmc_inter_pred_ctxt {
848
  uint8_t **adjacent;
849
  int *adjacent_stride;
850
};
851
852
static inline void build_obmc_inter_pred_above(
853
    MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size,
854
1.05k
    int dir, MB_MODE_INFO *above_mi, void *fun_ctxt, const int num_planes) {
855
1.05k
  (void)above_mi;
856
1.05k
  (void)rel_mi_row;
857
1.05k
  (void)dir;
858
1.05k
  struct obmc_inter_pred_ctxt *ctxt = (struct obmc_inter_pred_ctxt *)fun_ctxt;
859
1.05k
  const BLOCK_SIZE bsize = xd->mi[0]->bsize;
860
1.05k
  const int overlap =
861
1.05k
      AOMMIN(block_size_high[bsize], block_size_high[BLOCK_64X64]) >> 1;
862
863
4.20k
  for (int plane = 0; plane < num_planes; ++plane) {
864
3.15k
    const struct macroblockd_plane *pd = &xd->plane[plane];
865
3.15k
    const int bw = (op_mi_size * MI_SIZE) >> pd->subsampling_x;
866
3.15k
    const int bh = overlap >> pd->subsampling_y;
867
3.15k
    const int plane_col = (rel_mi_col * MI_SIZE) >> pd->subsampling_x;
868
869
3.15k
    if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue;
870
871
2.77k
    const int dst_stride = pd->dst.stride;
872
2.77k
    uint8_t *const dst = &pd->dst.buf[plane_col];
873
2.77k
    const int tmp_stride = ctxt->adjacent_stride[plane];
874
2.77k
    const uint8_t *const tmp = &ctxt->adjacent[plane][plane_col];
875
2.77k
    const uint8_t *const mask = av1_get_obmc_mask(bh);
876
2.77k
#if CONFIG_AV1_HIGHBITDEPTH
877
2.77k
    const int is_hbd = is_cur_buf_hbd(xd);
878
2.77k
    if (is_hbd)
879
2.24k
      aom_highbd_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp,
880
2.24k
                                 tmp_stride, mask, bw, bh, xd->bd);
881
532
    else
882
532
      aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
883
532
                          mask, bw, bh);
884
#else
885
    aom_blend_a64_vmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride, mask,
886
                        bw, bh);
887
#endif
888
2.77k
  }
889
1.05k
}
890
891
static inline void build_obmc_inter_pred_left(
892
    MACROBLOCKD *xd, int rel_mi_row, int rel_mi_col, uint8_t op_mi_size,
893
1.92k
    int dir, MB_MODE_INFO *left_mi, void *fun_ctxt, const int num_planes) {
894
1.92k
  (void)left_mi;
895
1.92k
  (void)rel_mi_col;
896
1.92k
  (void)dir;
897
1.92k
  struct obmc_inter_pred_ctxt *ctxt = (struct obmc_inter_pred_ctxt *)fun_ctxt;
898
1.92k
  const BLOCK_SIZE bsize = xd->mi[0]->bsize;
899
1.92k
  const int overlap =
900
1.92k
      AOMMIN(block_size_wide[bsize], block_size_wide[BLOCK_64X64]) >> 1;
901
902
7.71k
  for (int plane = 0; plane < num_planes; ++plane) {
903
5.78k
    const struct macroblockd_plane *pd = &xd->plane[plane];
904
5.78k
    const int bw = overlap >> pd->subsampling_x;
905
5.78k
    const int bh = (op_mi_size * MI_SIZE) >> pd->subsampling_y;
906
5.78k
    const int plane_row = (rel_mi_row * MI_SIZE) >> pd->subsampling_y;
907
908
5.78k
    if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue;
909
910
5.78k
    const int dst_stride = pd->dst.stride;
911
5.78k
    uint8_t *const dst = &pd->dst.buf[plane_row * dst_stride];
912
5.78k
    const int tmp_stride = ctxt->adjacent_stride[plane];
913
5.78k
    const uint8_t *const tmp = &ctxt->adjacent[plane][plane_row * tmp_stride];
914
5.78k
    const uint8_t *const mask = av1_get_obmc_mask(bw);
915
916
5.78k
#if CONFIG_AV1_HIGHBITDEPTH
917
5.78k
    const int is_hbd = is_cur_buf_hbd(xd);
918
5.78k
    if (is_hbd)
919
3.03k
      aom_highbd_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp,
920
3.03k
                                 tmp_stride, mask, bw, bh, xd->bd);
921
2.75k
    else
922
2.75k
      aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride,
923
2.75k
                          mask, bw, bh);
924
#else
925
    aom_blend_a64_hmask(dst, dst_stride, dst, dst_stride, tmp, tmp_stride, mask,
926
                        bw, bh);
927
#endif
928
5.78k
  }
929
1.92k
}
930
931
// This function combines motion compensated predictions that are generated by
932
// top/left neighboring blocks' inter predictors with the regular inter
933
// prediction. We assume the original prediction (bmc) is stored in
934
// xd->plane[].dst.buf
935
void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
936
                                     uint8_t *above[MAX_MB_PLANE],
937
                                     int above_stride[MAX_MB_PLANE],
938
                                     uint8_t *left[MAX_MB_PLANE],
939
2.62k
                                     int left_stride[MAX_MB_PLANE]) {
940
2.62k
  const BLOCK_SIZE bsize = xd->mi[0]->bsize;
941
942
  // handle above row
943
2.62k
  struct obmc_inter_pred_ctxt ctxt_above = { above, above_stride };
944
2.62k
  foreach_overlappable_nb_above(cm, xd,
945
2.62k
                                max_neighbor_obmc[mi_size_wide_log2[bsize]],
946
2.62k
                                build_obmc_inter_pred_above, &ctxt_above);
947
948
  // handle left column
949
2.62k
  struct obmc_inter_pred_ctxt ctxt_left = { left, left_stride };
950
2.62k
  foreach_overlappable_nb_left(cm, xd,
951
2.62k
                               max_neighbor_obmc[mi_size_high_log2[bsize]],
952
2.62k
                               build_obmc_inter_pred_left, &ctxt_left);
953
2.62k
}
954
955
void av1_setup_obmc_dst_bufs(MACROBLOCKD *xd, uint8_t **dst_buf1,
956
2.62k
                             uint8_t **dst_buf2) {
957
2.62k
  if (is_cur_buf_hbd(xd)) {
958
1.53k
    int len = sizeof(uint16_t);
959
1.53k
    dst_buf1[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0]);
960
1.53k
    dst_buf1[1] =
961
1.53k
        CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * len);
962
1.53k
    dst_buf1[2] =
963
1.53k
        CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2 * len);
964
1.53k
    dst_buf2[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1]);
965
1.53k
    dst_buf2[1] =
966
1.53k
        CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * len);
967
1.53k
    dst_buf2[2] =
968
1.53k
        CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2 * len);
969
1.53k
  } else {
970
1.08k
    dst_buf1[0] = xd->tmp_obmc_bufs[0];
971
1.08k
    dst_buf1[1] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE;
972
1.08k
    dst_buf1[2] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2;
973
1.08k
    dst_buf2[0] = xd->tmp_obmc_bufs[1];
974
1.08k
    dst_buf2[1] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE;
975
1.08k
    dst_buf2[2] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2;
976
1.08k
  }
977
2.62k
}
978
979
#if CONFIG_AV1_DECODER
980
void av1_setup_build_prediction_by_above_pred(
981
    MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width,
982
    MB_MODE_INFO *above_mbmi, struct build_prediction_ctxt *ctxt,
983
1.05k
    const int num_planes) {
984
1.05k
  const BLOCK_SIZE a_bsize = AOMMAX(BLOCK_8X8, above_mbmi->bsize);
985
1.05k
  const int above_mi_col = xd->mi_col + rel_mi_col;
986
987
1.05k
  modify_neighbor_predictor_for_obmc(above_mbmi);
988
989
4.20k
  for (int j = 0; j < num_planes; ++j) {
990
3.15k
    struct macroblockd_plane *const pd = &xd->plane[j];
991
3.15k
    setup_pred_plane(&pd->dst, a_bsize, ctxt->tmp_buf[j], ctxt->tmp_width[j],
992
3.15k
                     ctxt->tmp_height[j], ctxt->tmp_stride[j], 0, rel_mi_col,
993
3.15k
                     NULL, pd->subsampling_x, pd->subsampling_y);
994
3.15k
  }
995
996
1.05k
  const int num_refs = 1 + has_second_ref(above_mbmi);
997
998
2.10k
  for (int ref = 0; ref < num_refs; ++ref) {
999
1.05k
    const MV_REFERENCE_FRAME frame = above_mbmi->ref_frame[ref];
1000
1001
1.05k
    const RefCntBuffer *const ref_buf = get_ref_frame_buf(ctxt->cm, frame);
1002
1.05k
    const struct scale_factors *const sf =
1003
1.05k
        get_ref_scale_factors_const(ctxt->cm, frame);
1004
1.05k
    xd->block_ref_scale_factors[ref] = sf;
1005
1.05k
    if ((!av1_is_valid_scale(sf)))
1006
0
      aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
1007
0
                         "Reference frame has invalid dimensions");
1008
1.05k
    av1_setup_pre_planes(xd, ref, &ref_buf->buf, xd->mi_row, above_mi_col, sf,
1009
1.05k
                         num_planes);
1010
1.05k
  }
1011
1012
1.05k
  xd->mb_to_left_edge = 8 * MI_SIZE * (-above_mi_col);
1013
1.05k
  xd->mb_to_right_edge =
1014
1.05k
      ctxt->mb_to_far_edge +
1015
1.05k
      (xd->width - rel_mi_col - above_mi_width) * MI_SIZE * 8;
1016
1.05k
}
1017
1018
void av1_setup_build_prediction_by_left_pred(MACROBLOCKD *xd, int rel_mi_row,
1019
                                             uint8_t left_mi_height,
1020
                                             MB_MODE_INFO *left_mbmi,
1021
                                             struct build_prediction_ctxt *ctxt,
1022
1.92k
                                             const int num_planes) {
1023
1.92k
  const BLOCK_SIZE l_bsize = AOMMAX(BLOCK_8X8, left_mbmi->bsize);
1024
1.92k
  const int left_mi_row = xd->mi_row + rel_mi_row;
1025
1026
1.92k
  modify_neighbor_predictor_for_obmc(left_mbmi);
1027
1028
7.71k
  for (int j = 0; j < num_planes; ++j) {
1029
5.78k
    struct macroblockd_plane *const pd = &xd->plane[j];
1030
5.78k
    setup_pred_plane(&pd->dst, l_bsize, ctxt->tmp_buf[j], ctxt->tmp_width[j],
1031
5.78k
                     ctxt->tmp_height[j], ctxt->tmp_stride[j], rel_mi_row, 0,
1032
5.78k
                     NULL, pd->subsampling_x, pd->subsampling_y);
1033
5.78k
  }
1034
1035
1.92k
  const int num_refs = 1 + has_second_ref(left_mbmi);
1036
1037
3.85k
  for (int ref = 0; ref < num_refs; ++ref) {
1038
1.92k
    const MV_REFERENCE_FRAME frame = left_mbmi->ref_frame[ref];
1039
1040
1.92k
    const RefCntBuffer *const ref_buf = get_ref_frame_buf(ctxt->cm, frame);
1041
1.92k
    const struct scale_factors *const ref_scale_factors =
1042
1.92k
        get_ref_scale_factors_const(ctxt->cm, frame);
1043
1044
1.92k
    xd->block_ref_scale_factors[ref] = ref_scale_factors;
1045
1.92k
    if ((!av1_is_valid_scale(ref_scale_factors)))
1046
0
      aom_internal_error(xd->error_info, AOM_CODEC_UNSUP_BITSTREAM,
1047
0
                         "Reference frame has invalid dimensions");
1048
1.92k
    av1_setup_pre_planes(xd, ref, &ref_buf->buf, left_mi_row, xd->mi_col,
1049
1.92k
                         ref_scale_factors, num_planes);
1050
1.92k
  }
1051
1052
1.92k
  xd->mb_to_top_edge = GET_MV_SUBPEL(MI_SIZE * (-left_mi_row));
1053
1.92k
  xd->mb_to_bottom_edge =
1054
1.92k
      ctxt->mb_to_far_edge +
1055
1.92k
      GET_MV_SUBPEL((xd->height - rel_mi_row - left_mi_height) * MI_SIZE);
1056
1.92k
}
1057
#endif  // CONFIG_AV1_DECODER
1058
1059
static inline void combine_interintra(
1060
    INTERINTRA_MODE mode, int8_t use_wedge_interintra, int8_t wedge_index,
1061
    int8_t wedge_sign, BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
1062
    uint8_t *comppred, int compstride, const uint8_t *interpred,
1063
1.08k
    int interstride, const uint8_t *intrapred, int intrastride) {
1064
1.08k
  const int bw = block_size_wide[plane_bsize];
1065
1.08k
  const int bh = block_size_high[plane_bsize];
1066
1067
1.08k
  if (use_wedge_interintra) {
1068
507
    if (av1_is_wedge_used(bsize)) {
1069
507
      const uint8_t *mask =
1070
507
          av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
1071
507
      const int subw = 2 * mi_size_wide[bsize] == bw;
1072
507
      const int subh = 2 * mi_size_high[bsize] == bh;
1073
507
      aom_blend_a64_mask(comppred, compstride, intrapred, intrastride,
1074
507
                         interpred, interstride, mask, block_size_wide[bsize],
1075
507
                         bw, bh, subw, subh);
1076
507
    }
1077
507
    return;
1078
507
  }
1079
1080
580
  const uint8_t *mask = smooth_interintra_mask_buf[mode][plane_bsize];
1081
580
  aom_blend_a64_mask(comppred, compstride, intrapred, intrastride, interpred,
1082
580
                     interstride, mask, bw, bw, bh, 0, 0);
1083
580
}
1084
1085
#if CONFIG_AV1_HIGHBITDEPTH
1086
static inline void combine_interintra_highbd(
1087
    INTERINTRA_MODE mode, int8_t use_wedge_interintra, int8_t wedge_index,
1088
    int8_t wedge_sign, BLOCK_SIZE bsize, BLOCK_SIZE plane_bsize,
1089
    uint8_t *comppred8, int compstride, const uint8_t *interpred8,
1090
2.96k
    int interstride, const uint8_t *intrapred8, int intrastride, int bd) {
1091
2.96k
  const int bw = block_size_wide[plane_bsize];
1092
2.96k
  const int bh = block_size_high[plane_bsize];
1093
1094
2.96k
  if (use_wedge_interintra) {
1095
1.15k
    if (av1_is_wedge_used(bsize)) {
1096
1.15k
      const uint8_t *mask =
1097
1.15k
          av1_get_contiguous_soft_mask(wedge_index, wedge_sign, bsize);
1098
1.15k
      const int subh = 2 * mi_size_high[bsize] == bh;
1099
1.15k
      const int subw = 2 * mi_size_wide[bsize] == bw;
1100
1.15k
      aom_highbd_blend_a64_mask(comppred8, compstride, intrapred8, intrastride,
1101
1.15k
                                interpred8, interstride, mask,
1102
1.15k
                                block_size_wide[bsize], bw, bh, subw, subh, bd);
1103
1.15k
    }
1104
1.15k
    return;
1105
1.15k
  }
1106
1107
1.80k
  uint8_t mask[MAX_SB_SQUARE];
1108
1.80k
  build_smooth_interintra_mask(mask, bw, plane_bsize, mode);
1109
1.80k
  aom_highbd_blend_a64_mask(comppred8, compstride, intrapred8, intrastride,
1110
1.80k
                            interpred8, interstride, mask, bw, bw, bh, 0, 0,
1111
1.80k
                            bd);
1112
1.80k
}
1113
#endif
1114
1115
void av1_build_intra_predictors_for_interintra(const AV1_COMMON *cm,
1116
                                               MACROBLOCKD *xd,
1117
                                               BLOCK_SIZE bsize, int plane,
1118
                                               const BUFFER_SET *ctx,
1119
4.04k
                                               uint8_t *dst, int dst_stride) {
1120
4.04k
  struct macroblockd_plane *const pd = &xd->plane[plane];
1121
4.04k
  const int ssx = xd->plane[plane].subsampling_x;
1122
4.04k
  const int ssy = xd->plane[plane].subsampling_y;
1123
4.04k
  BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ssx, ssy);
1124
4.04k
  PREDICTION_MODE mode = interintra_to_intra_mode[xd->mi[0]->interintra_mode];
1125
4.04k
  assert(xd->mi[0]->angle_delta[PLANE_TYPE_Y] == 0);
1126
4.04k
  assert(xd->mi[0]->angle_delta[PLANE_TYPE_UV] == 0);
1127
4.04k
  assert(xd->mi[0]->filter_intra_mode_info.use_filter_intra == 0);
1128
4.04k
  assert(xd->mi[0]->use_intrabc == 0);
1129
4.04k
  const SequenceHeader *seq_params = cm->seq_params;
1130
1131
4.04k
  av1_predict_intra_block(xd, seq_params->sb_size,
1132
4.04k
                          seq_params->enable_intra_edge_filter, pd->width,
1133
4.04k
                          pd->height, max_txsize_rect_lookup[plane_bsize], mode,
1134
4.04k
                          0, 0, FILTER_INTRA_MODES, ctx->plane[plane],
1135
4.04k
                          ctx->stride[plane], dst, dst_stride, 0, 0, plane);
1136
4.04k
}
1137
1138
void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
1139
                            const uint8_t *inter_pred, int inter_stride,
1140
4.04k
                            const uint8_t *intra_pred, int intra_stride) {
1141
4.04k
  const int ssx = xd->plane[plane].subsampling_x;
1142
4.04k
  const int ssy = xd->plane[plane].subsampling_y;
1143
4.04k
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ssx, ssy);
1144
4.04k
#if CONFIG_AV1_HIGHBITDEPTH
1145
4.04k
  if (is_cur_buf_hbd(xd)) {
1146
2.96k
    combine_interintra_highbd(
1147
2.96k
        xd->mi[0]->interintra_mode, xd->mi[0]->use_wedge_interintra,
1148
2.96k
        xd->mi[0]->interintra_wedge_index, INTERINTRA_WEDGE_SIGN, bsize,
1149
2.96k
        plane_bsize, xd->plane[plane].dst.buf, xd->plane[plane].dst.stride,
1150
2.96k
        inter_pred, inter_stride, intra_pred, intra_stride, xd->bd);
1151
2.96k
    return;
1152
2.96k
  }
1153
1.08k
#endif
1154
1.08k
  combine_interintra(
1155
1.08k
      xd->mi[0]->interintra_mode, xd->mi[0]->use_wedge_interintra,
1156
1.08k
      xd->mi[0]->interintra_wedge_index, INTERINTRA_WEDGE_SIGN, bsize,
1157
1.08k
      plane_bsize, xd->plane[plane].dst.buf, xd->plane[plane].dst.stride,
1158
1.08k
      inter_pred, inter_stride, intra_pred, intra_stride);
1159
1.08k
}
1160
1161
// build interintra_predictors for one plane
1162
void av1_build_interintra_predictor(const AV1_COMMON *cm, MACROBLOCKD *xd,
1163
                                    uint8_t *pred, int stride,
1164
                                    const BUFFER_SET *ctx, int plane,
1165
4.04k
                                    BLOCK_SIZE bsize) {
1166
4.04k
  assert(bsize < BLOCK_SIZES_ALL);
1167
4.04k
  if (is_cur_buf_hbd(xd)) {
1168
2.96k
    DECLARE_ALIGNED(16, uint16_t, intrapredictor[MAX_SB_SQUARE]);
1169
2.96k
    av1_build_intra_predictors_for_interintra(
1170
2.96k
        cm, xd, bsize, plane, ctx, CONVERT_TO_BYTEPTR(intrapredictor),
1171
2.96k
        MAX_SB_SIZE);
1172
2.96k
    av1_combine_interintra(xd, bsize, plane, pred, stride,
1173
2.96k
                           CONVERT_TO_BYTEPTR(intrapredictor), MAX_SB_SIZE);
1174
2.96k
  } else {
1175
1.08k
    DECLARE_ALIGNED(16, uint8_t, intrapredictor[MAX_SB_SQUARE]);
1176
1.08k
    av1_build_intra_predictors_for_interintra(cm, xd, bsize, plane, ctx,
1177
1.08k
                                              intrapredictor, MAX_SB_SIZE);
1178
1.08k
    av1_combine_interintra(xd, bsize, plane, pred, stride, intrapredictor,
1179
1.08k
                           MAX_SB_SIZE);
1180
1.08k
  }
1181
4.04k
}