Coverage Report

Created: 2026-08-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavif/ext/aom/av1/common/reconinter_template.inc
Line
Count
Source
1
/*
2
 * Copyright (c) 2022, 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
#ifndef IS_DEC
13
#error "IS_DEC must be defined for reconinter_template.inc."
14
#endif
15
16
#if IS_DEC
17
static inline void build_one_inter_predictor(uint8_t *dst, int dst_stride,
18
                                             const MV *src_mv,
19
                                             InterPredParams *inter_pred_params,
20
                                             MACROBLOCKD *xd, int mi_x,
21
                                             int mi_y, int ref,
22
530k
                                             uint8_t **mc_buf) {
23
#else
24
static inline void build_one_inter_predictor(
25
    uint8_t *dst, int dst_stride, const MV *src_mv,
26
17.0M
    InterPredParams *inter_pred_params) {
27
17.0M
#endif  // IS_DEC
28
17.0M
  SubpelParams subpel_params;
29
17.0M
  uint8_t *src;
30
17.0M
  int src_stride;
31
#if IS_DEC
32
  dec_calc_subpel_params_and_extend(src_mv, inter_pred_params, xd, mi_x, mi_y,
33
                                    ref, mc_buf, &src, &subpel_params,
34
                                    &src_stride);
35
#else
36
  enc_calc_subpel_params(src_mv, inter_pred_params, &src, &subpel_params,
37
                         &src_stride);
38
#endif  // IS_DEC
39
17.5M
  if (inter_pred_params->comp_mode == UNIFORM_SINGLE ||
40
17.5M
      inter_pred_params->comp_mode == UNIFORM_COMP) {
41
17.5M
    av1_make_inter_predictor(src, src_stride, dst, dst_stride,
42
17.5M
                             inter_pred_params, &subpel_params);
43
17.5M
  } else {
44
48.1k
    av1_make_masked_inter_predictor(src, src_stride, dst, dst_stride,
45
48.1k
                                    inter_pred_params, &subpel_params);
46
48.1k
  }
47
17.0M
}
48
49
// True if the following hold:
50
//  1. Not intrabc and not build_for_obmc
51
//  2. At least one dimension is size 4 with subsampling
52
//  3. If sub-sampled, none of the previous blocks around the sub-sample
53
//     are intrabc or inter-blocks
54
static bool is_sub8x8_inter(const MACROBLOCKD *xd, int plane, BLOCK_SIZE bsize,
55
14.8M
                            int is_intrabc, int build_for_obmc) {
56
14.8M
  if (is_intrabc || build_for_obmc) {
57
648k
    return false;
58
648k
  }
59
60
14.2M
  const struct macroblockd_plane *const pd = &xd->plane[plane];
61
14.2M
  const int ss_x = pd->subsampling_x;
62
14.2M
  const int ss_y = pd->subsampling_y;
63
14.2M
  const int is_sub4_x = (block_size_wide[bsize] == 4) && ss_x;
64
14.2M
  const int is_sub4_y = (block_size_high[bsize] == 4) && ss_y;
65
14.2M
  if (!is_sub4_x && !is_sub4_y) {
66
14.1M
    return false;
67
14.1M
  }
68
69
  // For sub8x8 chroma blocks, we may be covering more than one luma block's
70
  // worth of pixels. Thus (mi_x, mi_y) may not be the correct coordinates for
71
  // the top-left corner of the prediction source - the correct top-left corner
72
  // is at (pre_x, pre_y).
73
20.3k
  const int row_start = is_sub4_y ? -1 : 0;
74
20.3k
  const int col_start = is_sub4_x ? -1 : 0;
75
76
38.7k
  for (int row = row_start; row <= 0; ++row) {
77
43.4k
    for (int col = col_start; col <= 0; ++col) {
78
25.0k
      const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
79
25.0k
      if (!is_inter_block(this_mbmi)) return false;
80
24.6k
      if (is_intrabc_block(this_mbmi)) return false;
81
24.6k
    }
82
18.7k
  }
83
19.9k
  return true;
84
20.3k
}
decodeframe.c:is_sub8x8_inter
Line
Count
Source
55
489k
                            int is_intrabc, int build_for_obmc) {
56
489k
  if (is_intrabc || build_for_obmc) {
57
90.9k
    return false;
58
90.9k
  }
59
60
398k
  const struct macroblockd_plane *const pd = &xd->plane[plane];
61
398k
  const int ss_x = pd->subsampling_x;
62
398k
  const int ss_y = pd->subsampling_y;
63
398k
  const int is_sub4_x = (block_size_wide[bsize] == 4) && ss_x;
64
398k
  const int is_sub4_y = (block_size_high[bsize] == 4) && ss_y;
65
398k
  if (!is_sub4_x && !is_sub4_y) {
66
385k
    return false;
67
385k
  }
68
69
  // For sub8x8 chroma blocks, we may be covering more than one luma block's
70
  // worth of pixels. Thus (mi_x, mi_y) may not be the correct coordinates for
71
  // the top-left corner of the prediction source - the correct top-left corner
72
  // is at (pre_x, pre_y).
73
12.7k
  const int row_start = is_sub4_y ? -1 : 0;
74
12.7k
  const int col_start = is_sub4_x ? -1 : 0;
75
76
31.1k
  for (int row = row_start; row <= 0; ++row) {
77
43.4k
    for (int col = col_start; col <= 0; ++col) {
78
25.0k
      const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
79
25.0k
      if (!is_inter_block(this_mbmi)) return false;
80
24.6k
      if (is_intrabc_block(this_mbmi)) return false;
81
24.6k
    }
82
18.7k
  }
83
12.3k
  return true;
84
12.7k
}
reconinter_enc.c:is_sub8x8_inter
Line
Count
Source
55
14.3M
                            int is_intrabc, int build_for_obmc) {
56
14.3M
  if (is_intrabc || build_for_obmc) {
57
557k
    return false;
58
557k
  }
59
60
13.8M
  const struct macroblockd_plane *const pd = &xd->plane[plane];
61
13.8M
  const int ss_x = pd->subsampling_x;
62
13.8M
  const int ss_y = pd->subsampling_y;
63
13.8M
  const int is_sub4_x = (block_size_wide[bsize] == 4) && ss_x;
64
13.8M
  const int is_sub4_y = (block_size_high[bsize] == 4) && ss_y;
65
13.8M
  if (!is_sub4_x && !is_sub4_y) {
66
13.8M
    return false;
67
13.8M
  }
68
69
  // For sub8x8 chroma blocks, we may be covering more than one luma block's
70
  // worth of pixels. Thus (mi_x, mi_y) may not be the correct coordinates for
71
  // the top-left corner of the prediction source - the correct top-left corner
72
  // is at (pre_x, pre_y).
73
7.57k
  const int row_start = is_sub4_y ? -1 : 0;
74
7.57k
  const int col_start = is_sub4_x ? -1 : 0;
75
76
7.57k
  for (int row = row_start; row <= 0; ++row) {
77
0
    for (int col = col_start; col <= 0; ++col) {
78
0
      const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
79
0
      if (!is_inter_block(this_mbmi)) return false;
80
0
      if (is_intrabc_block(this_mbmi)) return false;
81
0
    }
82
0
  }
83
7.57k
  return true;
84
7.57k
}
85
86
#if IS_DEC
87
static inline void build_inter_predictors_sub8x8(const AV1_COMMON *cm,
88
                                                 MACROBLOCKD *xd, int plane,
89
                                                 const MB_MODE_INFO *mi,
90
                                                 int mi_x, int mi_y,
91
11.1k
                                                 uint8_t **mc_buf) {
92
#else
93
static inline void build_inter_predictors_sub8x8(const AV1_COMMON *cm,
94
                                                 MACROBLOCKD *xd, int plane,
95
                                                 const MB_MODE_INFO *mi,
96
0
                                                 int mi_x, int mi_y) {
97
0
#endif  // IS_DEC
98
0
  const BLOCK_SIZE bsize = mi->bsize;
99
0
  struct macroblockd_plane *const pd = &xd->plane[plane];
100
0
  const bool ss_x = pd->subsampling_x;
101
0
  const bool ss_y = pd->subsampling_y;
102
0
  const int b4_w = block_size_wide[bsize] >> ss_x;
103
0
  const int b4_h = block_size_high[bsize] >> ss_y;
104
0
  const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ss_x, ss_y);
105
0
  const int b8_w = block_size_wide[plane_bsize];
106
0
  const int b8_h = block_size_high[plane_bsize];
107
0
  const int is_compound = has_second_ref(mi);
108
0
  assert(!is_compound);
109
0
  assert(!is_intrabc_block(mi));
110
111
  // For sub8x8 chroma blocks, we may be covering more than one luma block's
112
  // worth of pixels. Thus (mi_x, mi_y) may not be the correct coordinates for
113
  // the top-left corner of the prediction source - the correct top-left corner
114
  // is at (pre_x, pre_y).
115
11.1k
  const int row_start = (block_size_high[bsize] == 4) && ss_y ? -1 : 0;
116
11.1k
  const int col_start = (block_size_wide[bsize] == 4) && ss_x ? -1 : 0;
117
11.1k
  const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x;
118
11.1k
  const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y;
119
120
0
  int row = row_start;
121
29.5k
  for (int y = 0; y < b8_h; y += b4_h) {
122
18.3k
    int col = col_start;
123
42.9k
    for (int x = 0; x < b8_w; x += b4_w) {
124
24.5k
      MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col];
125
24.5k
      struct buf_2d *const dst_buf = &pd->dst;
126
24.5k
      uint8_t *dst = dst_buf->buf + dst_buf->stride * y + x;
127
24.5k
      int ref = 0;
128
24.5k
      const RefCntBuffer *ref_buf =
129
24.5k
          get_ref_frame_buf(cm, this_mbmi->ref_frame[ref]);
130
24.5k
      const struct scale_factors *ref_scale_factors =
131
24.5k
          get_ref_scale_factors_const(cm, this_mbmi->ref_frame[ref]);
132
24.5k
      const struct scale_factors *const sf = ref_scale_factors;
133
24.5k
      const struct buf_2d pre_buf = {
134
24.5k
        NULL,
135
24.5k
        (plane == 1) ? ref_buf->buf.u_buffer : ref_buf->buf.v_buffer,
136
24.5k
        ref_buf->buf.uv_crop_width,
137
24.5k
        ref_buf->buf.uv_crop_height,
138
24.5k
        ref_buf->buf.uv_stride,
139
24.5k
      };
140
141
24.5k
      const MV mv = this_mbmi->mv[ref].as_mv;
142
143
24.5k
      InterPredParams inter_pred_params;
144
24.5k
      av1_init_inter_params(&inter_pred_params, b4_w, b4_h, pre_y + y,
145
24.5k
                            pre_x + x, pd->subsampling_x, pd->subsampling_y,
146
24.5k
                            xd->bd, is_cur_buf_hbd(xd), mi->use_intrabc, sf,
147
24.5k
                            &pre_buf, this_mbmi->interp_filters);
148
24.5k
      inter_pred_params.conv_params =
149
24.5k
          get_conv_params_no_round(ref, plane, NULL, 0, is_compound, xd->bd);
150
151
#if IS_DEC
152
      build_one_inter_predictor(dst, dst_buf->stride, &mv, &inter_pred_params,
153
                                xd, mi_x + x, mi_y + y, ref, mc_buf);
154
#else
155
      build_one_inter_predictor(dst, dst_buf->stride, &mv, &inter_pred_params);
156
#endif  // IS_DEC
157
158
24.5k
      ++col;
159
24.5k
    }
160
18.3k
    ++row;
161
18.3k
  }
162
0
}
163
164
#if IS_DEC
165
static inline void build_inter_predictors_8x8_and_bigger(
166
    const AV1_COMMON *cm, MACROBLOCKD *xd, int plane, const MB_MODE_INFO *mi,
167
476k
    int build_for_obmc, int bw, int bh, int mi_x, int mi_y, uint8_t **mc_buf) {
168
#else
169
static inline void build_inter_predictors_8x8_and_bigger(
170
    const AV1_COMMON *cm, MACROBLOCKD *xd, int plane, const MB_MODE_INFO *mi,
171
14.3M
    int build_for_obmc, int bw, int bh, int mi_x, int mi_y) {
172
14.3M
#endif  // IS_DEC
173
14.3M
  const int is_compound = has_second_ref(mi);
174
14.3M
  const int is_intrabc = is_intrabc_block(mi);
175
14.3M
  assert(IMPLIES(is_intrabc, !is_compound));
176
14.3M
  struct macroblockd_plane *const pd = &xd->plane[plane];
177
14.3M
  struct buf_2d *const dst_buf = &pd->dst;
178
14.3M
  uint8_t *const dst = dst_buf->buf;
179
180
14.3M
  int is_global[2] = { 0, 0 };
181
30.8M
  for (int ref = 0; ref < 1 + is_compound; ++ref) {
182
16.0M
    const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]];
183
16.0M
    is_global[ref] = is_global_mv_block(mi, wm->wmtype);
184
16.0M
  }
185
186
14.3M
  const BLOCK_SIZE bsize = mi->bsize;
187
14.3M
  const int ss_x = pd->subsampling_x;
188
14.3M
  const int ss_y = pd->subsampling_y;
189
14.3M
  const int row_start =
190
14.8M
      (block_size_high[bsize] == 4) && ss_y && !build_for_obmc ? -1 : 0;
191
14.3M
  const int col_start =
192
14.8M
      (block_size_wide[bsize] == 4) && ss_x && !build_for_obmc ? -1 : 0;
193
14.8M
  const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x;
194
14.8M
  const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y;
195
196
30.8M
  for (int ref = 0; ref < 1 + is_compound; ++ref) {
197
16.0M
    const struct scale_factors *const sf =
198
16.0M
        is_intrabc ? &cm->sf_identity : xd->block_ref_scale_factors[ref];
199
16.0M
    struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref];
200
16.0M
    const MV mv = mi->mv[ref].as_mv;
201
16.0M
    const WarpTypesAllowed warp_types = { is_global[ref],
202
16.0M
                                          mi->motion_mode == WARPED_CAUSAL };
203
204
16.0M
    InterPredParams inter_pred_params;
205
16.0M
    av1_init_inter_params(&inter_pred_params, bw, bh, pre_y, pre_x,
206
16.0M
                          pd->subsampling_x, pd->subsampling_y, xd->bd,
207
16.0M
                          is_cur_buf_hbd(xd), mi->use_intrabc, sf, pre_buf,
208
16.0M
                          mi->interp_filters);
209
16.0M
    if (is_compound) av1_init_comp_mode(&inter_pred_params);
210
16.0M
    inter_pred_params.conv_params = get_conv_params_no_round(
211
16.0M
        ref, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd);
212
213
16.0M
    av1_dist_wtd_comp_weight_assign(
214
16.0M
        cm, mi, &inter_pred_params.conv_params.fwd_offset,
215
16.0M
        &inter_pred_params.conv_params.bck_offset,
216
16.0M
        &inter_pred_params.conv_params.use_dist_wtd_comp_avg, is_compound);
217
218
16.0M
    if (!build_for_obmc)
219
16.0M
      av1_init_warp_params(&inter_pred_params, &warp_types, ref, xd, mi);
220
221
16.0M
    if (is_masked_compound_type(mi->interinter_comp.type)) {
222
99.2k
      inter_pred_params.sb_type = mi->bsize;
223
99.2k
      inter_pred_params.mask_comp = mi->interinter_comp;
224
99.2k
      if (ref == 1) {
225
49.6k
        inter_pred_params.conv_params.do_average = 0;
226
49.6k
        inter_pred_params.comp_mode = MASK_COMP;
227
49.6k
      }
228
      // Assign physical buffer.
229
99.2k
      inter_pred_params.mask_comp.seg_mask = xd->seg_mask;
230
99.2k
    }
231
232
#if IS_DEC
233
    build_one_inter_predictor(dst, dst_buf->stride, &mv, &inter_pred_params, xd,
234
                              mi_x, mi_y, ref, mc_buf);
235
#else
236
    build_one_inter_predictor(dst, dst_buf->stride, &mv, &inter_pred_params);
237
#endif  // IS_DEC
238
16.0M
  }
239
14.3M
}
240
241
#if IS_DEC
242
static inline void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
243
                                          int plane, const MB_MODE_INFO *mi,
244
                                          int build_for_obmc, int bw, int bh,
245
                                          int mi_x, int mi_y,
246
488k
                                          uint8_t **mc_buf) {
247
488k
  if (is_sub8x8_inter(xd, plane, mi->bsize, is_intrabc_block(mi),
248
488k
                      build_for_obmc)) {
249
11.1k
    assert(bw < 8 || bh < 8);
250
11.1k
    build_inter_predictors_sub8x8(cm, xd, plane, mi, mi_x, mi_y, mc_buf);
251
477k
  } else {
252
477k
    build_inter_predictors_8x8_and_bigger(cm, xd, plane, mi, build_for_obmc, bw,
253
477k
                                          bh, mi_x, mi_y, mc_buf);
254
477k
  }
255
488k
}
256
#else
257
static inline void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd,
258
                                          int plane, const MB_MODE_INFO *mi,
259
                                          int build_for_obmc, int bw, int bh,
260
14.3M
                                          int mi_x, int mi_y) {
261
14.3M
  if (is_sub8x8_inter(xd, plane, mi->bsize, is_intrabc_block(mi),
262
14.3M
                      build_for_obmc)) {
263
0
    assert(bw < 8 || bh < 8);
264
0
    build_inter_predictors_sub8x8(cm, xd, plane, mi, mi_x, mi_y);
265
14.3M
  } else {
266
14.3M
    build_inter_predictors_8x8_and_bigger(cm, xd, plane, mi, build_for_obmc, bw,
267
14.3M
                                          bh, mi_x, mi_y);
268
14.3M
  }
269
14.3M
}
270
#endif  // IS_DEC