tor-browser

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

pred_common.h (13473B)


      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_PRED_COMMON_H_
     13 #define AOM_AV1_COMMON_PRED_COMMON_H_
     14 
     15 #include <stdint.h>
     16 
     17 #include "av1/common/av1_common_int.h"
     18 #include "av1/common/blockd.h"
     19 #include "av1/common/mvref_common.h"
     20 #include "aom_dsp/aom_dsp_common.h"
     21 
     22 #ifdef __cplusplus
     23 extern "C" {
     24 #endif
     25 
     26 static inline uint8_t get_segment_id(
     27    const CommonModeInfoParams *const mi_params, const uint8_t *segment_ids,
     28    BLOCK_SIZE bsize, int mi_row, int mi_col) {
     29  const int mi_offset = mi_row * mi_params->mi_cols + mi_col;
     30  const int bw = mi_size_wide[bsize];
     31  const int bh = mi_size_high[bsize];
     32  const int xmis = AOMMIN(mi_params->mi_cols - mi_col, bw);
     33  const int ymis = AOMMIN(mi_params->mi_rows - mi_row, bh);
     34  const int seg_stride = mi_params->mi_cols;
     35  uint8_t segment_id = MAX_SEGMENTS;
     36 
     37  for (int y = 0; y < ymis; ++y) {
     38    for (int x = 0; x < xmis; ++x) {
     39      segment_id =
     40          AOMMIN(segment_id, segment_ids[mi_offset + y * seg_stride + x]);
     41    }
     42  }
     43 
     44  assert(segment_id < MAX_SEGMENTS);
     45  return segment_id;
     46 }
     47 
     48 static inline uint8_t av1_get_spatial_seg_pred(const AV1_COMMON *const cm,
     49                                               const MACROBLOCKD *const xd,
     50                                               int *cdf_index,
     51                                               int skip_over4x4) {
     52  const int step_size = skip_over4x4 ? 2 : 1;
     53  uint8_t prev_ul = UINT8_MAX;  // top left segment_id
     54  uint8_t prev_l = UINT8_MAX;   // left segment_id
     55  uint8_t prev_u = UINT8_MAX;   // top segment_id
     56  const int mi_row = xd->mi_row;
     57  const int mi_col = xd->mi_col;
     58  const CommonModeInfoParams *const mi_params = &cm->mi_params;
     59  const uint8_t *seg_map = cm->cur_frame->seg_map;
     60  if ((xd->up_available) && (xd->left_available)) {
     61    prev_ul = get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - step_size,
     62                             mi_col - step_size);
     63  }
     64  if (xd->up_available) {
     65    prev_u = get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - step_size,
     66                            mi_col - 0);
     67  }
     68  if (xd->left_available) {
     69    prev_l = get_segment_id(mi_params, seg_map, BLOCK_4X4, mi_row - 0,
     70                            mi_col - step_size);
     71  }
     72  assert(IMPLIES(prev_ul != UINT8_MAX,
     73                 prev_u != UINT8_MAX && prev_l != UINT8_MAX));
     74 
     75  // Pick CDF index based on number of matching/out-of-bounds segment IDs.
     76  if (prev_ul == UINT8_MAX) /* Edge cases */
     77    *cdf_index = 0;
     78  else if ((prev_ul == prev_u) && (prev_ul == prev_l))
     79    *cdf_index = 2;
     80  else if ((prev_ul == prev_u) || (prev_ul == prev_l) || (prev_u == prev_l))
     81    *cdf_index = 1;
     82  else
     83    *cdf_index = 0;
     84 
     85  // If 2 or more are identical returns that as predictor, otherwise prev_l.
     86  if (prev_u == UINT8_MAX)  // edge case
     87    return prev_l == UINT8_MAX ? 0 : prev_l;
     88  if (prev_l == UINT8_MAX)  // edge case
     89    return prev_u;
     90  return (prev_ul == prev_u) ? prev_u : prev_l;
     91 }
     92 
     93 static inline uint8_t av1_get_pred_context_seg_id(const MACROBLOCKD *xd) {
     94  const MB_MODE_INFO *const above_mi = xd->above_mbmi;
     95  const MB_MODE_INFO *const left_mi = xd->left_mbmi;
     96  const int above_sip = (above_mi != NULL) ? above_mi->seg_id_predicted : 0;
     97  const int left_sip = (left_mi != NULL) ? left_mi->seg_id_predicted : 0;
     98 
     99  return above_sip + left_sip;
    100 }
    101 
    102 static inline int get_comp_index_context(const AV1_COMMON *cm,
    103                                         const MACROBLOCKD *xd) {
    104  MB_MODE_INFO *mbmi = xd->mi[0];
    105  const RefCntBuffer *const bck_buf = get_ref_frame_buf(cm, mbmi->ref_frame[0]);
    106  const RefCntBuffer *const fwd_buf = get_ref_frame_buf(cm, mbmi->ref_frame[1]);
    107  int bck_frame_index = 0, fwd_frame_index = 0;
    108  int cur_frame_index = cm->cur_frame->order_hint;
    109 
    110  if (bck_buf != NULL) bck_frame_index = bck_buf->order_hint;
    111  if (fwd_buf != NULL) fwd_frame_index = fwd_buf->order_hint;
    112 
    113  int fwd = abs(get_relative_dist(&cm->seq_params->order_hint_info,
    114                                  fwd_frame_index, cur_frame_index));
    115  int bck = abs(get_relative_dist(&cm->seq_params->order_hint_info,
    116                                  cur_frame_index, bck_frame_index));
    117 
    118  const MB_MODE_INFO *const above_mi = xd->above_mbmi;
    119  const MB_MODE_INFO *const left_mi = xd->left_mbmi;
    120 
    121  int above_ctx = 0, left_ctx = 0;
    122  const int offset = (fwd == bck);
    123 
    124  if (above_mi != NULL) {
    125    if (has_second_ref(above_mi))
    126      above_ctx = above_mi->compound_idx;
    127    else if (above_mi->ref_frame[0] == ALTREF_FRAME)
    128      above_ctx = 1;
    129  }
    130 
    131  if (left_mi != NULL) {
    132    if (has_second_ref(left_mi))
    133      left_ctx = left_mi->compound_idx;
    134    else if (left_mi->ref_frame[0] == ALTREF_FRAME)
    135      left_ctx = 1;
    136  }
    137 
    138  return above_ctx + left_ctx + 3 * offset;
    139 }
    140 
    141 static inline int get_comp_group_idx_context(const MACROBLOCKD *xd) {
    142  const MB_MODE_INFO *const above_mi = xd->above_mbmi;
    143  const MB_MODE_INFO *const left_mi = xd->left_mbmi;
    144  int above_ctx = 0, left_ctx = 0;
    145 
    146  if (above_mi) {
    147    if (has_second_ref(above_mi))
    148      above_ctx = above_mi->comp_group_idx;
    149    else if (above_mi->ref_frame[0] == ALTREF_FRAME)
    150      above_ctx = 3;
    151  }
    152  if (left_mi) {
    153    if (has_second_ref(left_mi))
    154      left_ctx = left_mi->comp_group_idx;
    155    else if (left_mi->ref_frame[0] == ALTREF_FRAME)
    156      left_ctx = 3;
    157  }
    158 
    159  return AOMMIN(5, above_ctx + left_ctx);
    160 }
    161 
    162 static inline aom_cdf_prob *av1_get_pred_cdf_seg_id(
    163    struct segmentation_probs *segp, const MACROBLOCKD *xd) {
    164  return segp->pred_cdf[av1_get_pred_context_seg_id(xd)];
    165 }
    166 
    167 static inline int av1_get_skip_mode_context(const MACROBLOCKD *xd) {
    168  const MB_MODE_INFO *const above_mi = xd->above_mbmi;
    169  const MB_MODE_INFO *const left_mi = xd->left_mbmi;
    170  const int above_skip_mode = above_mi ? above_mi->skip_mode : 0;
    171  const int left_skip_mode = left_mi ? left_mi->skip_mode : 0;
    172  return above_skip_mode + left_skip_mode;
    173 }
    174 
    175 static inline int av1_get_skip_txfm_context(const MACROBLOCKD *xd) {
    176  const MB_MODE_INFO *const above_mi = xd->above_mbmi;
    177  const MB_MODE_INFO *const left_mi = xd->left_mbmi;
    178  const int above_skip_txfm = above_mi ? above_mi->skip_txfm : 0;
    179  const int left_skip_txfm = left_mi ? left_mi->skip_txfm : 0;
    180  return above_skip_txfm + left_skip_txfm;
    181 }
    182 
    183 int av1_get_pred_context_switchable_interp(const MACROBLOCKD *xd, int dir);
    184 
    185 // Get a list of palette base colors that are used in the above and left blocks,
    186 // referred to as "color cache". The return value is the number of colors in the
    187 // cache (<= 2 * PALETTE_MAX_SIZE). The color values are stored in "cache"
    188 // in ascending order.
    189 int av1_get_palette_cache(const MACROBLOCKD *const xd, int plane,
    190                          uint16_t *cache);
    191 
    192 static inline int av1_get_palette_bsize_ctx(BLOCK_SIZE bsize) {
    193  assert(bsize < BLOCK_SIZES_ALL);
    194  return num_pels_log2_lookup[bsize] - num_pels_log2_lookup[BLOCK_8X8];
    195 }
    196 
    197 static inline int av1_get_palette_mode_ctx(const MACROBLOCKD *xd) {
    198  const MB_MODE_INFO *const above_mi = xd->above_mbmi;
    199  const MB_MODE_INFO *const left_mi = xd->left_mbmi;
    200  int ctx = 0;
    201  if (above_mi) ctx += (above_mi->palette_mode_info.palette_size[0] > 0);
    202  if (left_mi) ctx += (left_mi->palette_mode_info.palette_size[0] > 0);
    203  return ctx;
    204 }
    205 
    206 int av1_get_intra_inter_context(const MACROBLOCKD *xd);
    207 
    208 int av1_get_reference_mode_context(const MACROBLOCKD *xd);
    209 
    210 static inline aom_cdf_prob *av1_get_reference_mode_cdf(const MACROBLOCKD *xd) {
    211  return xd->tile_ctx->comp_inter_cdf[av1_get_reference_mode_context(xd)];
    212 }
    213 
    214 static inline aom_cdf_prob *av1_get_skip_txfm_cdf(const MACROBLOCKD *xd) {
    215  return xd->tile_ctx->skip_txfm_cdfs[av1_get_skip_txfm_context(xd)];
    216 }
    217 
    218 int av1_get_comp_reference_type_context(const MACROBLOCKD *xd);
    219 
    220 // == Uni-directional contexts ==
    221 
    222 int av1_get_pred_context_uni_comp_ref_p(const MACROBLOCKD *xd);
    223 
    224 int av1_get_pred_context_uni_comp_ref_p1(const MACROBLOCKD *xd);
    225 
    226 int av1_get_pred_context_uni_comp_ref_p2(const MACROBLOCKD *xd);
    227 
    228 static inline aom_cdf_prob *av1_get_comp_reference_type_cdf(
    229    const MACROBLOCKD *xd) {
    230  const int pred_context = av1_get_comp_reference_type_context(xd);
    231  return xd->tile_ctx->comp_ref_type_cdf[pred_context];
    232 }
    233 
    234 static inline aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p(
    235    const MACROBLOCKD *xd) {
    236  const int pred_context = av1_get_pred_context_uni_comp_ref_p(xd);
    237  return xd->tile_ctx->uni_comp_ref_cdf[pred_context][0];
    238 }
    239 
    240 static inline aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p1(
    241    const MACROBLOCKD *xd) {
    242  const int pred_context = av1_get_pred_context_uni_comp_ref_p1(xd);
    243  return xd->tile_ctx->uni_comp_ref_cdf[pred_context][1];
    244 }
    245 
    246 static inline aom_cdf_prob *av1_get_pred_cdf_uni_comp_ref_p2(
    247    const MACROBLOCKD *xd) {
    248  const int pred_context = av1_get_pred_context_uni_comp_ref_p2(xd);
    249  return xd->tile_ctx->uni_comp_ref_cdf[pred_context][2];
    250 }
    251 
    252 // == Bi-directional contexts ==
    253 
    254 int av1_get_pred_context_comp_ref_p(const MACROBLOCKD *xd);
    255 
    256 int av1_get_pred_context_comp_ref_p1(const MACROBLOCKD *xd);
    257 
    258 int av1_get_pred_context_comp_ref_p2(const MACROBLOCKD *xd);
    259 
    260 int av1_get_pred_context_comp_bwdref_p(const MACROBLOCKD *xd);
    261 
    262 int av1_get_pred_context_comp_bwdref_p1(const MACROBLOCKD *xd);
    263 
    264 static inline aom_cdf_prob *av1_get_pred_cdf_comp_ref_p(const MACROBLOCKD *xd) {
    265  const int pred_context = av1_get_pred_context_comp_ref_p(xd);
    266  return xd->tile_ctx->comp_ref_cdf[pred_context][0];
    267 }
    268 
    269 static inline aom_cdf_prob *av1_get_pred_cdf_comp_ref_p1(
    270    const MACROBLOCKD *xd) {
    271  const int pred_context = av1_get_pred_context_comp_ref_p1(xd);
    272  return xd->tile_ctx->comp_ref_cdf[pred_context][1];
    273 }
    274 
    275 static inline aom_cdf_prob *av1_get_pred_cdf_comp_ref_p2(
    276    const MACROBLOCKD *xd) {
    277  const int pred_context = av1_get_pred_context_comp_ref_p2(xd);
    278  return xd->tile_ctx->comp_ref_cdf[pred_context][2];
    279 }
    280 
    281 static inline aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p(
    282    const MACROBLOCKD *xd) {
    283  const int pred_context = av1_get_pred_context_comp_bwdref_p(xd);
    284  return xd->tile_ctx->comp_bwdref_cdf[pred_context][0];
    285 }
    286 
    287 static inline aom_cdf_prob *av1_get_pred_cdf_comp_bwdref_p1(
    288    const MACROBLOCKD *xd) {
    289  const int pred_context = av1_get_pred_context_comp_bwdref_p1(xd);
    290  return xd->tile_ctx->comp_bwdref_cdf[pred_context][1];
    291 }
    292 
    293 // == Single contexts ==
    294 
    295 int av1_get_pred_context_single_ref_p1(const MACROBLOCKD *xd);
    296 
    297 int av1_get_pred_context_single_ref_p2(const MACROBLOCKD *xd);
    298 
    299 int av1_get_pred_context_single_ref_p3(const MACROBLOCKD *xd);
    300 
    301 int av1_get_pred_context_single_ref_p4(const MACROBLOCKD *xd);
    302 
    303 int av1_get_pred_context_single_ref_p5(const MACROBLOCKD *xd);
    304 
    305 int av1_get_pred_context_single_ref_p6(const MACROBLOCKD *xd);
    306 
    307 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p1(
    308    const MACROBLOCKD *xd) {
    309  return xd->tile_ctx
    310      ->single_ref_cdf[av1_get_pred_context_single_ref_p1(xd)][0];
    311 }
    312 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p2(
    313    const MACROBLOCKD *xd) {
    314  return xd->tile_ctx
    315      ->single_ref_cdf[av1_get_pred_context_single_ref_p2(xd)][1];
    316 }
    317 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p3(
    318    const MACROBLOCKD *xd) {
    319  return xd->tile_ctx
    320      ->single_ref_cdf[av1_get_pred_context_single_ref_p3(xd)][2];
    321 }
    322 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p4(
    323    const MACROBLOCKD *xd) {
    324  return xd->tile_ctx
    325      ->single_ref_cdf[av1_get_pred_context_single_ref_p4(xd)][3];
    326 }
    327 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p5(
    328    const MACROBLOCKD *xd) {
    329  return xd->tile_ctx
    330      ->single_ref_cdf[av1_get_pred_context_single_ref_p5(xd)][4];
    331 }
    332 static inline aom_cdf_prob *av1_get_pred_cdf_single_ref_p6(
    333    const MACROBLOCKD *xd) {
    334  return xd->tile_ctx
    335      ->single_ref_cdf[av1_get_pred_context_single_ref_p6(xd)][5];
    336 }
    337 
    338 // Returns a context number for the given MB prediction signal
    339 // The mode info data structure has a one element border above and to the
    340 // left of the entries corresponding to real blocks.
    341 // The prediction flags in these dummy entries are initialized to 0.
    342 static inline int get_tx_size_context(const MACROBLOCKD *xd) {
    343  const MB_MODE_INFO *mbmi = xd->mi[0];
    344  const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
    345  const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
    346  const TX_SIZE max_tx_size = max_txsize_rect_lookup[mbmi->bsize];
    347  const int max_tx_wide = tx_size_wide[max_tx_size];
    348  const int max_tx_high = tx_size_high[max_tx_size];
    349  const int has_above = xd->up_available;
    350  const int has_left = xd->left_available;
    351 
    352  int above = xd->above_txfm_context[0] >= max_tx_wide;
    353  int left = xd->left_txfm_context[0] >= max_tx_high;
    354 
    355  if (has_above)
    356    if (is_inter_block(above_mbmi))
    357      above = block_size_wide[above_mbmi->bsize] >= max_tx_wide;
    358 
    359  if (has_left)
    360    if (is_inter_block(left_mbmi))
    361      left = block_size_high[left_mbmi->bsize] >= max_tx_high;
    362 
    363  if (has_above && has_left)
    364    return (above + left);
    365  else if (has_above)
    366    return above;
    367  else if (has_left)
    368    return left;
    369  else
    370    return 0;
    371 }
    372 
    373 #ifdef __cplusplus
    374 }  // extern "C"
    375 #endif
    376 
    377 #endif  // AOM_AV1_COMMON_PRED_COMMON_H_