1 /* 2 * Copyright (c) 2016, 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 #include <assert.h> 13 #include <stdio.h> 14 #include <limits.h> 15 16 #include "config/aom_config.h" 17 #include "config/aom_dsp_rtcd.h" 18 #include "config/aom_scale_rtcd.h" 19 20 #include "aom/aom_integer.h" 21 #include "aom_dsp/blend.h" 22 23 #include "av1/common/blockd.h" 24 #include "av1/common/mvref_common.h" 25 #include "av1/common/reconinter.h" 26 #include "av1/common/reconintra.h" 27 #include "av1/common/onyxc_int.h" 28 #include "av1/common/obmc.h" 29 #include "av1/encoder/reconinter_enc.h" 30 31 static INLINE void calc_subpel_params( 32 MACROBLOCKD *xd, const struct scale_factors *const sf, const MV mv, 33 int plane, const int pre_x, const int pre_y, int x, int y, 34 struct buf_2d *const pre_buf, uint8_t **pre, SubpelParams *subpel_params, 35 int bw, int bh) { 36 struct macroblockd_plane *const pd = &xd->plane[plane]; 37 const int is_scaled = av1_is_scaled(sf); 38 if (is_scaled) { 39 int ssx = pd->subsampling_x; 40 int ssy = pd->subsampling_y; 41 int orig_pos_y = (pre_y + y) << SUBPEL_BITS; 42 orig_pos_y += mv.row * (1 << (1 - ssy)); 43 int orig_pos_x = (pre_x + x) << SUBPEL_BITS; 44 orig_pos_x += mv.col * (1 << (1 - ssx)); 45 int pos_y = sf->scale_value_y(orig_pos_y, sf); 46 int pos_x = sf->scale_value_x(orig_pos_x, sf); 47 pos_x += SCALE_EXTRA_OFF; 48 pos_y += SCALE_EXTRA_OFF; 49 50 const int top = -AOM_LEFT_TOP_MARGIN_SCALED(ssy); 51 const int left = -AOM_LEFT_TOP_MARGIN_SCALED(ssx); 52 const int bottom = (pre_buf->height + AOM_INTERP_EXTEND) 53 << SCALE_SUBPEL_BITS; 54 const int right = (pre_buf->width + AOM_INTERP_EXTEND) << SCALE_SUBPEL_BITS; 55 pos_y = clamp(pos_y, top, bottom); 56 pos_x = clamp(pos_x, left, right); 57 58 *pre = pre_buf->buf0 + (pos_y >> SCALE_SUBPEL_BITS) * pre_buf->stride + 59 (pos_x >> SCALE_SUBPEL_BITS); 60 subpel_params->subpel_x = pos_x & SCALE_SUBPEL_MASK; 61 subpel_params->subpel_y = pos_y & SCALE_SUBPEL_MASK; 62 subpel_params->xs = sf->x_step_q4; 63 subpel_params->ys = sf->y_step_q4; 64 } else { 65 const MV mv_q4 = clamp_mv_to_umv_border_sb( 66 xd, &mv, bw, bh, pd->subsampling_x, pd->subsampling_y); 67 subpel_params->xs = subpel_params->ys = SCALE_SUBPEL_SHIFTS; 68 subpel_params->subpel_x = (mv_q4.col & SUBPEL_MASK) << SCALE_EXTRA_BITS; 69 subpel_params->subpel_y = (mv_q4.row & SUBPEL_MASK) << SCALE_EXTRA_BITS; 70 *pre = pre_buf->buf + (y + (mv_q4.row >> SUBPEL_BITS)) * pre_buf->stride + 71 (x + (mv_q4.col >> SUBPEL_BITS)); 72 } 73 } 74 75 static INLINE void build_inter_predictors(const AV1_COMMON *cm, MACROBLOCKD *xd, 76 int plane, const MB_MODE_INFO *mi, 77 int build_for_obmc, int bw, int bh, 78 int mi_x, int mi_y) { 79 struct macroblockd_plane *const pd = &xd->plane[plane]; 80 int is_compound = has_second_ref(mi); 81 int ref; 82 const int is_intrabc = is_intrabc_block(mi); 83 assert(IMPLIES(is_intrabc, !is_compound)); 84 int is_global[2] = { 0, 0 }; 85 for (ref = 0; ref < 1 + is_compound; ++ref) { 86 const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]]; 87 is_global[ref] = is_global_mv_block(mi, wm->wmtype); 88 } 89 90 const BLOCK_SIZE bsize = mi->sb_type; 91 const int ss_x = pd->subsampling_x; 92 const int ss_y = pd->subsampling_y; 93 int sub8x8_inter = (block_size_wide[bsize] < 8 && ss_x) || 94 (block_size_high[bsize] < 8 && ss_y); 95 96 if (is_intrabc) sub8x8_inter = 0; 97 98 // For sub8x8 chroma blocks, we may be covering more than one luma block's 99 // worth of pixels. Thus (mi_x, mi_y) may not be the correct coordinates for 100 // the top-left corner of the prediction source - the correct top-left corner 101 // is at (pre_x, pre_y). 102 const int row_start = 103 (block_size_high[bsize] == 4) && ss_y && !build_for_obmc ? -1 : 0; 104 const int col_start = 105 (block_size_wide[bsize] == 4) && ss_x && !build_for_obmc ? -1 : 0; 106 const int pre_x = (mi_x + MI_SIZE * col_start) >> ss_x; 107 const int pre_y = (mi_y + MI_SIZE * row_start) >> ss_y; 108 109 sub8x8_inter = sub8x8_inter && !build_for_obmc; 110 if (sub8x8_inter) { 111 for (int row = row_start; row <= 0 && sub8x8_inter; ++row) { 112 for (int col = col_start; col <= 0; ++col) { 113 const MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col]; 114 if (!is_inter_block(this_mbmi)) sub8x8_inter = 0; 115 if (is_intrabc_block(this_mbmi)) sub8x8_inter = 0; 116 } 117 } 118 } 119 120 if (sub8x8_inter) { 121 // block size 122 const int b4_w = block_size_wide[bsize] >> ss_x; 123 const int b4_h = block_size_high[bsize] >> ss_y; 124 const BLOCK_SIZE plane_bsize = scale_chroma_bsize(bsize, ss_x, ss_y); 125 const int b8_w = block_size_wide[plane_bsize] >> ss_x; 126 const int b8_h = block_size_high[plane_bsize] >> ss_y; 127 assert(!is_compound); 128 129 const struct buf_2d orig_pred_buf[2] = { pd->pre[0], pd->pre[1] }; 130 131 int row = row_start; 132 for (int y = 0; y < b8_h; y += b4_h) { 133 int col = col_start; 134 for (int x = 0; x < b8_w; x += b4_w) { 135 MB_MODE_INFO *this_mbmi = xd->mi[row * xd->mi_stride + col]; 136 is_compound = has_second_ref(this_mbmi); 137 int tmp_dst_stride = 8; 138 assert(bw < 8 || bh < 8); 139 ConvolveParams conv_params = get_conv_params_no_round( 140 0, plane, xd->tmp_conv_dst, tmp_dst_stride, is_compound, xd->bd); 141 conv_params.use_dist_wtd_comp_avg = 0; 142 struct buf_2d *const dst_buf = &pd->dst; 143 uint8_t *dst = dst_buf->buf + dst_buf->stride * y + x; 144 145 ref = 0; 146 const RefCntBuffer *ref_buf = 147 get_ref_frame_buf(cm, this_mbmi->ref_frame[ref]); 148 const struct scale_factors *ref_scale_factors = 149 get_ref_scale_factors_const(cm, this_mbmi->ref_frame[ref]); 150 151 pd->pre[ref].buf0 = 152 (plane == 1) ? ref_buf->buf.u_buffer : ref_buf->buf.v_buffer; 153 pd->pre[ref].buf = 154 pd->pre[ref].buf0 + scaled_buffer_offset(pre_x, pre_y, 155 ref_buf->buf.uv_stride, 156 ref_scale_factors); 157 pd->pre[ref].width = ref_buf->buf.uv_crop_width; 158 pd->pre[ref].height = ref_buf->buf.uv_crop_height; 159 pd->pre[ref].stride = ref_buf->buf.uv_stride; 160 161 const struct scale_factors *const sf = 162 is_intrabc ? &cm->sf_identity : ref_scale_factors; 163 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref]; 164 165 const MV mv = this_mbmi->mv[ref].as_mv; 166 167 uint8_t *pre; 168 SubpelParams subpel_params; 169 WarpTypesAllowed warp_types; 170 warp_types.global_warp_allowed = is_global[ref]; 171 warp_types.local_warp_allowed = this_mbmi->motion_mode == WARPED_CAUSAL; 172 173 calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf, &pre, 174 &subpel_params, bw, bh); 175 conv_params.do_average = ref; 176 if (is_masked_compound_type(mi->interinter_comp.type)) { 177 // masked compound type has its own average mechanism 178 conv_params.do_average = 0; 179 } 180 181 av1_make_inter_predictor( 182 pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, 183 b4_w, b4_h, &conv_params, this_mbmi->interp_filters, &warp_types, 184 (mi_x >> pd->subsampling_x) + x, (mi_y >> pd->subsampling_y) + y, 185 plane, ref, mi, build_for_obmc, xd, cm->allow_warped_motion); 186 187 ++col; 188 } 189 ++row; 190 } 191 192 for (ref = 0; ref < 2; ++ref) pd->pre[ref] = orig_pred_buf[ref]; 193 return; 194 } 195 196 { 197 ConvolveParams conv_params = get_conv_params_no_round( 198 0, plane, xd->tmp_conv_dst, MAX_SB_SIZE, is_compound, xd->bd); 199 av1_dist_wtd_comp_weight_assign( 200 cm, mi, 0, &conv_params.fwd_offset, &conv_params.bck_offset, 201 &conv_params.use_dist_wtd_comp_avg, is_compound); 202 203 struct buf_2d *const dst_buf = &pd->dst; 204 uint8_t *const dst = dst_buf->buf; 205 for (ref = 0; ref < 1 + is_compound; ++ref) { 206 const struct scale_factors *const sf = 207 is_intrabc ? &cm->sf_identity : xd->block_ref_scale_factors[ref]; 208 struct buf_2d *const pre_buf = is_intrabc ? dst_buf : &pd->pre[ref]; 209 const MV mv = mi->mv[ref].as_mv; 210 211 uint8_t *pre; 212 SubpelParams subpel_params; 213 calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, 0, 0, pre_buf, &pre, 214 &subpel_params, bw, bh); 215 216 WarpTypesAllowed warp_types; 217 warp_types.global_warp_allowed = is_global[ref]; 218 warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL; 219 220 if (ref && is_masked_compound_type(mi->interinter_comp.type)) { 221 // masked compound type has its own average mechanism 222 conv_params.do_average = 0; 223 av1_make_masked_inter_predictor( 224 pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, bw, 225 bh, &conv_params, mi->interp_filters, plane, &warp_types, 226 mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y, ref, xd, 227 cm->allow_warped_motion); 228 } else { 229 conv_params.do_average = ref; 230 av1_make_inter_predictor( 231 pre, pre_buf->stride, dst, dst_buf->stride, &subpel_params, sf, bw, 232 bh, &conv_params, mi->interp_filters, &warp_types, 233 mi_x >> pd->subsampling_x, mi_y >> pd->subsampling_y, plane, ref, 234 mi, build_for_obmc, xd, cm->allow_warped_motion); 235 } 236 } 237 } 238 } 239 240 static void build_inter_predictors_for_plane(const AV1_COMMON *cm, 241 MACROBLOCKD *xd, int mi_row, 242 int mi_col, const BUFFER_SET *ctx, 243 BLOCK_SIZE bsize, int plane_idx) { 244 const struct macroblockd_plane *pd = &xd->plane[plane_idx]; 245 if (!is_chroma_reference(mi_row, mi_col, bsize, pd->subsampling_x, 246 pd->subsampling_y)) 247 return; 248 249 const int mi_x = mi_col * MI_SIZE; 250 const int mi_y = mi_row * MI_SIZE; 251 build_inter_predictors(cm, xd, plane_idx, xd->mi[0], 0, pd->width, pd->height, 252 mi_x, mi_y); 253 254 if (is_interintra_pred(xd->mi[0])) { 255 BUFFER_SET default_ctx = { { NULL, NULL, NULL }, { 0, 0, 0 } }; 256 if (!ctx) { 257 default_ctx.plane[plane_idx] = xd->plane[plane_idx].dst.buf; 258 default_ctx.stride[plane_idx] = xd->plane[plane_idx].dst.stride; 259 ctx = &default_ctx; 260 } 261 av1_build_interintra_predictors_sbp(cm, xd, xd->plane[plane_idx].dst.buf, 262 xd->plane[plane_idx].dst.stride, ctx, 263 plane_idx, bsize); 264 } 265 } 266 267 void av1_enc_build_inter_predictor(const AV1_COMMON *cm, MACROBLOCKD *xd, 268 int mi_row, int mi_col, 269 const BUFFER_SET *ctx, BLOCK_SIZE bsize, 270 int plane_from, int plane_to) { 271 for (int plane_idx = plane_from; plane_idx <= plane_to; ++plane_idx) { 272 build_inter_predictors_for_plane(cm, xd, mi_row, mi_col, ctx, bsize, 273 plane_idx); 274 } 275 } 276 277 // TODO(sarahparker): 278 // av1_build_inter_predictor should be combined with 279 // av1_make_inter_predictor 280 void av1_build_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst, 281 int dst_stride, const MV *src_mv, 282 const struct scale_factors *sf, int w, int h, 283 ConvolveParams *conv_params, 284 InterpFilters interp_filters, 285 const WarpTypesAllowed *warp_types, int p_col, 286 int p_row, int plane, int ref, 287 mv_precision precision, int x, int y, 288 const MACROBLOCKD *xd, int can_use_previous) { 289 const int is_q4 = precision == MV_PRECISION_Q4; 290 const MV mv_q4 = { is_q4 ? src_mv->row : src_mv->row * 2, 291 is_q4 ? src_mv->col : src_mv->col * 2 }; 292 MV32 mv = av1_scale_mv(&mv_q4, x, y, sf); 293 mv.col += SCALE_EXTRA_OFF; 294 mv.row += SCALE_EXTRA_OFF; 295 296 const SubpelParams subpel_params = { sf->x_step_q4, sf->y_step_q4, 297 mv.col & SCALE_SUBPEL_MASK, 298 mv.row & SCALE_SUBPEL_MASK }; 299 src += (mv.row >> SCALE_SUBPEL_BITS) * src_stride + 300 (mv.col >> SCALE_SUBPEL_BITS); 301 302 av1_make_inter_predictor(src, src_stride, dst, dst_stride, &subpel_params, sf, 303 w, h, conv_params, interp_filters, warp_types, p_col, 304 p_row, plane, ref, xd->mi[0], 0, xd, 305 can_use_previous); 306 } 307 308 static INLINE void build_prediction_by_above_pred( 309 MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width, 310 MB_MODE_INFO *above_mbmi, void *fun_ctxt, const int num_planes) { 311 struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; 312 const int above_mi_col = ctxt->mi_col + rel_mi_col; 313 int mi_x, mi_y; 314 MB_MODE_INFO backup_mbmi = *above_mbmi; 315 316 av1_setup_build_prediction_by_above_pred(xd, rel_mi_col, above_mi_width, 317 &backup_mbmi, ctxt, num_planes); 318 mi_x = above_mi_col << MI_SIZE_LOG2; 319 mi_y = ctxt->mi_row << MI_SIZE_LOG2; 320 321 const BLOCK_SIZE bsize = xd->mi[0]->sb_type; 322 323 for (int j = 0; j < num_planes; ++j) { 324 const struct macroblockd_plane *pd = &xd->plane[j]; 325 int bw = (above_mi_width * MI_SIZE) >> pd->subsampling_x; 326 int bh = clamp(block_size_high[bsize] >> (pd->subsampling_y + 1), 4, 327 block_size_high[BLOCK_64X64] >> (pd->subsampling_y + 1)); 328 329 if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 0)) continue; 330 build_inter_predictors(ctxt->cm, xd, j, &backup_mbmi, 1, bw, bh, mi_x, 331 mi_y); 332 } 333 } 334 335 void av1_build_prediction_by_above_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, 336 int mi_row, int mi_col, 337 uint8_t *tmp_buf[MAX_MB_PLANE], 338 int tmp_width[MAX_MB_PLANE], 339 int tmp_height[MAX_MB_PLANE], 340 int tmp_stride[MAX_MB_PLANE]) { 341 if (!xd->up_available) return; 342 343 // Adjust mb_to_bottom_edge to have the correct value for the OBMC 344 // prediction block. This is half the height of the original block, 345 // except for 128-wide blocks, where we only use a height of 32. 346 int this_height = xd->n4_h * MI_SIZE; 347 int pred_height = AOMMIN(this_height / 2, 32); 348 xd->mb_to_bottom_edge += (this_height - pred_height) * 8; 349 350 struct build_prediction_ctxt ctxt = { cm, mi_row, 351 mi_col, tmp_buf, 352 tmp_width, tmp_height, 353 tmp_stride, xd->mb_to_right_edge }; 354 BLOCK_SIZE bsize = xd->mi[0]->sb_type; 355 foreach_overlappable_nb_above(cm, xd, mi_col, 356 max_neighbor_obmc[mi_size_wide_log2[bsize]], 357 build_prediction_by_above_pred, &ctxt); 358 359 xd->mb_to_left_edge = -((mi_col * MI_SIZE) * 8); 360 xd->mb_to_right_edge = ctxt.mb_to_far_edge; 361 xd->mb_to_bottom_edge -= (this_height - pred_height) * 8; 362 } 363 364 static INLINE void build_prediction_by_left_pred( 365 MACROBLOCKD *xd, int rel_mi_row, uint8_t left_mi_height, 366 MB_MODE_INFO *left_mbmi, void *fun_ctxt, const int num_planes) { 367 struct build_prediction_ctxt *ctxt = (struct build_prediction_ctxt *)fun_ctxt; 368 const int left_mi_row = ctxt->mi_row + rel_mi_row; 369 int mi_x, mi_y; 370 MB_MODE_INFO backup_mbmi = *left_mbmi; 371 372 av1_setup_build_prediction_by_left_pred(xd, rel_mi_row, left_mi_height, 373 &backup_mbmi, ctxt, num_planes); 374 mi_x = ctxt->mi_col << MI_SIZE_LOG2; 375 mi_y = left_mi_row << MI_SIZE_LOG2; 376 const BLOCK_SIZE bsize = xd->mi[0]->sb_type; 377 378 for (int j = 0; j < num_planes; ++j) { 379 const struct macroblockd_plane *pd = &xd->plane[j]; 380 int bw = clamp(block_size_wide[bsize] >> (pd->subsampling_x + 1), 4, 381 block_size_wide[BLOCK_64X64] >> (pd->subsampling_x + 1)); 382 int bh = (left_mi_height << MI_SIZE_LOG2) >> pd->subsampling_y; 383 384 if (av1_skip_u4x4_pred_in_obmc(bsize, pd, 1)) continue; 385 build_inter_predictors(ctxt->cm, xd, j, &backup_mbmi, 1, bw, bh, mi_x, 386 mi_y); 387 } 388 } 389 390 void av1_build_prediction_by_left_preds(const AV1_COMMON *cm, MACROBLOCKD *xd, 391 int mi_row, int mi_col, 392 uint8_t *tmp_buf[MAX_MB_PLANE], 393 int tmp_width[MAX_MB_PLANE], 394 int tmp_height[MAX_MB_PLANE], 395 int tmp_stride[MAX_MB_PLANE]) { 396 if (!xd->left_available) return; 397 398 // Adjust mb_to_right_edge to have the correct value for the OBMC 399 // prediction block. This is half the width of the original block, 400 // except for 128-wide blocks, where we only use a width of 32. 401 int this_width = xd->n4_w * MI_SIZE; 402 int pred_width = AOMMIN(this_width / 2, 32); 403 xd->mb_to_right_edge += (this_width - pred_width) * 8; 404 405 struct build_prediction_ctxt ctxt = { cm, mi_row, 406 mi_col, tmp_buf, 407 tmp_width, tmp_height, 408 tmp_stride, xd->mb_to_bottom_edge }; 409 BLOCK_SIZE bsize = xd->mi[0]->sb_type; 410 foreach_overlappable_nb_left(cm, xd, mi_row, 411 max_neighbor_obmc[mi_size_high_log2[bsize]], 412 build_prediction_by_left_pred, &ctxt); 413 414 xd->mb_to_top_edge = -((mi_row * MI_SIZE) * 8); 415 xd->mb_to_right_edge -= (this_width - pred_width) * 8; 416 xd->mb_to_bottom_edge = ctxt.mb_to_far_edge; 417 } 418 419 void av1_build_obmc_inter_predictors_sb(const AV1_COMMON *cm, MACROBLOCKD *xd, 420 int mi_row, int mi_col) { 421 const int num_planes = av1_num_planes(cm); 422 uint8_t *dst_buf1[MAX_MB_PLANE], *dst_buf2[MAX_MB_PLANE]; 423 int dst_stride1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; 424 int dst_stride2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; 425 int dst_width1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; 426 int dst_width2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; 427 int dst_height1[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; 428 int dst_height2[MAX_MB_PLANE] = { MAX_SB_SIZE, MAX_SB_SIZE, MAX_SB_SIZE }; 429 430 if (is_cur_buf_hbd(xd)) { 431 int len = sizeof(uint16_t); 432 dst_buf1[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0]); 433 dst_buf1[1] = 434 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * len); 435 dst_buf1[2] = 436 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2 * len); 437 dst_buf2[0] = CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1]); 438 dst_buf2[1] = 439 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * len); 440 dst_buf2[2] = 441 CONVERT_TO_BYTEPTR(xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2 * len); 442 } else { 443 dst_buf1[0] = xd->tmp_obmc_bufs[0]; 444 dst_buf1[1] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE; 445 dst_buf1[2] = xd->tmp_obmc_bufs[0] + MAX_SB_SQUARE * 2; 446 dst_buf2[0] = xd->tmp_obmc_bufs[1]; 447 dst_buf2[1] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE; 448 dst_buf2[2] = xd->tmp_obmc_bufs[1] + MAX_SB_SQUARE * 2; 449 } 450 av1_build_prediction_by_above_preds(cm, xd, mi_row, mi_col, dst_buf1, 451 dst_width1, dst_height1, dst_stride1); 452 av1_build_prediction_by_left_preds(cm, xd, mi_row, mi_col, dst_buf2, 453 dst_width2, dst_height2, dst_stride2); 454 av1_setup_dst_planes(xd->plane, xd->mi[0]->sb_type, &cm->cur_frame->buf, 455 mi_row, mi_col, 0, num_planes); 456 av1_build_obmc_inter_prediction(cm, xd, mi_row, mi_col, dst_buf1, dst_stride1, 457 dst_buf2, dst_stride2); 458 } 459 460 // Builds the inter-predictor for the single ref case 461 // for use in the encoder to search the wedges efficiently. 462 static void build_inter_predictors_single_buf(MACROBLOCKD *xd, int plane, 463 int bw, int bh, int x, int y, 464 int w, int h, int mi_x, int mi_y, 465 int ref, uint8_t *const ext_dst, 466 int ext_dst_stride, 467 int can_use_previous) { 468 struct macroblockd_plane *const pd = &xd->plane[plane]; 469 const MB_MODE_INFO *mi = xd->mi[0]; 470 471 const struct scale_factors *const sf = xd->block_ref_scale_factors[ref]; 472 struct buf_2d *const pre_buf = &pd->pre[ref]; 473 uint8_t *const dst = get_buf_by_bd(xd, ext_dst) + ext_dst_stride * y + x; 474 const MV mv = mi->mv[ref].as_mv; 475 476 ConvolveParams conv_params = get_conv_params(0, plane, xd->bd); 477 WarpTypesAllowed warp_types; 478 const WarpedMotionParams *const wm = &xd->global_motion[mi->ref_frame[ref]]; 479 warp_types.global_warp_allowed = is_global_mv_block(mi, wm->wmtype); 480 warp_types.local_warp_allowed = mi->motion_mode == WARPED_CAUSAL; 481 const int pre_x = (mi_x) >> pd->subsampling_x; 482 const int pre_y = (mi_y) >> pd->subsampling_y; 483 uint8_t *pre; 484 SubpelParams subpel_params; 485 calc_subpel_params(xd, sf, mv, plane, pre_x, pre_y, x, y, pre_buf, &pre, 486 &subpel_params, bw, bh); 487 488 av1_make_inter_predictor(pre, pre_buf->stride, dst, ext_dst_stride, 489 &subpel_params, sf, w, h, &conv_params, 490 mi->interp_filters, &warp_types, pre_x + x, 491 pre_y + y, plane, ref, mi, 0, xd, can_use_previous); 492 } 493 494 void av1_build_inter_predictors_for_planes_single_buf( 495 MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane_from, int plane_to, int mi_row, 496 int mi_col, int ref, uint8_t *ext_dst[3], int ext_dst_stride[3], 497 int can_use_previous) { 498 int plane; 499 const int mi_x = mi_col * MI_SIZE; 500 const int mi_y = mi_row * MI_SIZE; 501 for (plane = plane_from; plane <= plane_to; ++plane) { 502 const BLOCK_SIZE plane_bsize = get_plane_block_size( 503 bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y); 504 const int bw = block_size_wide[plane_bsize]; 505 const int bh = block_size_high[plane_bsize]; 506 build_inter_predictors_single_buf(xd, plane, bw, bh, 0, 0, bw, bh, mi_x, 507 mi_y, ref, ext_dst[plane], 508 ext_dst_stride[plane], can_use_previous); 509 } 510 } 511 512 static void build_masked_compound( 513 uint8_t *dst, int dst_stride, const uint8_t *src0, int src0_stride, 514 const uint8_t *src1, int src1_stride, 515 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h, 516 int w) { 517 // Derive subsampling from h and w passed in. May be refactored to 518 // pass in subsampling factors directly. 519 const int subh = (2 << mi_size_high_log2[sb_type]) == h; 520 const int subw = (2 << mi_size_wide_log2[sb_type]) == w; 521 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type); 522 aom_blend_a64_mask(dst, dst_stride, src0, src0_stride, src1, src1_stride, 523 mask, block_size_wide[sb_type], w, h, subw, subh); 524 } 525 526 static void build_masked_compound_highbd( 527 uint8_t *dst_8, int dst_stride, const uint8_t *src0_8, int src0_stride, 528 const uint8_t *src1_8, int src1_stride, 529 const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type, int h, 530 int w, int bd) { 531 // Derive subsampling from h and w passed in. May be refactored to 532 // pass in subsampling factors directly. 533 const int subh = (2 << mi_size_high_log2[sb_type]) == h; 534 const int subw = (2 << mi_size_wide_log2[sb_type]) == w; 535 const uint8_t *mask = av1_get_compound_type_mask(comp_data, sb_type); 536 // const uint8_t *mask = 537 // av1_get_contiguous_soft_mask(wedge_index, wedge_sign, sb_type); 538 aom_highbd_blend_a64_mask(dst_8, dst_stride, src0_8, src0_stride, src1_8, 539 src1_stride, mask, block_size_wide[sb_type], w, h, 540 subw, subh, bd); 541 } 542 543 static void build_wedge_inter_predictor_from_buf( 544 MACROBLOCKD *xd, int plane, int x, int y, int w, int h, uint8_t *ext_dst0, 545 int ext_dst_stride0, uint8_t *ext_dst1, int ext_dst_stride1) { 546 MB_MODE_INFO *const mbmi = xd->mi[0]; 547 const int is_compound = has_second_ref(mbmi); 548 MACROBLOCKD_PLANE *const pd = &xd->plane[plane]; 549 struct buf_2d *const dst_buf = &pd->dst; 550 uint8_t *const dst = dst_buf->buf + dst_buf->stride * y + x; 551 mbmi->interinter_comp.seg_mask = xd->seg_mask; 552 const INTERINTER_COMPOUND_DATA *comp_data = &mbmi->interinter_comp; 553 const int is_hbd = is_cur_buf_hbd(xd); 554 555 if (is_compound && is_masked_compound_type(comp_data->type)) { 556 if (!plane && comp_data->type == COMPOUND_DIFFWTD) { 557 if (is_hbd) { 558 av1_build_compound_diffwtd_mask_highbd( 559 comp_data->seg_mask, comp_data->mask_type, 560 CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0, 561 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, h, w, xd->bd); 562 } else { 563 av1_build_compound_diffwtd_mask( 564 comp_data->seg_mask, comp_data->mask_type, ext_dst0, 565 ext_dst_stride0, ext_dst1, ext_dst_stride1, h, w); 566 } 567 } 568 569 if (is_hbd) { 570 build_masked_compound_highbd( 571 dst, dst_buf->stride, CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0, 572 CONVERT_TO_BYTEPTR(ext_dst1), ext_dst_stride1, comp_data, 573 mbmi->sb_type, h, w, xd->bd); 574 } else { 575 build_masked_compound(dst, dst_buf->stride, ext_dst0, ext_dst_stride0, 576 ext_dst1, ext_dst_stride1, comp_data, mbmi->sb_type, 577 h, w); 578 } 579 } else { 580 if (is_hbd) { 581 aom_highbd_convolve_copy(CONVERT_TO_BYTEPTR(ext_dst0), ext_dst_stride0, 582 dst, dst_buf->stride, NULL, 0, NULL, 0, w, h, 583 xd->bd); 584 } else { 585 aom_convolve_copy(ext_dst0, ext_dst_stride0, dst, dst_buf->stride, NULL, 586 0, NULL, 0, w, h); 587 } 588 } 589 } 590 591 void av1_build_wedge_inter_predictor_from_buf(MACROBLOCKD *xd, BLOCK_SIZE bsize, 592 int plane_from, int plane_to, 593 uint8_t *ext_dst0[3], 594 int ext_dst_stride0[3], 595 uint8_t *ext_dst1[3], 596 int ext_dst_stride1[3]) { 597 int plane; 598 for (plane = plane_from; plane <= plane_to; ++plane) { 599 const BLOCK_SIZE plane_bsize = get_plane_block_size( 600 bsize, xd->plane[plane].subsampling_x, xd->plane[plane].subsampling_y); 601 const int bw = block_size_wide[plane_bsize]; 602 const int bh = block_size_high[plane_bsize]; 603 build_wedge_inter_predictor_from_buf( 604 xd, plane, 0, 0, bw, bh, ext_dst0[plane], ext_dst_stride0[plane], 605 ext_dst1[plane], ext_dst_stride1[plane]); 606 } 607 } 608