Home | History | Annotate | Download | only in common
      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 #ifndef AOM_AV1_COMMON_RECONINTER_H_
     13 #define AOM_AV1_COMMON_RECONINTER_H_
     14 
     15 #include "av1/common/filter.h"
     16 #include "av1/common/onyxc_int.h"
     17 #include "av1/common/convolve.h"
     18 #include "av1/common/warped_motion.h"
     19 #include "aom/aom_integer.h"
     20 
     21 // Work out how many pixels off the edge of a reference frame we're allowed
     22 // to go when forming an inter prediction.
     23 // The outermost row/col of each referernce frame is extended by
     24 // (AOM_BORDER_IN_PIXELS >> subsampling) pixels, but we need to keep
     25 // at least AOM_INTERP_EXTEND pixels within that to account for filtering.
     26 //
     27 // We have to break this up into two macros to keep both clang-format and
     28 // tools/lint-hunks.py happy.
     29 #define AOM_LEFT_TOP_MARGIN_PX(subsampling) \
     30   ((AOM_BORDER_IN_PIXELS >> subsampling) - AOM_INTERP_EXTEND)
     31 #define AOM_LEFT_TOP_MARGIN_SCALED(subsampling) \
     32   (AOM_LEFT_TOP_MARGIN_PX(subsampling) << SCALE_SUBPEL_BITS)
     33 
     34 #ifdef __cplusplus
     35 extern "C" {
     36 #endif
     37 
     38 // Set to (1 << 5) if the 32-ary codebooks are used for any bock size
     39 #define MAX_WEDGE_TYPES (1 << 4)
     40 
     41 #define MAX_WEDGE_SIZE_LOG2 5  // 32x32
     42 #define MAX_WEDGE_SIZE (1 << MAX_WEDGE_SIZE_LOG2)
     43 #define MAX_WEDGE_SQUARE (MAX_WEDGE_SIZE * MAX_WEDGE_SIZE)
     44 
     45 #define WEDGE_WEIGHT_BITS 6
     46 
     47 #define WEDGE_NONE -1
     48 
     49 // Angles are with respect to horizontal anti-clockwise
     50 enum {
     51   WEDGE_HORIZONTAL = 0,
     52   WEDGE_VERTICAL = 1,
     53   WEDGE_OBLIQUE27 = 2,
     54   WEDGE_OBLIQUE63 = 3,
     55   WEDGE_OBLIQUE117 = 4,
     56   WEDGE_OBLIQUE153 = 5,
     57   WEDGE_DIRECTIONS
     58 } UENUM1BYTE(WedgeDirectionType);
     59 
     60 // 3-tuple: {direction, x_offset, y_offset}
     61 typedef struct {
     62   WedgeDirectionType direction;
     63   int x_offset;
     64   int y_offset;
     65 } wedge_code_type;
     66 
     67 typedef uint8_t *wedge_masks_type[MAX_WEDGE_TYPES];
     68 
     69 typedef struct {
     70   int bits;
     71   const wedge_code_type *codebook;
     72   uint8_t *signflip;
     73   wedge_masks_type *masks;
     74 } wedge_params_type;
     75 
     76 extern const wedge_params_type wedge_params_lookup[BLOCK_SIZES_ALL];
     77 
     78 typedef struct SubpelParams {
     79   int xs;
     80   int ys;
     81   int subpel_x;
     82   int subpel_y;
     83 } SubpelParams;
     84 
     85 struct build_prediction_ctxt {
     86   const AV1_COMMON *cm;
     87   int mi_row;
     88   int mi_col;
     89   uint8_t **tmp_buf;
     90   int *tmp_width;
     91   int *tmp_height;
     92   int *tmp_stride;
     93   int mb_to_far_edge;
     94 };
     95 
     96 static INLINE int has_scale(int xs, int ys) {
     97   return xs != SCALE_SUBPEL_SHIFTS || ys != SCALE_SUBPEL_SHIFTS;
     98 }
     99 
    100 static INLINE void revert_scale_extra_bits(SubpelParams *sp) {
    101   sp->subpel_x >>= SCALE_EXTRA_BITS;
    102   sp->subpel_y >>= SCALE_EXTRA_BITS;
    103   sp->xs >>= SCALE_EXTRA_BITS;
    104   sp->ys >>= SCALE_EXTRA_BITS;
    105   assert(sp->subpel_x < SUBPEL_SHIFTS);
    106   assert(sp->subpel_y < SUBPEL_SHIFTS);
    107   assert(sp->xs <= SUBPEL_SHIFTS);
    108   assert(sp->ys <= SUBPEL_SHIFTS);
    109 }
    110 
    111 static INLINE void inter_predictor(const uint8_t *src, int src_stride,
    112                                    uint8_t *dst, int dst_stride,
    113                                    const SubpelParams *subpel_params,
    114                                    const struct scale_factors *sf, int w, int h,
    115                                    ConvolveParams *conv_params,
    116                                    InterpFilters interp_filters,
    117                                    int is_intrabc) {
    118   assert(conv_params->do_average == 0 || conv_params->do_average == 1);
    119   assert(sf);
    120   const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
    121   assert(IMPLIES(is_intrabc, !is_scaled));
    122   if (is_scaled) {
    123     av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
    124                            interp_filters, subpel_params->subpel_x,
    125                            subpel_params->xs, subpel_params->subpel_y,
    126                            subpel_params->ys, 1, conv_params, sf, is_intrabc);
    127   } else {
    128     SubpelParams sp = *subpel_params;
    129     revert_scale_extra_bits(&sp);
    130     av1_convolve_2d_facade(src, src_stride, dst, dst_stride, w, h,
    131                            interp_filters, sp.subpel_x, sp.xs, sp.subpel_y,
    132                            sp.ys, 0, conv_params, sf, is_intrabc);
    133   }
    134 }
    135 
    136 static INLINE void highbd_inter_predictor(const uint8_t *src, int src_stride,
    137                                           uint8_t *dst, int dst_stride,
    138                                           const SubpelParams *subpel_params,
    139                                           const struct scale_factors *sf, int w,
    140                                           int h, ConvolveParams *conv_params,
    141                                           InterpFilters interp_filters,
    142                                           int is_intrabc, int bd) {
    143   assert(conv_params->do_average == 0 || conv_params->do_average == 1);
    144   assert(sf);
    145   const int is_scaled = has_scale(subpel_params->xs, subpel_params->ys);
    146   assert(IMPLIES(is_intrabc, !is_scaled));
    147   if (is_scaled) {
    148     av1_highbd_convolve_2d_facade(
    149         src, src_stride, dst, dst_stride, w, h, interp_filters,
    150         subpel_params->subpel_x, subpel_params->xs, subpel_params->subpel_y,
    151         subpel_params->ys, 1, conv_params, sf, is_intrabc, bd);
    152   } else {
    153     SubpelParams sp = *subpel_params;
    154     revert_scale_extra_bits(&sp);
    155     av1_highbd_convolve_2d_facade(
    156         src, src_stride, dst, dst_stride, w, h, interp_filters, sp.subpel_x,
    157         sp.xs, sp.subpel_y, sp.ys, 0, conv_params, sf, is_intrabc, bd);
    158   }
    159 }
    160 
    161 void av1_modify_neighbor_predictor_for_obmc(MB_MODE_INFO *mbmi);
    162 int av1_skip_u4x4_pred_in_obmc(BLOCK_SIZE bsize,
    163                                const struct macroblockd_plane *pd, int dir);
    164 
    165 static INLINE int is_interinter_compound_used(COMPOUND_TYPE type,
    166                                               BLOCK_SIZE sb_type) {
    167   const int comp_allowed = is_comp_ref_allowed(sb_type);
    168   switch (type) {
    169     case COMPOUND_AVERAGE:
    170     case COMPOUND_DISTWTD:
    171     case COMPOUND_DIFFWTD: return comp_allowed;
    172     case COMPOUND_WEDGE:
    173       return comp_allowed && wedge_params_lookup[sb_type].bits > 0;
    174     default: assert(0); return 0;
    175   }
    176 }
    177 
    178 static INLINE int is_any_masked_compound_used(BLOCK_SIZE sb_type) {
    179   COMPOUND_TYPE comp_type;
    180   int i;
    181   if (!is_comp_ref_allowed(sb_type)) return 0;
    182   for (i = 0; i < COMPOUND_TYPES; i++) {
    183     comp_type = (COMPOUND_TYPE)i;
    184     if (is_masked_compound_type(comp_type) &&
    185         is_interinter_compound_used(comp_type, sb_type))
    186       return 1;
    187   }
    188   return 0;
    189 }
    190 
    191 static INLINE int get_wedge_bits_lookup(BLOCK_SIZE sb_type) {
    192   return wedge_params_lookup[sb_type].bits;
    193 }
    194 
    195 static INLINE int get_interinter_wedge_bits(BLOCK_SIZE sb_type) {
    196   const int wbits = wedge_params_lookup[sb_type].bits;
    197   return (wbits > 0) ? wbits + 1 : 0;
    198 }
    199 
    200 static INLINE int is_interintra_wedge_used(BLOCK_SIZE sb_type) {
    201   return wedge_params_lookup[sb_type].bits > 0;
    202 }
    203 
    204 static INLINE int get_interintra_wedge_bits(BLOCK_SIZE sb_type) {
    205   return wedge_params_lookup[sb_type].bits;
    206 }
    207 
    208 void av1_make_inter_predictor(const uint8_t *src, int src_stride, uint8_t *dst,
    209                               int dst_stride, const SubpelParams *subpel_params,
    210                               const struct scale_factors *sf, int w, int h,
    211                               ConvolveParams *conv_params,
    212                               InterpFilters interp_filters,
    213                               const WarpTypesAllowed *warp_types, int p_col,
    214                               int p_row, int plane, int ref,
    215                               const MB_MODE_INFO *mi, int build_for_obmc,
    216                               const MACROBLOCKD *xd, int can_use_previous);
    217 
    218 void av1_make_masked_inter_predictor(
    219     const uint8_t *pre, int pre_stride, uint8_t *dst, int dst_stride,
    220     const SubpelParams *subpel_params, const struct scale_factors *sf, int w,
    221     int h, ConvolveParams *conv_params, InterpFilters interp_filters, int plane,
    222     const WarpTypesAllowed *warp_types, int p_col, int p_row, int ref,
    223     MACROBLOCKD *xd, int can_use_previous);
    224 
    225 // TODO(jkoleszar): yet another mv clamping function :-(
    226 static INLINE MV clamp_mv_to_umv_border_sb(const MACROBLOCKD *xd,
    227                                            const MV *src_mv, int bw, int bh,
    228                                            int ss_x, int ss_y) {
    229   // If the MV points so far into the UMV border that no visible pixels
    230   // are used for reconstruction, the subpel part of the MV can be
    231   // discarded and the MV limited to 16 pixels with equivalent results.
    232   const int spel_left = (AOM_INTERP_EXTEND + bw) << SUBPEL_BITS;
    233   const int spel_right = spel_left - SUBPEL_SHIFTS;
    234   const int spel_top = (AOM_INTERP_EXTEND + bh) << SUBPEL_BITS;
    235   const int spel_bottom = spel_top - SUBPEL_SHIFTS;
    236   MV clamped_mv = { (int16_t)(src_mv->row * (1 << (1 - ss_y))),
    237                     (int16_t)(src_mv->col * (1 << (1 - ss_x))) };
    238   assert(ss_x <= 1);
    239   assert(ss_y <= 1);
    240 
    241   clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
    242            xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
    243            xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
    244            xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom);
    245 
    246   return clamped_mv;
    247 }
    248 
    249 static INLINE int64_t scaled_buffer_offset(int x_offset, int y_offset,
    250                                            int stride,
    251                                            const struct scale_factors *sf) {
    252   const int x =
    253       sf ? sf->scale_value_x(x_offset, sf) >> SCALE_EXTRA_BITS : x_offset;
    254   const int y =
    255       sf ? sf->scale_value_y(y_offset, sf) >> SCALE_EXTRA_BITS : y_offset;
    256   return (int64_t)y * stride + x;
    257 }
    258 
    259 static INLINE void setup_pred_plane(struct buf_2d *dst, BLOCK_SIZE bsize,
    260                                     uint8_t *src, int width, int height,
    261                                     int stride, int mi_row, int mi_col,
    262                                     const struct scale_factors *scale,
    263                                     int subsampling_x, int subsampling_y) {
    264   // Offset the buffer pointer
    265   if (subsampling_y && (mi_row & 0x01) && (mi_size_high[bsize] == 1))
    266     mi_row -= 1;
    267   if (subsampling_x && (mi_col & 0x01) && (mi_size_wide[bsize] == 1))
    268     mi_col -= 1;
    269 
    270   const int x = (MI_SIZE * mi_col) >> subsampling_x;
    271   const int y = (MI_SIZE * mi_row) >> subsampling_y;
    272   dst->buf = src + scaled_buffer_offset(x, y, stride, scale);
    273   dst->buf0 = src;
    274   dst->width = width;
    275   dst->height = height;
    276   dst->stride = stride;
    277 }
    278 
    279 void av1_setup_dst_planes(struct macroblockd_plane *planes, BLOCK_SIZE bsize,
    280                           const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
    281                           const int plane_start, const int plane_end);
    282 
    283 void av1_setup_pre_planes(MACROBLOCKD *xd, int idx,
    284                           const YV12_BUFFER_CONFIG *src, int mi_row, int mi_col,
    285                           const struct scale_factors *sf, const int num_planes);
    286 
    287 static INLINE void set_default_interp_filters(
    288     MB_MODE_INFO *const mbmi, InterpFilter frame_interp_filter) {
    289   mbmi->interp_filters =
    290       av1_broadcast_interp_filter(av1_unswitchable_filter(frame_interp_filter));
    291 }
    292 
    293 static INLINE int av1_is_interp_needed(const MACROBLOCKD *const xd) {
    294   const MB_MODE_INFO *const mbmi = xd->mi[0];
    295   if (mbmi->skip_mode) return 0;
    296   if (mbmi->motion_mode == WARPED_CAUSAL) return 0;
    297   if (is_nontrans_global_motion(xd, xd->mi[0])) return 0;
    298   return 1;
    299 }
    300 
    301 void av1_setup_build_prediction_by_above_pred(
    302     MACROBLOCKD *xd, int rel_mi_col, uint8_t above_mi_width,
    303     MB_MODE_INFO *above_mbmi, struct build_prediction_ctxt *ctxt,
    304     const int num_planes);
    305 void av1_setup_build_prediction_by_left_pred(MACROBLOCKD *xd, int rel_mi_row,
    306                                              uint8_t left_mi_height,
    307                                              MB_MODE_INFO *left_mbmi,
    308                                              struct build_prediction_ctxt *ctxt,
    309                                              const int num_planes);
    310 void av1_build_obmc_inter_prediction(const AV1_COMMON *cm, MACROBLOCKD *xd,
    311                                      int mi_row, int mi_col,
    312                                      uint8_t *above[MAX_MB_PLANE],
    313                                      int above_stride[MAX_MB_PLANE],
    314                                      uint8_t *left[MAX_MB_PLANE],
    315                                      int left_stride[MAX_MB_PLANE]);
    316 
    317 const uint8_t *av1_get_obmc_mask(int length);
    318 void av1_count_overlappable_neighbors(const AV1_COMMON *cm, MACROBLOCKD *xd,
    319                                       int mi_row, int mi_col);
    320 
    321 #define MASK_MASTER_SIZE ((MAX_WEDGE_SIZE) << 1)
    322 #define MASK_MASTER_STRIDE (MASK_MASTER_SIZE)
    323 
    324 void av1_init_wedge_masks();
    325 
    326 static INLINE const uint8_t *av1_get_contiguous_soft_mask(int wedge_index,
    327                                                           int wedge_sign,
    328                                                           BLOCK_SIZE sb_type) {
    329   return wedge_params_lookup[sb_type].masks[wedge_sign][wedge_index];
    330 }
    331 
    332 const uint8_t *av1_get_compound_type_mask(
    333     const INTERINTER_COMPOUND_DATA *const comp_data, BLOCK_SIZE sb_type);
    334 
    335 // build interintra_predictors for one plane
    336 void av1_build_interintra_predictors_sbp(const AV1_COMMON *cm, MACROBLOCKD *xd,
    337                                          uint8_t *pred, int stride,
    338                                          const BUFFER_SET *ctx, int plane,
    339                                          BLOCK_SIZE bsize);
    340 
    341 void av1_build_interintra_predictors_sbuv(const AV1_COMMON *cm, MACROBLOCKD *xd,
    342                                           uint8_t *upred, uint8_t *vpred,
    343                                           int ustride, int vstride,
    344                                           const BUFFER_SET *ctx,
    345                                           BLOCK_SIZE bsize);
    346 
    347 void av1_build_intra_predictors_for_interintra(
    348     const AV1_COMMON *cm, MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
    349     const BUFFER_SET *ctx, uint8_t *intra_pred, int intra_stride);
    350 
    351 void av1_combine_interintra(MACROBLOCKD *xd, BLOCK_SIZE bsize, int plane,
    352                             const uint8_t *inter_pred, int inter_stride,
    353                             const uint8_t *intra_pred, int intra_stride);
    354 
    355 void av1_dist_wtd_comp_weight_assign(const AV1_COMMON *cm,
    356                                      const MB_MODE_INFO *mbmi, int order_idx,
    357                                      int *fwd_offset, int *bck_offset,
    358                                      int *use_dist_wtd_comp_avg,
    359                                      int is_compound);
    360 int av1_allow_warp(const MB_MODE_INFO *const mbmi,
    361                    const WarpTypesAllowed *const warp_types,
    362                    const WarpedMotionParams *const gm_params,
    363                    int build_for_obmc, const struct scale_factors *const sf,
    364                    WarpedMotionParams *final_warp_params);
    365 
    366 #ifdef __cplusplus
    367 }  // extern "C"
    368 #endif
    369 
    370 #endif  // AOM_AV1_COMMON_RECONINTER_H_
    371