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