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