/src/aom/av1/common/reconinter_template.inc
Line | Count | Source (jump to first uncovered line) |
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 | 17.0M | 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 | | InterPredParams *inter_pred_params) { |
27 | | #endif // IS_DEC |
28 | 17.0M | SubpelParams subpel_params; |
29 | 17.0M | uint8_t *src; |
30 | 17.0M | int src_stride; |
31 | 17.0M | #if IS_DEC |
32 | 17.0M | dec_calc_subpel_params_and_extend(src_mv, inter_pred_params, xd, mi_x, mi_y, |
33 | 17.0M | ref, mc_buf, &src, &subpel_params, |
34 | 17.0M | &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.0M | if (inter_pred_params->comp_mode == UNIFORM_SINGLE || |
40 | 17.0M | inter_pred_params->comp_mode == UNIFORM_COMP) { |
41 | 16.6M | av1_make_inter_predictor(src, src_stride, dst, dst_stride, |
42 | 16.6M | inter_pred_params, &subpel_params); |
43 | 16.6M | } else { |
44 | 413k | av1_make_masked_inter_predictor(src, src_stride, dst, dst_stride, |
45 | 413k | inter_pred_params, &subpel_params); |
46 | 413k | } |
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.0M | int is_intrabc, int build_for_obmc) { |
56 | 14.0M | if (is_intrabc || build_for_obmc) { |
57 | 3.03M | return false; |
58 | 3.03M | } |
59 | | |
60 | 11.0M | const struct macroblockd_plane *const pd = &xd->plane[plane]; |
61 | 11.0M | const int ss_x = pd->subsampling_x; |
62 | 11.0M | const int ss_y = pd->subsampling_y; |
63 | 11.0M | const int is_sub4_x = (block_size_wide[bsize] == 4) && ss_x; |
64 | 11.0M | const int is_sub4_y = (block_size_high[bsize] == 4) && ss_y; |
65 | 11.0M | if (!is_sub4_x && !is_sub4_y) { |
66 | 9.78M | return false; |
67 | 9.78M | } |
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 | 1.25M | const int row_start = is_sub4_y ? -1 : 0; |
74 | 1.25M | const int col_start = is_sub4_x ? -1 : 0; |
75 | | |
76 | 3.01M | for (int row = row_start; row <= 0; ++row) { |
77 | 4.32M | for (int col = col_start; col <= 0; ++col) { |
78 | 2.55M | const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col]; |
79 | 2.55M | if (!is_inter_block(this_mbmi)) return false; |
80 | 2.40M | if (is_intrabc_block(this_mbmi)) return false; |
81 | 2.40M | } |
82 | 1.91M | } |
83 | 1.10M | return true; |
84 | 1.25M | } |
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 | 1.09M | 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 | | int mi_x, int mi_y) { |
97 | | #endif // IS_DEC |
98 | 1.09M | const BLOCK_SIZE bsize = mi->bsize; |
99 | 1.09M | struct macroblockd_plane *const pd = &xd->plane[plane]; |
100 | 1.09M | const bool ss_x = pd->subsampling_x; |
101 | 1.09M | const bool ss_y = pd->subsampling_y; |
102 | 1.09M | const int b4_w = block_size_wide[bsize] >> ss_x; |
103 | 1.09M | const int b4_h = block_size_high[bsize] >> ss_y; |
104 | 1.09M | const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ss_x, ss_y); |
105 | 1.09M | const int b8_w = block_size_wide[plane_bsize]; |
106 | 1.09M | const int b8_h = block_size_high[plane_bsize]; |
107 | 1.09M | const int is_compound = has_second_ref(mi); |
108 | 1.09M | assert(!is_compound); |
109 | 1.09M | 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 | 1.09M | const int row_start = (block_size_high[bsize] == 4) && ss_y ? -1 : 0; |
116 | 1.09M | const int col_start = (block_size_wide[bsize] == 4) && ss_x ? -1 : 0; |
117 | 1.09M | const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x; |
118 | 1.09M | const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y; |
119 | | |
120 | 1.09M | int row = row_start; |
121 | 2.85M | for (int y = 0; y < b8_h; y += b4_h) { |
122 | 1.75M | int col = col_start; |
123 | 4.14M | for (int x = 0; x < b8_w; x += b4_w) { |
124 | 2.38M | MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col]; |
125 | 2.38M | struct buf_2d *const dst_buf = &pd->dst; |
126 | 2.38M | uint8_t *dst = dst_buf->buf + dst_buf->stride * y + x; |
127 | 2.38M | int ref = 0; |
128 | 2.38M | const RefCntBuffer *ref_buf = |
129 | 2.38M | get_ref_frame_buf(cm, this_mbmi->ref_frame[ref]); |
130 | 2.38M | const struct scale_factors *ref_scale_factors = |
131 | 2.38M | get_ref_scale_factors_const(cm, this_mbmi->ref_frame[ref]); |
132 | 2.38M | const struct scale_factors *const sf = ref_scale_factors; |
133 | 2.38M | const struct buf_2d pre_buf = { |
134 | 2.38M | NULL, |
135 | 2.38M | (plane == 1) ? ref_buf->buf.u_buffer : ref_buf->buf.v_buffer, |
136 | 2.38M | ref_buf->buf.uv_crop_width, |
137 | 2.38M | ref_buf->buf.uv_crop_height, |
138 | 2.38M | ref_buf->buf.uv_stride, |
139 | 2.38M | }; |
140 | | |
141 | 2.38M | const MV mv = this_mbmi->mv[ref].as_mv; |
142 | | |
143 | 2.38M | InterPredParams inter_pred_params; |
144 | 2.38M | av1_init_inter_params(&inter_pred_params, b4_w, b4_h, pre_y + y, |
145 | 2.38M | pre_x + x, pd->subsampling_x, pd->subsampling_y, |
146 | 2.38M | xd->bd, is_cur_buf_hbd(xd), mi->use_intrabc, sf, |
147 | 2.38M | &pre_buf, this_mbmi->interp_filters); |
148 | 2.38M | inter_pred_params.conv_params = |
149 | 2.38M | get_conv_params_no_round(ref, plane, NULL, 0, is_compound, xd->bd); |
150 | | |
151 | 2.38M | #if IS_DEC |
152 | 2.38M | build_one_inter_predictor(dst, dst_buf->stride, &mv, &inter_pred_params, |
153 | 2.38M | 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 | 2.38M | ++col; |
159 | 2.38M | } |
160 | 1.75M | ++row; |
161 | 1.75M | } |
162 | 1.09M | } |
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 | 12.9M | 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 | | int build_for_obmc, int bw, int bh, int mi_x, int mi_y) { |
172 | | #endif // IS_DEC |
173 | 12.9M | const int is_compound = has_second_ref(mi); |
174 | 12.9M | const int is_intrabc = is_intrabc_block(mi); |
175 | 12.9M | assert(IMPLIES(is_intrabc, !is_compound)); |
176 | 12.9M | struct macroblockd_plane *const pd = &xd->plane[plane]; |
177 | 12.9M | struct buf_2d *const dst_buf = &pd->dst; |
178 | 12.9M | uint8_t *const dst = dst_buf->buf; |
179 | | |
180 | 12.9M | int is_global[2] = { 0, 0 }; |
181 | 27.6M | for (int ref = 0; ref < 1 + is_compound; ++ref) { |
182 | 14.6M | const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]]; |
183 | 14.6M | is_global[ref] = is_global_mv_block(mi, wm->wmtype); |
184 | 14.6M | } |
185 | | |
186 | 12.9M | const BLOCK_SIZE bsize = mi->bsize; |
187 | 12.9M | const int ss_x = pd->subsampling_x; |
188 | 12.9M | const int ss_y = pd->subsampling_y; |
189 | 12.9M | const int row_start = |
190 | 12.9M | (block_size_high[bsize] == 4) && ss_y && !build_for_obmc ? -1 : 0; |
191 | 12.9M | const int col_start = |
192 | 12.9M | (block_size_wide[bsize] == 4) && ss_x && !build_for_obmc ? -1 : 0; |
193 | 12.9M | const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x; |
194 | 12.9M | const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y; |
195 | | |
196 | 27.6M | for (int ref = 0; ref < 1 + is_compound; ++ref) { |
197 | 14.6M | const struct scale_factors *const sf = |
198 | 14.6M | is_intrabc ? &cm->sf_identity : xd->block_ref_scale_factors[ref]; |
199 | 14.6M | struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref]; |
200 | 14.6M | const MV mv = mi->mv[ref].as_mv; |
201 | 14.6M | const WarpTypesAllowed warp_types = { is_global[ref], |
202 | 14.6M | mi->motion_mode == WARPED_CAUSAL }; |
203 | | |
204 | 14.6M | InterPredParams inter_pred_params; |
205 | 14.6M | av1_init_inter_params(&inter_pred_params, bw, bh, pre_y, pre_x, |
206 | 14.6M | pd->subsampling_x, pd->subsampling_y, xd->bd, |
207 | 14.6M | is_cur_buf_hbd(xd), mi->use_intrabc, sf, pre_buf, |
208 | 14.6M | mi->interp_filters); |
209 | 14.6M | if (is_compound) av1_init_comp_mode(&inter_pred_params); |
210 | 14.6M | inter_pred_params.conv_params = get_conv_params_no_round( |
211 | 14.6M | ref, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd); |
212 | | |
213 | 14.6M | av1_dist_wtd_comp_weight_assign( |
214 | 14.6M | cm, mi, &inter_pred_params.conv_params.fwd_offset, |
215 | 14.6M | &inter_pred_params.conv_params.bck_offset, |
216 | 14.6M | &inter_pred_params.conv_params.use_dist_wtd_comp_avg, is_compound); |
217 | | |
218 | 14.6M | if (!build_for_obmc) |
219 | 11.7M | av1_init_warp_params(&inter_pred_params, &warp_types, ref, xd, mi); |
220 | | |
221 | 14.6M | if (is_masked_compound_type(mi->interinter_comp.type)) { |
222 | 821k | inter_pred_params.sb_type = mi->bsize; |
223 | 821k | inter_pred_params.mask_comp = mi->interinter_comp; |
224 | 821k | if (ref == 1) { |
225 | 410k | inter_pred_params.conv_params.do_average = 0; |
226 | 410k | inter_pred_params.comp_mode = MASK_COMP; |
227 | 410k | } |
228 | | // Assign physical buffer. |
229 | 821k | inter_pred_params.mask_comp.seg_mask = xd->seg_mask; |
230 | 821k | } |
231 | | |
232 | 14.6M | #if IS_DEC |
233 | 14.6M | build_one_inter_predictor(dst, dst_buf->stride, &mv, &inter_pred_params, xd, |
234 | 14.6M | 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 | 14.6M | } |
239 | 12.9M | } |
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 | 14.0M | uint8_t **mc_buf) { |
247 | 14.0M | if (is_sub8x8_inter(xd, plane, mi->bsize, is_intrabc_block(mi), |
248 | 14.0M | build_for_obmc)) { |
249 | 1.09M | assert(bw < 8 || bh < 8); |
250 | 1.09M | build_inter_predictors_sub8x8(cm, xd, plane, mi, mi_x, mi_y, mc_buf); |
251 | 12.9M | } else { |
252 | 12.9M | build_inter_predictors_8x8_and_bigger(cm, xd, plane, mi, build_for_obmc, bw, |
253 | 12.9M | bh, mi_x, mi_y, mc_buf); |
254 | 12.9M | } |
255 | 14.0M | } |
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 | | int mi_x, int mi_y) { |
261 | | if (is_sub8x8_inter(xd, plane, mi->bsize, is_intrabc_block(mi), |
262 | | build_for_obmc)) { |
263 | | assert(bw < 8 || bh < 8); |
264 | | build_inter_predictors_sub8x8(cm, xd, plane, mi, mi_x, mi_y); |
265 | | } else { |
266 | | build_inter_predictors_8x8_and_bigger(cm, xd, plane, mi, build_for_obmc, bw, |
267 | | bh, mi_x, mi_y); |
268 | | } |
269 | | } |
270 | | #endif // IS_DEC |