Coverage Report

Created: 2025-08-29 07:08

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