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 17static 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 uint8_t **mc_buf) { 23#else 24static 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 SubpelParams subpel_params; 29 uint8_t *src; 30 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 if (inter_pred_params->comp_mode == UNIFORM_SINGLE || 40 inter_pred_params->comp_mode == UNIFORM_COMP) { 41 av1_make_inter_predictor(src, src_stride, dst, dst_stride, 42 inter_pred_params, &subpel_params); 43 } else { 44 av1_make_masked_inter_predictor(src, src_stride, dst, dst_stride, 45 inter_pred_params, &subpel_params); 46 } 47} 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 54static bool is_sub8x8_inter(const MACROBLOCKD *xd, int plane, BLOCK_SIZE bsize, 55 int is_intrabc, int build_for_obmc) { 56 if (is_intrabc || build_for_obmc) { 57 return false; 58 } 59 60 const struct macroblockd_plane *const pd = &xd->plane[plane]; 61 const int ss_x = pd->subsampling_x; 62 const int ss_y = pd->subsampling_y; 63 const int is_sub4_x = (block_size_wide[bsize] == 4) && ss_x; 64 const int is_sub4_y = (block_size_high[bsize] == 4) && ss_y; 65 if (!is_sub4_x && !is_sub4_y) { 66 return false; 67 } 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 const int row_start = is_sub4_y ? -1 : 0; 74 const int col_start = is_sub4_x ? -1 : 0; 75 76 for (int row = row_start; row <= 0; ++row) { 77 for (int col = col_start; col <= 0; ++col) { 78 const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col]; 79 if (!is_inter_block(this_mbmi)) return false; 80 if (is_intrabc_block(this_mbmi)) return false; 81 } 82 } 83 return true; 84} 85 86#if IS_DEC 87static 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 uint8_t **mc_buf) { 92#else 93static 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 const BLOCK_SIZE bsize = mi->bsize; 99 struct macroblockd_plane *const pd = &xd->plane[plane]; 100 const bool ss_x = pd->subsampling_x; 101 const bool ss_y = pd->subsampling_y; 102 const int b4_w = block_size_wide[bsize] >> ss_x; 103 const int b4_h = block_size_high[bsize] >> ss_y; 104 const BLOCK_SIZE plane_bsize = get_plane_block_size(bsize, ss_x, ss_y); 105 const int b8_w = block_size_wide[plane_bsize]; 106 const int b8_h = block_size_high[plane_bsize]; 107 const int is_compound = has_second_ref(mi); 108 assert(!is_compound); 109 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 const int row_start = (block_size_high[bsize] == 4) && ss_y ? -1 : 0; 116 const int col_start = (block_size_wide[bsize] == 4) && ss_x ? -1 : 0; 117 const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x; 118 const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y; 119 120 int row = row_start; 121 for (int y = 0; y < b8_h; y += b4_h) { 122 int col = col_start; 123 for (int x = 0; x < b8_w; x += b4_w) { 124 MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col]; 125 struct buf_2d *const dst_buf = &pd->dst; 126 uint8_t *dst = dst_buf->buf + dst_buf->stride * y + x; 127 int ref = 0; 128 const RefCntBuffer *ref_buf = 129 get_ref_frame_buf(cm, this_mbmi->ref_frame[ref]); 130 const struct scale_factors *ref_scale_factors = 131 get_ref_scale_factors_const(cm, this_mbmi->ref_frame[ref]); 132 const struct scale_factors *const sf = ref_scale_factors; 133 const struct buf_2d pre_buf = { 134 NULL, 135 (plane == 1) ? ref_buf->buf.u_buffer : ref_buf->buf.v_buffer, 136 ref_buf->buf.uv_crop_width, 137 ref_buf->buf.uv_crop_height, 138 ref_buf->buf.uv_stride, 139 }; 140 141 const MV mv = this_mbmi->mv[ref].as_mv; 142 143 InterPredParams inter_pred_params; 144 av1_init_inter_params(&inter_pred_params, b4_w, b4_h, pre_y + y, 145 pre_x + x, pd->subsampling_x, pd->subsampling_y, 146 xd->bd, is_cur_buf_hbd(xd), mi->use_intrabc, sf, 147 &pre_buf, this_mbmi->interp_filters); 148 inter_pred_params.conv_params = 149 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 ++col; 159 } 160 ++row; 161 } 162} 163 164#if IS_DEC 165static inline void build_inter_predictors_8x8_and_bigger( 166 const AV1_COMMON *cm, MACROBLOCKD *xd, int plane, const MB_MODE_INFO *mi, 167 int build_for_obmc, int bw, int bh, int mi_x, int mi_y, uint8_t **mc_buf) { 168#else 169static 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 const int is_compound = has_second_ref(mi); 174 const int is_intrabc = is_intrabc_block(mi); 175 assert(IMPLIES(is_intrabc, !is_compound)); 176 struct macroblockd_plane *const pd = &xd->plane[plane]; 177 struct buf_2d *const dst_buf = &pd->dst; 178 uint8_t *const dst = dst_buf->buf; 179 180 int is_global[2] = { 0, 0 }; 181 for (int ref = 0; ref < 1 + is_compound; ++ref) { 182 const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]]; 183 is_global[ref] = is_global_mv_block(mi, wm->wmtype); 184 } 185 186 const BLOCK_SIZE bsize = mi->bsize; 187 const int ss_x = pd->subsampling_x; 188 const int ss_y = pd->subsampling_y; 189 const int row_start = 190 (block_size_high[bsize] == 4) && ss_y && !build_for_obmc ? -1 : 0; 191 const int col_start = 192 (block_size_wide[bsize] == 4) && ss_x && !build_for_obmc ? -1 : 0; 193 const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x; 194 const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y; 195 196 for (int ref = 0; ref < 1 + is_compound; ++ref) { 197 const struct scale_factors *const sf = 198 is_intrabc ? &cm->sf_identity : xd->block_ref_scale_factors[ref]; 199 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref]; 200 const MV mv = mi->mv[ref].as_mv; 201 const WarpTypesAllowed warp_types = { is_global[ref], 202 mi->motion_mode == WARPED_CAUSAL }; 203 204 InterPredParams inter_pred_params; 205 av1_init_inter_params(&inter_pred_params, bw, bh, pre_y, pre_x, 206 pd->subsampling_x, pd->subsampling_y, xd->bd, 207 is_cur_buf_hbd(xd), mi->use_intrabc, sf, pre_buf, 208 mi->interp_filters); 209 if (is_compound) av1_init_comp_mode(&inter_pred_params); 210 inter_pred_params.conv_params = get_conv_params_no_round( 211 ref, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd); 212 213 av1_dist_wtd_comp_weight_assign( 214 cm, mi, &inter_pred_params.conv_params.fwd_offset, 215 &inter_pred_params.conv_params.bck_offset, 216 &inter_pred_params.conv_params.use_dist_wtd_comp_avg, is_compound); 217 218 if (!build_for_obmc) 219 av1_init_warp_params(&inter_pred_params, &warp_types, ref, xd, mi); 220 221 if (is_masked_compound_type(mi->interinter_comp.type)) { 222 inter_pred_params.sb_type = mi->bsize; 223 inter_pred_params.mask_comp = mi->interinter_comp; 224 if (ref == 1) { 225 inter_pred_params.conv_params.do_average = 0; 226 inter_pred_params.comp_mode = MASK_COMP; 227 } 228 // Assign physical buffer. 229 inter_pred_params.mask_comp.seg_mask = xd->seg_mask; 230 } 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 } 239} 240 241#if IS_DEC 242static 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 uint8_t **mc_buf) { 247 if (is_sub8x8_inter(xd, plane, mi->bsize, is_intrabc_block(mi), 248 build_for_obmc)) { 249 assert(bw < 8 || bh < 8); 250 build_inter_predictors_sub8x8(cm, xd, plane, mi, mi_x, mi_y, mc_buf); 251 } else { 252 build_inter_predictors_8x8_and_bigger(cm, xd, plane, mi, build_for_obmc, bw, 253 bh, mi_x, mi_y, mc_buf); 254 } 255} 256#else 257static 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 271