decodemv.c 76.8 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11 12 13
 */

#include <assert.h>

14 15 16 17 18 19 20
#include "av1/common/common.h"
#include "av1/common/entropy.h"
#include "av1/common/entropymode.h"
#include "av1/common/entropymv.h"
#include "av1/common/mvref_common.h"
#include "av1/common/pred_common.h"
#include "av1/common/reconinter.h"
hui su's avatar
hui su committed
21 22 23
#if CONFIG_EXT_INTRA
#include "av1/common/reconintra.h"
#endif  // CONFIG_EXT_INTRA
24
#include "av1/common/seg_common.h"
Yue Chen's avatar
Yue Chen committed
25 26 27
#if CONFIG_WARPED_MOTION
#include "av1/common/warped_motion.h"
#endif  // CONFIG_WARPED_MOTION
28 29

#include "av1/decoder/decodeframe.h"
Jingning Han's avatar
Jingning Han committed
30
#include "av1/decoder/decodemv.h"
31

Yaowu Xu's avatar
Yaowu Xu committed
32
#include "aom_dsp/aom_dsp_common.h"
33

Michael Bebenita's avatar
Michael Bebenita committed
34
#define ACCT_STR __func__
35
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
36
static INLINE int read_uniform(aom_reader *r, int n) {
hui su's avatar
hui su committed
37 38
  int l = get_unsigned_bits(n);
  int m = (1 << l) - n;
Michael Bebenita's avatar
Michael Bebenita committed
39
  int v = aom_read_literal(r, l - 1, ACCT_STR);
hui su's avatar
hui su committed
40 41 42 43 44 45

  assert(l != 0);

  if (v < m)
    return v;
  else
Michael Bebenita's avatar
Michael Bebenita committed
46
    return (v << 1) - m + aom_read_literal(r, 1, ACCT_STR);
hui su's avatar
hui su committed
47
}
48
#endif  // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
hui su's avatar
hui su committed
49

50
#if CONFIG_EC_MULTISYMBOL
51
static PREDICTION_MODE read_intra_mode(aom_reader *r, aom_cdf_prob *cdf) {
52 53 54
  return (PREDICTION_MODE)
      av1_intra_mode_inv[aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR)];
}
55
#else
Yaowu Xu's avatar
Yaowu Xu committed
56
static PREDICTION_MODE read_intra_mode(aom_reader *r, const aom_prob *p) {
Michael Bebenita's avatar
Michael Bebenita committed
57
  return (PREDICTION_MODE)aom_read_tree(r, av1_intra_mode_tree, p, ACCT_STR);
Jingning Han's avatar
Jingning Han committed
58
}
59
#endif
Jingning Han's avatar
Jingning Han committed
60

61 62 63 64 65 66 67 68 69
#if CONFIG_DELTA_Q
static int read_delta_qindex(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
                             MB_MODE_INFO *const mbmi, int mi_col, int mi_row) {
  FRAME_COUNTS *counts = xd->counts;
  int sign, abs, reduced_delta_qindex = 0;
  BLOCK_SIZE bsize = mbmi->sb_type;
  const int b_col = mi_col & MAX_MIB_MASK;
  const int b_row = mi_row & MAX_MIB_MASK;
  const int read_delta_q_flag = (b_col == 0 && b_row == 0);
Thomas Davies's avatar
Thomas Davies committed
70 71 72 73 74 75 76 77
  int rem_bits, thr;
  int i, smallval;
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif
78

79
  if ((bsize != BLOCK_LARGEST || mbmi->skip == 0) && read_delta_q_flag) {
Thomas Davies's avatar
Thomas Davies committed
80 81
#if !CONFIG_EC_MULTISYMBOL
    int bit = 1;
82 83
    abs = 0;
    while (abs < DELTA_Q_SMALL && bit) {
Thomas Davies's avatar
Thomas Davies committed
84
      bit = aom_read(r, ec_ctx->delta_q_prob[abs], ACCT_STR);
85 86
      abs += bit;
    }
Thomas Davies's avatar
Thomas Davies committed
87 88 89 90 91 92 93 94 95 96
#else
    abs = aom_read_symbol(r, ec_ctx->delta_q_cdf, DELTA_Q_PROBS + 1, ACCT_STR);
#endif
    smallval = (abs < DELTA_Q_SMALL);
    if (counts) {
      for (i = 0; i < abs; ++i) counts->delta_q[i][1]++;
      if (smallval) counts->delta_q[abs][0]++;
    }

    if (!smallval) {
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
      rem_bits = aom_read_literal(r, 3, ACCT_STR);
      thr = (1 << rem_bits) + 1;
      abs = aom_read_literal(r, rem_bits, ACCT_STR) + thr;
    }

    if (abs) {
      sign = aom_read_bit(r, ACCT_STR);
    } else {
      sign = 1;
    }

    reduced_delta_qindex = sign ? -abs : abs;
  }
  return reduced_delta_qindex;
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
114 115
static PREDICTION_MODE read_intra_mode_y(AV1_COMMON *cm, MACROBLOCKD *xd,
                                         aom_reader *r, int size_group) {
116 117 118 119 120 121
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
#elif CONFIG_EC_MULTISYMBOL
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif

Jingning Han's avatar
Jingning Han committed
122
  const PREDICTION_MODE y_mode =
123
#if CONFIG_EC_MULTISYMBOL
124
      read_intra_mode(r, ec_ctx->y_mode_cdf[size_group]);
125
#else
Jingning Han's avatar
Jingning Han committed
126
      read_intra_mode(r, cm->fc->y_mode_prob[size_group]);
127
#endif
Jingning Han's avatar
Jingning Han committed
128
  FRAME_COUNTS *counts = xd->counts;
129 130 131
#if CONFIG_EC_ADAPT
  (void)cm;
#endif
132
  if (counts) ++counts->y_mode[size_group][y_mode];
Jingning Han's avatar
Jingning Han committed
133 134 135
  return y_mode;
}

Yaowu Xu's avatar
Yaowu Xu committed
136 137
static PREDICTION_MODE read_intra_mode_uv(AV1_COMMON *cm, MACROBLOCKD *xd,
                                          aom_reader *r,
Jingning Han's avatar
Jingning Han committed
138
                                          PREDICTION_MODE y_mode) {
139 140 141 142 143 144
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
#elif CONFIG_EC_MULTISYMBOL
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif

145
  const PREDICTION_MODE uv_mode =
146
#if CONFIG_EC_MULTISYMBOL
147
      read_intra_mode(r, ec_ctx->uv_mode_cdf[y_mode]);
148
#else
149
      read_intra_mode(r, cm->fc->uv_mode_prob[y_mode]);
150
#endif
Jingning Han's avatar
Jingning Han committed
151
  FRAME_COUNTS *counts = xd->counts;
152 153 154
#if CONFIG_EC_ADAPT
  (void)cm;
#endif
155
  if (counts) ++counts->uv_mode[y_mode][uv_mode];
Jingning Han's avatar
Jingning Han committed
156 157 158
  return uv_mode;
}

159
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
160 161 162
static INTERINTRA_MODE read_interintra_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                            aom_reader *r, int size_group) {
  const INTERINTRA_MODE ii_mode = (INTERINTRA_MODE)aom_read_tree(
Michael Bebenita's avatar
Michael Bebenita committed
163 164
      r, av1_interintra_mode_tree, cm->fc->interintra_mode_prob[size_group],
      ACCT_STR);
165
  FRAME_COUNTS *counts = xd->counts;
166
  if (counts) ++counts->interintra_mode[size_group][ii_mode];
167 168 169 170
  return ii_mode;
}
#endif  // CONFIG_EXT_INTER

171
static PREDICTION_MODE read_inter_mode(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
172
                                       aom_reader *r, int16_t ctx) {
173 174
#if CONFIG_REF_MV
  FRAME_COUNTS *counts = xd->counts;
175
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
176
  aom_prob mode_prob = ec_ctx->newmv_prob[mode_ctx];
177

Michael Bebenita's avatar
Michael Bebenita committed
178
  if (aom_read(r, mode_prob, ACCT_STR) == 0) {
179
    if (counts) ++counts->newmv_mode[mode_ctx][0];
180
    return NEWMV;
181
  }
182
  if (counts) ++counts->newmv_mode[mode_ctx][1];
183

184
  if (ctx & (1 << ALL_ZERO_FLAG_OFFSET)) return ZEROMV;
185

186
  mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
187

188
  mode_prob = ec_ctx->zeromv_prob[mode_ctx];
Michael Bebenita's avatar
Michael Bebenita committed
189
  if (aom_read(r, mode_prob, ACCT_STR) == 0) {
190
    if (counts) ++counts->zeromv_mode[mode_ctx][0];
191 192
    return ZEROMV;
  }
193
  if (counts) ++counts->zeromv_mode[mode_ctx][1];
194

195
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
196

197 198 199
  if (ctx & (1 << SKIP_NEARESTMV_OFFSET)) mode_ctx = 6;
  if (ctx & (1 << SKIP_NEARMV_OFFSET)) mode_ctx = 7;
  if (ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) mode_ctx = 8;
200

201
  mode_prob = ec_ctx->refmv_prob[mode_ctx];
202

Michael Bebenita's avatar
Michael Bebenita committed
203
  if (aom_read(r, mode_prob, ACCT_STR) == 0) {
204
    if (counts) ++counts->refmv_mode[mode_ctx][0];
205

206 207
    return NEARESTMV;
  } else {
208
    if (counts) ++counts->refmv_mode[mode_ctx][1];
209 210 211 212 213
    return NEARMV;
  }

  // Invalid prediction mode.
  assert(0);
214
#else
215
#if CONFIG_EC_MULTISYMBOL
216
  const int mode = av1_inter_mode_inv[aom_read_symbol(
217
      r, ec_ctx->inter_mode_cdf[ctx], INTER_MODES, ACCT_STR)];
218
#else
Michael Bebenita's avatar
Michael Bebenita committed
219
  const int mode = aom_read_tree(r, av1_inter_mode_tree,
220
                                 ec_ctx->inter_mode_probs[ctx], ACCT_STR);
221
#endif
Jingning Han's avatar
Jingning Han committed
222
  FRAME_COUNTS *counts = xd->counts;
223
  if (counts) ++counts->inter_mode[ctx][mode];
Jingning Han's avatar
Jingning Han committed
224 225

  return NEARESTMV + mode;
226
#endif
Jingning Han's avatar
Jingning Han committed
227 228
}

229
#if CONFIG_REF_MV
Yaowu Xu's avatar
Yaowu Xu committed
230 231 232
static void read_drl_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
                         MB_MODE_INFO *mbmi, aom_reader *r) {
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
233 234
  mbmi->ref_mv_idx = 0;

235 236 237
#if CONFIG_EXT_INTER
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
#else
238
  if (mbmi->mode == NEWMV) {
239
#endif
240 241 242
    int idx;
    for (idx = 0; idx < 2; ++idx) {
      if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
Yaowu Xu's avatar
Yaowu Xu committed
243 244
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
Michael Bebenita's avatar
Michael Bebenita committed
245
        if (!aom_read(r, drl_prob, ACCT_STR)) {
246
          mbmi->ref_mv_idx = idx;
247
          if (xd->counts) ++xd->counts->drl_mode[drl_ctx][0];
248 249 250
          return;
        }
        mbmi->ref_mv_idx = idx + 1;
251
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][1];
252 253 254 255
      }
    }
  }

256 257 258
#if CONFIG_EXT_INTER
  if (mbmi->mode == NEARMV || mbmi->mode == NEAR_NEARMV) {
#else
259
  if (mbmi->mode == NEARMV) {
260
#endif
261 262 263 264 265 266
    int idx;
    // Offset the NEARESTMV mode.
    // TODO(jingning): Unify the two syntax decoding loops after the NEARESTMV
    // mode is factored in.
    for (idx = 1; idx < 3; ++idx) {
      if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
Yaowu Xu's avatar
Yaowu Xu committed
267 268
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
Michael Bebenita's avatar
Michael Bebenita committed
269
        if (!aom_read(r, drl_prob, ACCT_STR)) {
270
          mbmi->ref_mv_idx = idx - 1;
271
          if (xd->counts) ++xd->counts->drl_mode[drl_ctx][0];
272 273
          return;
        }
274
        mbmi->ref_mv_idx = idx;
275
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][1];
276 277 278 279 280 281
      }
    }
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
282 283
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
284 285 286 287 288 289 290
                                    MODE_INFO *mi, aom_reader *r) {
  MB_MODE_INFO *mbmi = &mi->mbmi;
  const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
      0, xd->global_motion,
#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
      mi);
Yue Chen's avatar
Yue Chen committed
291 292
  int motion_mode;
  FRAME_COUNTS *counts = xd->counts;
Yaowu Xu's avatar
Yaowu Xu committed
293

Yue Chen's avatar
Yue Chen committed
294 295 296 297 298 299 300 301
  if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return SIMPLE_TRANSLATION;
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
  if (last_motion_mode_allowed == OBMC_CAUSAL) {
    motion_mode = aom_read(r, cm->fc->obmc_prob[mbmi->sb_type], ACCT_STR);
    if (counts) ++counts->obmc[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else {
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
302 303 304 305 306
    motion_mode =
        aom_read_tree(r, av1_motion_mode_tree,
                      cm->fc->motion_mode_prob[mbmi->sb_type], ACCT_STR);
    if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
Yue Chen's avatar
Yue Chen committed
307
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
308
  }
Yue Chen's avatar
Yue Chen committed
309
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
310 311 312
}
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION

313
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
314 315
static PREDICTION_MODE read_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                                aom_reader *r, int16_t ctx) {
Michael Bebenita's avatar
Michael Bebenita committed
316 317 318
  const int mode =
      aom_read_tree(r, av1_inter_compound_mode_tree,
                    cm->fc->inter_compound_mode_probs[ctx], ACCT_STR);
319 320
  FRAME_COUNTS *counts = xd->counts;

321
  if (counts) ++counts->inter_compound_mode[ctx][mode];
322 323 324 325 326 327

  assert(is_inter_compound_mode(NEAREST_NEARESTMV + mode));
  return NEAREST_NEARESTMV + mode;
}
#endif  // CONFIG_EXT_INTER

328
static int read_segment_id(aom_reader *r, struct segmentation_probs *segp) {
329
#if CONFIG_EC_MULTISYMBOL
Michael Bebenita's avatar
Michael Bebenita committed
330
  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
331
#else
Michael Bebenita's avatar
Michael Bebenita committed
332
  return aom_read_tree(r, av1_segment_tree, segp->tree_probs, ACCT_STR);
333
#endif
Jingning Han's avatar
Jingning Han committed
334 335
}

336
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
337
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
338
                               MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
339 340
                               TX_SIZE tx_size, int depth, int blk_row,
                               int blk_col, aom_reader *r) {
341
  int is_split = 0;
342 343
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
344 345
  const int max_blocks_high = max_block_high(xd, mbmi->sb_type, 0);
  const int max_blocks_wide = max_block_wide(xd, mbmi->sb_type, 0);
346
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
347 348
                                   xd->left_txfm_context + tx_row,
                                   mbmi->sb_type, tx_size);
clang-format's avatar
clang-format committed
349
  TX_SIZE(*const inter_tx_size)
350 351 352
  [MAX_MIB_SIZE] =
      (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
353

Jingning Han's avatar
Jingning Han committed
354
  if (depth == MAX_VARTX_DEPTH) {
355 356
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
357 358
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
359 360
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
361
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
362 363
    if (counts) ++counts->txfm_partition[ctx][0];
    txfm_partition_update(xd->above_txfm_context + tx_col,
364
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
365 366 367
    return;
  }

Michael Bebenita's avatar
Michael Bebenita committed
368
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
369 370

  if (is_split) {
371 372
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
373
    int i;
374

375
    if (counts) ++counts->txfm_partition[ctx][1];
376

377
    if (tx_size == TX_8X8) {
378
      int idx, idy;
379
      inter_tx_size[0][0] = sub_txs;
380 381
      for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
        for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
382
          inter_tx_size[idy][idx] = inter_tx_size[0][0];
383
      mbmi->tx_size = sub_txs;
384
      mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
385
      txfm_partition_update(xd->above_txfm_context + tx_col,
386
                            xd->left_txfm_context + tx_row, sub_txs, tx_size);
387 388 389 390 391
      return;
    }

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
392 393 394
      int offsetr = blk_row + (i >> 1) * bsl;
      int offsetc = blk_col + (i & 0x01) * bsl;
      read_tx_size_vartx(cm, xd, mbmi, counts, sub_txs, depth + 1, offsetr,
395
                         offsetc, r);
396 397
    }
  } else {
398
    int idx, idy;
399
    inter_tx_size[0][0] = tx_size;
400 401
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
402 403
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
404
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
405
    if (counts) ++counts->txfm_partition[ctx][0];
406
    txfm_partition_update(xd->above_txfm_context + tx_col,
407
                          xd->left_txfm_context + tx_row, tx_size, tx_size);
408 409 410 411
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
412 413
static TX_SIZE read_selected_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd,
                                     int tx_size_cat, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
414 415
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
416 417 418 419 420 421 422
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif

423
  const int depth =
424
#if CONFIG_EC_MULTISYMBOL
425
      aom_read_symbol(r, ec_ctx->tx_size_cdf[tx_size_cat][ctx], tx_size_cat + 2,
426 427
                      ACCT_STR);
#else
428
      aom_read_tree(r, av1_tx_size_tree[tx_size_cat],
429
                    ec_ctx->tx_size_probs[tx_size_cat][ctx], ACCT_STR);
430
#endif
431 432 433 434
  const TX_SIZE tx_size = depth_to_tx_size(depth);
#if CONFIG_RECT_TX
  assert(!is_rect_tx(tx_size));
#endif  // CONFIG_RECT_TX
435
  if (counts) ++counts->tx_size[tx_size_cat][ctx][depth];
436
  return tx_size;
Jingning Han's avatar
Jingning Han committed
437 438
}

439 440 441 442
static TX_SIZE read_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd, int is_inter,
                            int allow_select_inter, aom_reader *r) {
  const TX_MODE tx_mode = cm->tx_mode;
  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
443
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
444
#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX
445
  if (bsize > BLOCK_4X4) {
446
#else
447
  if (bsize >= BLOCK_8X8) {
448 449 450 451
#endif  // CONFIG_CB4X4 && CONFIG_VAR_TX
    if ((!is_inter || allow_select_inter) && tx_mode == TX_MODE_SELECT) {
      const int32_t tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
                                           : intra_tx_size_cat_lookup[bsize];
452
      const TX_SIZE coded_tx_size =
453
          read_selected_tx_size(cm, xd, tx_size_cat, r);
454
#if CONFIG_EXT_TX && CONFIG_RECT_TX
455 456 457 458
      if (coded_tx_size > max_txsize_lookup[bsize]) {
        assert(coded_tx_size == max_txsize_lookup[bsize] + 1);
        return max_txsize_rect_lookup[bsize];
      }
459 460 461
#else
      assert(coded_tx_size <= max_txsize_lookup[bsize]);
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX
462
      return coded_tx_size;
463
    } else {
464
      return tx_size_from_tx_mode(bsize, tx_mode, is_inter);
465 466
    }
  } else {
467
#if CONFIG_EXT_TX && CONFIG_RECT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
468
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
469 470 471
    return max_txsize_rect_lookup[bsize];
#else
    return TX_4X4;
472
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX
473
  }
Jingning Han's avatar
Jingning Han committed
474 475
}

Yaowu Xu's avatar
Yaowu Xu committed
476
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
477 478 479 480 481
                              int mi_offset, int x_mis, int y_mis) {
  int x, y, segment_id = INT_MAX;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
482
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
483
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
484 485 486 487 488

  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
489
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
490
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
491 492 493 494 495 496 497 498 499
  int x, y;

  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
      cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
500
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
501
                                 int mi_offset, int x_mis, int y_mis,
Yaowu Xu's avatar
Yaowu Xu committed
502
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
503
  struct segmentation *const seg = &cm->seg;
504 505
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
506 507
  int segment_id;

508
  if (!seg->enabled) return 0;  // Default for disabled segmentation
Jingning Han's avatar
Jingning Han committed
509

510
  assert(seg->update_map && !seg->temporal_update);
Jingning Han's avatar
Jingning Han committed
511

512
  segment_id = read_segment_id(r, segp);
513
  if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
514 515 516 517
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
518
static void copy_segment_id(const AV1_COMMON *cm,
519 520 521
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
522 523 524 525
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
526 527 528
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
529 530
}

Yaowu Xu's avatar
Yaowu Xu committed
531 532
static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                 int mi_row, int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
533
  struct segmentation *const seg = &cm->seg;
534 535
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
536 537 538
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  int predicted_segment_id, segment_id;
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
539 540
  const int bw = mi_size_wide[mbmi->sb_type];
  const int bh = mi_size_high[mbmi->sb_type];
Jingning Han's avatar
Jingning Han committed
541 542

  // TODO(slavarnway): move x_mis, y_mis into xd ?????
Yaowu Xu's avatar
Yaowu Xu committed
543 544
  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
545

546
  if (!seg->enabled) return 0;  // Default for disabled segmentation
Jingning Han's avatar
Jingning Han committed
547

548 549 550 551
  predicted_segment_id = cm->last_frame_seg_map
                             ? dec_get_segment_id(cm, cm->last_frame_seg_map,
                                                  mi_offset, x_mis, y_mis)
                             : 0;
Jingning Han's avatar
Jingning Han committed
552 553 554 555 556 557 558 559

  if (!seg->update_map) {
    copy_segment_id(cm, cm->last_frame_seg_map, cm->current_frame_seg_map,
                    mi_offset, x_mis, y_mis);
    return predicted_segment_id;
  }

  if (seg->temporal_update) {
Yaowu Xu's avatar
Yaowu Xu committed
560 561
    const int ctx = av1_get_pred_context_seg_id(xd);
    const aom_prob pred_prob = segp->pred_probs[ctx];
Michael Bebenita's avatar
Michael Bebenita committed
562
    mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
563
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
564 565 566 567
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
568
      if (counts) ++counts->seg.tree_mispred[segment_id];
569
    }
Jingning Han's avatar
Jingning Han committed
570
  } else {
571
    segment_id = read_segment_id(r, segp);
572
    if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
573 574 575 576 577
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
578 579
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
580 581 582
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
583
    const int ctx = av1_get_skip_context(xd);
Michael Bebenita's avatar
Michael Bebenita committed
584
    const int skip = aom_read(r, cm->fc->skip_probs[ctx], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
585
    FRAME_COUNTS *counts = xd->counts;
586
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
587 588 589 590
    return skip;
  }
}

591
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
592 593
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                   aom_reader *r) {
hui su's avatar
hui su committed
594 595
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
596
  const MODE_INFO *const above_mi = xd->above_mi;
597
  const MODE_INFO *const left_mi = xd->left_mi;
hui su's avatar
hui su committed
598
  const BLOCK_SIZE bsize = mbmi->sb_type;
599
  int i, n;
600 601 602
  PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;

  if (mbmi->mode == DC_PRED) {
603
    int palette_y_mode_ctx = 0;
604
    if (above_mi)
605 606
      palette_y_mode_ctx +=
          (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
607
    if (left_mi)
608 609 610 611 612
      palette_y_mode_ctx +=
          (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    if (aom_read(r, av1_default_palette_y_mode_prob[bsize - BLOCK_8X8]
                                                   [palette_y_mode_ctx],
                 ACCT_STR)) {
613
      pmi->palette_size[0] =
Yaowu Xu's avatar
Yaowu Xu committed
614
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
615 616
                        av1_default_palette_y_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
617
          2;
618 619
      n = pmi->palette_size[0];
      for (i = 0; i < n; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
620
        pmi->palette_colors[i] = aom_read_literal(r, cm->bit_depth, ACCT_STR);
hui su's avatar
hui su committed
621

622 623 624 625
      xd->plane[0].color_index_map[0] = read_uniform(r, n);
      assert(xd->plane[0].color_index_map[0] < n);
    }
  }
hui su's avatar
hui su committed
626

627
  if (mbmi->uv_mode == DC_PRED) {
628 629
    const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0);
    if (aom_read(r, av1_default_palette_uv_mode_prob[palette_uv_mode_ctx],
Michael Bebenita's avatar
Michael Bebenita committed
630
                 ACCT_STR)) {
631
      pmi->palette_size[1] =
Yaowu Xu's avatar
Yaowu Xu committed
632
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
633 634
                        av1_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
635
          2;
636 637 638
      n = pmi->palette_size[1];
      for (i = 0; i < n; ++i) {
        pmi->palette_colors[PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
639
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
640
        pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
641
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
642 643 644 645
      }
      xd->plane[1].color_index_map[0] = read_uniform(r, n);
      assert(xd->plane[1].color_index_map[0] < n);
    }
hui su's avatar
hui su committed
646 647
  }
}
648
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
649

650 651 652
#if CONFIG_FILTER_INTRA
static void read_filter_intra_mode_info(AV1_COMMON *const cm,
                                        MACROBLOCKD *const xd, aom_reader *r) {
hui su's avatar
hui su committed
653 654 655
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
656 657
  FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
      &mbmi->filter_intra_mode_info;
hui su's avatar
hui su committed
658

659 660 661 662 663
  if (mbmi->mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[0] == 0
#endif  // CONFIG_PALETTE
      ) {
664 665 666 667
    filter_intra_mode_info->use_filter_intra_mode[0] =
        aom_read(r, cm->fc->filter_intra_probs[0], ACCT_STR);
    if (filter_intra_mode_info->use_filter_intra_mode[0]) {
      filter_intra_mode_info->filter_intra_mode[0] =
hui su's avatar
hui su committed
668
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
669
    }
670
    if (counts) {
clang-format's avatar
clang-format committed
671 672
      ++counts
            ->filter_intra[0][filter_intra_mode_info->use_filter_intra_mode[0]];
673
    }
hui su's avatar
hui su committed
674
  }
675 676 677 678 679
  if (mbmi->uv_mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[1] == 0
#endif  // CONFIG_PALETTE
      ) {
680 681 682 683
    filter_intra_mode_info->use_filter_intra_mode[1] =
        aom_read(r, cm->fc->filter_intra_probs[1], ACCT_STR);
    if (filter_intra_mode_info->use_filter_intra_mode[1]) {
      filter_intra_mode_info->filter_intra_mode[1] =
hui su's avatar
hui su committed
684
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
685
    }
686
    if (counts) {
clang-format's avatar
clang-format committed
687 688
      ++counts
            ->filter_intra[1][filter_intra_mode_info->use_filter_intra_mode[1]];
689
    }
hui su's avatar
hui su committed
690 691
  }
}
692
#endif  // CONFIG_FILTER_INTRA
693

694
#if CONFIG_EXT_INTRA
Yaowu Xu's avatar
Yaowu Xu committed
695 696
static void read_intra_angle_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  aom_reader *r) {
697 698
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
hui su's avatar
hui su committed
699
#if CONFIG_INTRA_INTERP
700 701 702 703 704
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
#else
  FRAME_CONTEXT *const ec_ctx = cm->fc;
#endif  // CONFIG_EC_ADAPT
Yaowu Xu's avatar
Yaowu Xu committed
705
  const int ctx = av1_get_pred_context_intra_interp(xd);
706
  int p_angle;
hui su's avatar
hui su committed
707
#endif  // CONFIG_INTRA_INTERP
708

hui su's avatar
hui su committed
709
  (void)cm;
710
  if (bsize < BLOCK_8X8) return;
711

hui su's avatar
hui su committed
712 713
  if (av1_is_directional_mode(mbmi->mode, bsize)) {
    const int max_angle_delta = av1_get_max_angle_delta(mbmi->sb_type, 0);
714
    mbmi->angle_delta[0] =
hui su's avatar
hui su committed
715
        read_uniform(r, 2 * max_angle_delta + 1) - max_angle_delta;
hui su's avatar
hui su committed
716
#if CONFIG_INTRA_INTERP
hui su's avatar
hui su committed
717 718
    p_angle = mode_to_angle_map[mbmi->mode] +
              mbmi->angle_delta[0] * av1_get_angle_step(mbmi->sb_type, 0);
Yaowu Xu's avatar
Yaowu Xu committed
719
    if (av1_is_intra_filter_switchable(p_angle)) {
720
      FRAME_COUNTS *counts = xd->counts;
721 722 723 724
#if CONFIG_EC_MULTISYMBOL
      mbmi->intra_filter = aom_read_symbol(r, ec_ctx->intra_filter_cdf[ctx],
                                           INTRA_FILTERS, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
725
      mbmi->intra_filter = aom_read_tree(
726 727
          r, av1_intra_filter_tree, ec_ctx->intra_filter_probs[ctx], ACCT_STR);
#endif  // CONFIG_EC_MULTISYMBOL
728
      if (counts) ++counts->intra_filter[ctx][mbmi->intra_filter];
729 730 731
    } else {
      mbmi->intra_filter = INTRA_FILTER_LINEAR;
    }
hui su's avatar
hui su committed
732
#endif  // CONFIG_INTRA_INTERP
733 734
  }

hui su's avatar
hui su committed
735
  if (av1_is_directional_mode(mbmi->uv_mode, bsize)) {
736
    mbmi->angle_delta[1] =
hui su's avatar
hui su committed
737
        read_uniform(r, 2 * MAX_ANGLE_DELTA_UV + 1) - MAX_ANGLE_DELTA_UV;
738 739
  }
}
hui su's avatar
hui su committed
740 741
#endif  // CONFIG_EXT_INTRA

742
void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
743
#if CONFIG_SUPERTX
744
                      int supertx_enabled,
Jingning Han's avatar
Jingning Han committed
745
#endif
746
#if CONFIG_LV_MAP
747
                      int block, int plane,
748 749 750
#endif
                      aom_reader *r) {
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han's avatar
Jingning Han committed
751
  const int inter_block = is_inter_block(mbmi);
752 753 754
#if CONFIG_VAR_TX
  const TX_SIZE tx_size = inter_block ? mbmi->min_tx_size : mbmi->tx_size;
#else
Jingning Han's avatar
Jingning Han committed
755
  const TX_SIZE tx_size = mbmi->tx_size;
756
#endif
757 758 759 760 761 762
#if CONFIG_EC_ADAPT
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
#else
  FRAME_CONTEXT *ec_ctx = cm->fc;
#endif

763 764 765
#if !CONFIG_LV_MAP
  TX_TYPE *tx_type = &mbmi->tx_type;
#else
766 767
  // only y plane's tx_type is transmitted
  if (plane > 0) return;
768 769 770
  TX_TYPE *tx_type = &mbmi->txk_type[block];
#endif

Jingning Han's avatar
Jingning Han committed
771 772
  if (!FIXED_TX_TYPE) {
#if CONFIG_EXT_TX
773
    const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
774 775
    if (get_ext_tx_types(tx_size, mbmi->sb_type, inter_block,
                         cm->reduced_tx_set_used) > 1 &&
776 777 778
        ((!cm->seg.enabled && cm->base_qindex > 0) ||
         (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
        !mbmi->skip &&
Jingning Han's avatar
Jingning Han committed
779 780 781 782
#if CONFIG_SUPERTX
        !supertx_enabled &&
#endif  // CONFIG_SUPERTX
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
783 784
      const int eset = get_ext_tx_set(tx_size, mbmi->sb_type, inter_block,
                                      cm->reduced_tx_set_used);
Jingning Han's avatar
Jingning Han committed
785 786 787 788
      FRAME_COUNTS *counts = xd->counts;

      if (inter_block) {
        if (eset > 0) {
789
#if CONFIG_EC_MULTISYMBOL
790
          *tx_type = av1_ext_tx_inter_inv[eset][aom_read_symbol(
791 792 793
              r, ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
              ext_tx_cnt_inter[eset], ACCT_STR)];
#else
794
          *tx_type = aom_read_tree(
Jingning Han's avatar
Jingning Han committed
795
              r, av1_ext_tx_inter_tree[eset],
796
              ec_ctx->inter_ext_tx_prob[eset][square_tx_size], ACCT_STR);
797
#endif
798
          if (counts) ++counts->inter_ext_tx[eset][square_tx_size][*tx_type];
Jingning Han's avatar
Jingning Han committed
799 800 801
        }
      } else if (ALLOW_INTRA_EXT_TX) {
        if (eset > 0) {
802
#if CONFIG_EC_MULTISYMBOL
803
          *tx_type = av1_ext_tx_intra_inv[eset][aom_read_symbol(
804 805 806
              r, ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][mbmi->mode],
              ext_tx_cnt_intra[eset], ACCT_STR)];
#else
807
          *tx_type = aom_read_tree(