tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

reconinter_template.inc (11548B)


      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                                             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  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
     54 static 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
     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                                                 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  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
    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    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  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
    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                                          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
    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