decodemv.c 82.1 KB
Newer Older
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3
 *
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.
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
#include "av1/common/reconintra.h"
22
#include "av1/common/seg_common.h"
Yue Chen's avatar
Yue Chen committed
23
#include "av1/common/warped_motion.h"
24 25

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

28
#include "aom_dsp/aom_dsp_common.h"
29

Luc Trudeau's avatar
Luc Trudeau committed
30 31 32 33
#if CONFIG_CFL
#include "av1/common/cfl.h"
#endif

Michael Bebenita's avatar
Michael Bebenita committed
34
#define ACCT_STR __func__
35

36
#define DEC_MISMATCH_DEBUG 0
37

38
static PREDICTION_MODE read_intra_mode(aom_reader *r, aom_cdf_prob *cdf) {
39
  return (PREDICTION_MODE)aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR);
40
}
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
static void read_cdef(AV1_COMMON *cm, aom_reader *r, MB_MODE_INFO *const mbmi,
                      int mi_col, int mi_row) {
  if (cm->all_lossless) return;

  const int m = ~((1 << (6 - MI_SIZE_LOG2)) - 1);
  if (!(mi_col & (cm->mib_size - 1)) &&
      !(mi_row & (cm->mib_size - 1))) {  // Top left?
#if CONFIG_EXT_PARTITION
    cm->cdef_preset[0] = cm->cdef_preset[1] = cm->cdef_preset[2] =
        cm->cdef_preset[3] = -1;
#else
    cm->cdef_preset = -1;
#endif
  }
// Read CDEF param at first a non-skip coding block
#if CONFIG_EXT_PARTITION
  const int mask = 1 << (6 - MI_SIZE_LOG2);
  const int index = cm->sb_size == BLOCK_128X128
                        ? !!(mi_col & mask) + 2 * !!(mi_row & mask)
                        : 0;
  cm->mi_grid_visible[(mi_row & m) * cm->mi_stride + (mi_col & m)]
      ->mbmi.cdef_strength = cm->cdef_preset[index] =
      cm->cdef_preset[index] == -1 && !mbmi->skip
          ? aom_read_literal(r, cm->cdef_bits, ACCT_STR)
          : cm->cdef_preset[index];
#else
  cm->mi_grid_visible[(mi_row & m) * cm->mi_stride + (mi_col & m)]
      ->mbmi.cdef_strength = cm->cdef_preset =
      cm->cdef_preset == -1 && !mbmi->skip
          ? aom_read_literal(r, cm->cdef_bits, ACCT_STR)
          : cm->cdef_preset;
#endif
}

76 77 78 79
static int read_delta_qindex(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
                             MB_MODE_INFO *const mbmi, int mi_col, int mi_row) {
  int sign, abs, reduced_delta_qindex = 0;
  BLOCK_SIZE bsize = mbmi->sb_type;
80 81
  const int b_col = mi_col & (cm->mib_size - 1);
  const int b_row = mi_row & (cm->mib_size - 1);
82
  const int read_delta_q_flag = (b_col == 0 && b_row == 0);
83 84
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
85

86
  if ((bsize != cm->sb_size || mbmi->skip == 0) && read_delta_q_flag) {
87
    abs = aom_read_symbol(r, ec_ctx->delta_q_cdf, DELTA_Q_PROBS + 1, ACCT_STR);
88
    const int smallval = (abs < DELTA_Q_SMALL);
89 90

    if (!smallval) {
91 92
      const int rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
      const int thr = (1 << rem_bits) + 1;
93 94 95 96 97 98 99 100 101 102 103 104 105
      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;
}
106 107
#if CONFIG_EXT_DELTA_Q
static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
108 109 110
#if CONFIG_LOOPFILTER_LEVEL
                              int lf_id,
#endif
111 112 113 114
                              MB_MODE_INFO *const mbmi, int mi_col,
                              int mi_row) {
  int sign, abs, reduced_delta_lflevel = 0;
  BLOCK_SIZE bsize = mbmi->sb_type;
115 116
  const int b_col = mi_col & (cm->mib_size - 1);
  const int b_row = mi_row & (cm->mib_size - 1);
117 118 119 120
  const int read_delta_lf_flag = (b_col == 0 && b_row == 0);
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;

121
  if ((bsize != cm->sb_size || mbmi->skip == 0) && read_delta_lf_flag) {
122
#if CONFIG_LOOPFILTER_LEVEL
123 124 125 126 127 128 129 130
    if (cm->delta_lf_multi) {
      assert(lf_id >= 0 && lf_id < FRAME_LF_COUNT);
      abs = aom_read_symbol(r, ec_ctx->delta_lf_multi_cdf[lf_id],
                            DELTA_LF_PROBS + 1, ACCT_STR);
    } else {
      abs = aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1,
                            ACCT_STR);
    }
131
#else
132 133
    abs =
        aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1, ACCT_STR);
134
#endif  // CONFIG_LOOPFILTER_LEVEL
135
    const int smallval = (abs < DELTA_LF_SMALL);
136
    if (!smallval) {
137 138
      const int rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
      const int thr = (1 << rem_bits) + 1;
139 140 141 142 143 144 145 146 147 148 149 150 151 152
      abs = aom_read_literal(r, rem_bits, ACCT_STR) + thr;
    }

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

    reduced_delta_lflevel = sign ? -abs : abs;
  }
  return reduced_delta_lflevel;
}
#endif
153

Luc Trudeau's avatar
Luc Trudeau committed
154
static UV_PREDICTION_MODE read_intra_mode_uv(FRAME_CONTEXT *ec_ctx,
155
                                             aom_reader *r,
156 157 158
#if CONFIG_CFL
                                             CFL_ALLOWED_TYPE cfl_allowed,
#endif
Luc Trudeau's avatar
Luc Trudeau committed
159 160
                                             PREDICTION_MODE y_mode) {
  const UV_PREDICTION_MODE uv_mode =
161
#if CONFIG_CFL
162 163
      aom_read_symbol(r, ec_ctx->uv_mode_cdf[cfl_allowed][y_mode],
                      UV_INTRA_MODES - !cfl_allowed, ACCT_STR);
164
#else
165
      read_intra_mode(r, ec_ctx->uv_mode_cdf[y_mode]);
166
#endif  // CONFIG_CFL
167 168 169
  return uv_mode;
}

Luc Trudeau's avatar
Luc Trudeau committed
170
#if CONFIG_CFL
171
static int read_cfl_alphas(FRAME_CONTEXT *const ec_ctx, aom_reader *r,
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
                           int *signs_out) {
  const int joint_sign =
      aom_read_symbol(r, ec_ctx->cfl_sign_cdf, CFL_JOINT_SIGNS, "cfl:signs");
  int idx = 0;
  // Magnitudes are only coded for nonzero values
  if (CFL_SIGN_U(joint_sign) != CFL_SIGN_ZERO) {
    aom_cdf_prob *cdf_u = ec_ctx->cfl_alpha_cdf[CFL_CONTEXT_U(joint_sign)];
    idx = aom_read_symbol(r, cdf_u, CFL_ALPHABET_SIZE, "cfl:alpha_u")
          << CFL_ALPHABET_SIZE_LOG2;
  }
  if (CFL_SIGN_V(joint_sign) != CFL_SIGN_ZERO) {
    aom_cdf_prob *cdf_v = ec_ctx->cfl_alpha_cdf[CFL_CONTEXT_V(joint_sign)];
    idx += aom_read_symbol(r, cdf_v, CFL_ALPHABET_SIZE, "cfl:alpha_v");
  }
  *signs_out = joint_sign;
  return idx;
Luc Trudeau's avatar
Luc Trudeau committed
188 189 190
}
#endif

Yue Chen's avatar
Yue Chen committed
191 192
static INTERINTRA_MODE read_interintra_mode(MACROBLOCKD *xd, aom_reader *r,
                                            int size_group) {
193 194 195
  const INTERINTRA_MODE ii_mode = (INTERINTRA_MODE)aom_read_symbol(
      r, xd->tile_ctx->interintra_mode_cdf[size_group], INTERINTRA_MODES,
      ACCT_STR);
196 197 198
  return ii_mode;
}

199 200
static PREDICTION_MODE read_inter_mode(FRAME_CONTEXT *ec_ctx, aom_reader *r,
                                       int16_t ctx) {
201
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
202 203
  int is_newmv, is_zeromv, is_refmv;
  is_newmv = aom_read_symbol(r, ec_ctx->newmv_cdf[mode_ctx], 2, ACCT_STR) == 0;
204 205
  if (is_newmv) return NEWMV;

Sarah Parker's avatar
Sarah Parker committed
206
  mode_ctx = (ctx >> GLOBALMV_OFFSET) & GLOBALMV_CTX_MASK;
207 208
  is_zeromv =
      aom_read_symbol(r, ec_ctx->zeromv_cdf[mode_ctx], 2, ACCT_STR) == 0;
209 210
  if (is_zeromv) return GLOBALMV;

211
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
212 213 214
  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;
215
  is_refmv = aom_read_symbol(r, ec_ctx->refmv_cdf[mode_ctx], 2, ACCT_STR) == 0;
216
  if (is_refmv)
217
    return NEARESTMV;
218
  else
219
    return NEARMV;
220 221
}

222
static void read_drl_idx(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
223 224
                         MB_MODE_INFO *mbmi, aom_reader *r) {
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
225
  mbmi->ref_mv_idx = 0;
226
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
227
    for (int idx = 0; idx < 2; ++idx) {
228
      if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
229
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
230 231 232
        int drl_idx = aom_read_symbol(r, ec_ctx->drl_cdf[drl_ctx], 2, ACCT_STR);
        mbmi->ref_mv_idx = idx + drl_idx;
        if (!drl_idx) return;
233 234 235
      }
    }
  }
236
  if (have_nearmv_in_inter_mode(mbmi->mode)) {
237 238 239
    // Offset the NEARESTMV mode.
    // TODO(jingning): Unify the two syntax decoding loops after the NEARESTMV
    // mode is factored in.
240
    for (int idx = 1; idx < 3; ++idx) {
241
      if (xd->ref_mv_count[ref_frame_type] > idx + 1) {
242
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
243 244 245
        int drl_idx = aom_read_symbol(r, ec_ctx->drl_cdf[drl_ctx], 2, ACCT_STR);
        mbmi->ref_mv_idx = idx + drl_idx - 1;
        if (!drl_idx) return;
246 247 248 249 250
      }
    }
  }
}

251 252
static MOTION_MODE read_motion_mode(MACROBLOCKD *xd, MODE_INFO *mi,
                                    aom_reader *r) {
253
  MB_MODE_INFO *mbmi = &mi->mbmi;
254

255 256 257 258
#if CONFIG_EXT_SKIP
  if (mbmi->skip_mode) return SIMPLE_TRANSLATION;
#endif  // CONFIG_EXT_SKIP

259
  const MOTION_MODE last_motion_mode_allowed =
260
      motion_mode_allowed(xd->global_motion, xd, mi);
Yue Chen's avatar
Yue Chen committed
261
  int motion_mode;
262

Yue Chen's avatar
Yue Chen committed
263
  if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return SIMPLE_TRANSLATION;
264

Yue Chen's avatar
Yue Chen committed
265
  if (last_motion_mode_allowed == OBMC_CAUSAL) {
266 267
    motion_mode =
        aom_read_symbol(r, xd->tile_ctx->obmc_cdf[mbmi->sb_type], 2, ACCT_STR);
Yue Chen's avatar
Yue Chen committed
268 269
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else {
270
    motion_mode =
271 272
        aom_read_symbol(r, xd->tile_ctx->motion_mode_cdf[mbmi->sb_type],
                        MOTION_MODES, ACCT_STR);
273 274 275
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  }
}
276

277 278
static PREDICTION_MODE read_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                                aom_reader *r, int16_t ctx) {
279 280 281 282
  (void)cm;
  const int mode =
      aom_read_symbol(r, xd->tile_ctx->inter_compound_mode_cdf[ctx],
                      INTER_COMPOUND_MODES, ACCT_STR);
283 284 285
  assert(is_inter_compound_mode(NEAREST_NEARESTMV + mode));
  return NEAREST_NEARESTMV + mode;
}
286

287
#if CONFIG_SPATIAL_SEGMENTATION
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
static int neg_deinterleave(int diff, int ref, int max) {
  if (!ref) return diff;
  if (ref >= (max - 1)) return max - diff - 1;
  if (2 * ref < max) {
    if (diff <= 2 * ref) {
      if (diff & 1)
        return ref + ((diff + 1) >> 1);
      else
        return ref - (diff >> 1);
    }
    return diff;
  } else {
    if (diff <= 2 * (max - ref - 1)) {
      if (diff & 1)
        return ref + ((diff + 1) >> 1);
      else
        return ref - (diff >> 1);
    }
    return max - (diff + 1);
  }
}

310 311
static int read_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                           int mi_row, int mi_col, aom_reader *r, int skip) {
312 313
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  struct segmentation_probs *const segp = &ec_ctx->seg;
314 315 316
  int prev_ul = -1; /* Top left segment_id */
  int prev_l = -1;  /* Current left segment_id */
  int prev_u = -1;  /* Current top segment_id */
317

318
  if ((xd->up_available) && (xd->left_available))
319 320
    prev_ul = get_segment_id(cm, cm->current_frame_seg_map, BLOCK_4X4,
                             mi_row - 1, mi_col - 1);
321

322
  if (xd->up_available)
323 324
    prev_u = get_segment_id(cm, cm->current_frame_seg_map, BLOCK_4X4,
                            mi_row - 1, mi_col - 0);
325

326
  if (xd->left_available)
327 328
    prev_l = get_segment_id(cm, cm->current_frame_seg_map, BLOCK_4X4,
                            mi_row - 0, mi_col - 1);
329

330 331
  int cdf_num = pick_spatial_seg_cdf(prev_ul, prev_u, prev_l);
  int pred = pick_spatial_seg_pred(prev_ul, prev_u, prev_l);
332

333
  if (skip) return pred;
334

335
  aom_cdf_prob *pred_cdf = segp->spatial_pred_seg_cdf[cdf_num];
336 337
  int coded_id = aom_read_symbol(r, pred_cdf, 8, ACCT_STR);

338
  int segment_id = neg_deinterleave(coded_id, pred, cm->last_active_segid + 1);
339

340
  assert(segment_id >= 0 && segment_id <= cm->last_active_segid);
341 342 343

  return segment_id;
}
344 345 346 347
#else
static int read_segment_id(aom_reader *r, struct segmentation_probs *segp) {
  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
}
348 349
#endif

350
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
351 352
                               MB_MODE_INFO *mbmi, TX_SIZE tx_size, int depth,
                               int blk_row, int blk_col, aom_reader *r) {
353 354
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
355
  int is_split = 0;
356 357 358 359 360 361 362
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
  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);
  TX_SIZE(*const inter_tx_size)
  [MAX_MIB_SIZE] =
      (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
363
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
364
  assert(tx_size > TX_4X4);
365

Jingning Han's avatar
Jingning Han committed
366
  if (depth == MAX_VARTX_DEPTH) {
367 368 369 370 371
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
    for (idy = 0; idy < AOMMAX(1, tx_size_high_unit[tx_size] / 2); ++idy)
      for (idx = 0; idx < AOMMAX(1, tx_size_wide_unit[tx_size] / 2); ++idx)
        inter_tx_size[idy][idx] = tx_size;
372
    mbmi->tx_size = tx_size;
373
    mbmi->min_tx_size = TXSIZEMIN(mbmi->min_tx_size, tx_size);
374 375
    txfm_partition_update(xd->above_txfm_context + blk_col,
                          xd->left_txfm_context + blk_row, tx_size, tx_size);
376 377 378
    return;
  }

379 380 381
  int ctx = txfm_partition_context(xd->above_txfm_context + blk_col,
                                   xd->left_txfm_context + blk_row,
                                   mbmi->sb_type, tx_size);
382
  is_split = aom_read_symbol(r, ec_ctx->txfm_partition_cdf[ctx], 2, ACCT_STR);
383 384

  if (is_split) {
385
    const TX_SIZE sub_txs = sub_tx_size_map[1][tx_size];
386 387
    const int bsw = tx_size_wide_unit[sub_txs];
    const int bsh = tx_size_high_unit[sub_txs];
388

389
    if (sub_txs == TX_4X4) {
390 391 392 393 394
      int idx, idy;
      inter_tx_size[0][0] = sub_txs;
      for (idy = 0; idy < AOMMAX(1, tx_size_high_unit[tx_size] / 2); ++idy)
        for (idx = 0; idx < AOMMAX(1, tx_size_wide_unit[tx_size] / 2); ++idx)
          inter_tx_size[idy][idx] = inter_tx_size[0][0];
395
      mbmi->tx_size = sub_txs;
396
      mbmi->min_tx_size = mbmi->tx_size;
397 398
      txfm_partition_update(xd->above_txfm_context + blk_col,
                            xd->left_txfm_context + blk_row, sub_txs, tx_size);
399 400 401
      return;
    }

402 403 404 405 406
    assert(bsw > 0 && bsh > 0);
    for (int row = 0; row < tx_size_high_unit[tx_size]; row += bsh) {
      for (int col = 0; col < tx_size_wide_unit[tx_size]; col += bsw) {
        int offsetr = blk_row + row;
        int offsetc = blk_col + col;
407 408
        read_tx_size_vartx(cm, xd, mbmi, sub_txs, depth + 1, offsetr, offsetc,
                           r);
409
      }
410 411
    }
  } else {
412 413 414 415 416
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
    for (idy = 0; idy < AOMMAX(1, tx_size_high_unit[tx_size] / 2); ++idy)
      for (idx = 0; idx < AOMMAX(1, tx_size_wide_unit[tx_size] / 2); ++idx)
        inter_tx_size[idy][idx] = tx_size;
417
    mbmi->tx_size = tx_size;
418
    mbmi->min_tx_size = TXSIZEMIN(mbmi->min_tx_size, tx_size);
419 420
    txfm_partition_update(xd->above_txfm_context + blk_col,
                          xd->left_txfm_context + blk_row, tx_size, tx_size);
421 422 423
  }
}

424
static TX_SIZE read_selected_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd,
425 426 427 428
                                     int is_inter, aom_reader *r) {
  // TODO(debargha): Clean up the logic here. This function should only
  // be called for intra.
  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
429
  const int32_t tx_size_cat = bsize_to_tx_size_cat(bsize, is_inter);
430
  const int max_depths = bsize_to_max_depth(bsize, 0);
431
  const int ctx = get_tx_size_context(xd, is_inter);
432 433 434
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;

435
  const int depth = aom_read_symbol(r, ec_ctx->tx_size_cdf[tx_size_cat][ctx],
436 437
                                    max_depths + 1, ACCT_STR);
  assert(depth >= 0 && depth <= max_depths);
438
  const TX_SIZE tx_size = depth_to_tx_size(depth, bsize, 0);
439
  return tx_size;
440 441
}

442 443 444 445
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;
446
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
447 448

  if (block_signals_txsize(bsize)) {
449
    if ((!is_inter || allow_select_inter) && tx_mode == TX_MODE_SELECT) {
450
      const TX_SIZE coded_tx_size = read_selected_tx_size(cm, xd, is_inter, r);
451
      return coded_tx_size;
452
    } else {
453
      return tx_size_from_tx_mode(bsize, tx_mode, is_inter);
454 455
    }
  } else {
456
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
457
    return get_max_rect_tx_size(bsize, is_inter);
458
  }
459 460
}

461
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
462
                              int mi_offset, int x_mis, int y_mis) {
463
  int segment_id = INT_MAX;
464

465 466
  for (int y = 0; y < y_mis; y++)
    for (int x = 0; x < x_mis; x++)
467
      segment_id =
468
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
469 470 471 472 473

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

474
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
475
                           int segment_id) {
476 477
  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);

478 479
  for (int y = 0; y < y_mis; y++)
    for (int x = 0; x < x_mis; x++)
480 481 482
      cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}

483
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
484 485
                                 int mi_row, int mi_col, int bsize,
                                 aom_reader *r, int skip) {
486
  struct segmentation *const seg = &cm->seg;
487 488 489 490 491
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = mi_size_wide[bsize];
  const int bh = mi_size_high[bsize];
  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
492

493
  if (!seg->enabled) return 0;  // Default for disabled segmentation
494

495
  assert(seg->update_map && !seg->temporal_update);
496

497
#if CONFIG_SPATIAL_SEGMENTATION
498
  const int segment_id = read_segment_id(cm, xd, mi_row, mi_col, r, skip);
499 500
#else
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
501
  (void)skip;
502
  const int segment_id = read_segment_id(r, &ec_ctx->seg);
503
#endif
504 505 506 507
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

508
static void copy_segment_id(const AV1_COMMON *cm,
509 510 511
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
512 513
  for (int y = 0; y < y_mis; y++)
    for (int x = 0; x < x_mis; x++)
514 515 516
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
517 518
}

519
static int read_inter_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
520 521
                                 int mi_row, int mi_col, int preskip,
                                 aom_reader *r) {
522
  struct segmentation *const seg = &cm->seg;
523 524 525
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  struct segmentation_probs *const segp = &ec_ctx->seg;

526 527 528
  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;
529 530
  const int bw = mi_size_wide[mbmi->sb_type];
  const int bh = mi_size_high[mbmi->sb_type];
531 532

  // TODO(slavarnway): move x_mis, y_mis into xd ?????
533 534
  const int x_mis = AOMMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = AOMMIN(cm->mi_rows - mi_row, bh);
535

536
  if (!seg->enabled) return 0;  // Default for disabled segmentation
537

538 539 540 541
  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;
542 543 544 545 546 547 548

  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;
  }

549 550 551 552 553 554 555 556 557
#if CONFIG_SPATIAL_SEGMENTATION
  if (preskip) {
    if (!cm->preskip_segid) return 0;
  } else {
    if (cm->preskip_segid) return mbmi->segment_id;
    if (mbmi->skip) {
      if (seg->temporal_update) {
        mbmi->seg_id_predicted = 0;
      }
558
      segment_id = read_segment_id(cm, xd, mi_row, mi_col, r, 1);
559 560 561 562 563 564
      set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
      return segment_id;
    }
  }
#endif
  (void)preskip;
565
  if (seg->temporal_update) {
566
    const int ctx = av1_get_pred_context_seg_id(xd);
567 568
    aom_cdf_prob *pred_cdf = segp->pred_cdf[ctx];
    mbmi->seg_id_predicted = aom_read_symbol(r, pred_cdf, 2, ACCT_STR);
569 570 571
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
572 573 574
#if CONFIG_SPATIAL_SEGMENTATION
      segment_id = read_segment_id(cm, xd, mi_row, mi_col, r, 0);
#else
575
      segment_id = read_segment_id(r, segp);
576
#endif
577
    }
578
  } else {
579 580 581
#if CONFIG_SPATIAL_SEGMENTATION
    segment_id = read_segment_id(cm, xd, mi_row, mi_col, r, 0);
#else
582
    segment_id = read_segment_id(r, segp);
583
#endif
584 585 586 587 588
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

589 590 591
#if CONFIG_EXT_SKIP
static int read_skip_mode(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                          aom_reader *r) {
592
  if (!cm->skip_mode_flag) return 0;
593 594 595 596 597

  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    // TODO(zoeliu): To revisit the handling of this scenario.
    return 0;
  }
598 599 600 601 602 603 604 605

  if (!is_comp_ref_allowed(xd->mi[0]->mbmi.sb_type)) return 0;

  const int ctx = av1_get_skip_mode_context(xd);
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  const int skip_mode =
      aom_read_symbol(r, ec_ctx->skip_mode_cdfs[ctx], 2, ACCT_STR);
  return skip_mode;
606 607 608
}
#endif  // CONFIG_EXT_SKIP

609 610
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
611 612 613
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
614
    const int ctx = av1_get_skip_context(xd);
615 616
    FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
    const int skip = aom_read_symbol(r, ec_ctx->skip_cdfs[ctx], 2, ACCT_STR);
617 618 619 620
    return skip;
  }
}

621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
// Merge the sorted list of cached colors(cached_colors[0...n_cached_colors-1])
// and the sorted list of transmitted colors(colors[n_cached_colors...n-1]) into
// one single sorted list(colors[...]).
static void merge_colors(uint16_t *colors, uint16_t *cached_colors,
                         int n_colors, int n_cached_colors) {
  if (n_cached_colors == 0) return;
  int cache_idx = 0, trans_idx = n_cached_colors;
  for (int i = 0; i < n_colors; ++i) {
    if (cache_idx < n_cached_colors &&
        (trans_idx >= n_colors ||
         cached_colors[cache_idx] <= colors[trans_idx])) {
      colors[i] = cached_colors[cache_idx++];
    } else {
      assert(trans_idx < n_colors);
      colors[i] = colors[trans_idx++];
    }
  }
638 639 640 641 642
}

static void read_palette_colors_y(MACROBLOCKD *const xd, int bit_depth,
                                  PALETTE_MODE_INFO *const pmi, aom_reader *r) {
  uint16_t color_cache[2 * PALETTE_MAX_SIZE];
643
  uint16_t cached_colors[PALETTE_MAX_SIZE];
644
  const int n_cache = av1_get_palette_cache(xd, 0, color_cache);
645 646 647
  const int n = pmi->palette_size[0];
  int idx = 0;
  for (int i = 0; i < n_cache && idx < n; ++i)
648
    if (aom_read_bit(r, ACCT_STR)) cached_colors[idx++] = color_cache[i];
649
  if (idx < n) {
650
    const int n_cached_colors = idx;
651 652 653 654 655 656
    pmi->palette_colors[idx++] = aom_read_literal(r, bit_depth, ACCT_STR);
    if (idx < n) {
      const int min_bits = bit_depth - 3;
      int bits = min_bits + aom_read_literal(r, 2, ACCT_STR);
      int range = (1 << bit_depth) - pmi->palette_colors[idx - 1] - 1;
      for (; idx < n; ++idx) {
657
        assert(range >= 0);
658
        const int delta = aom_read_literal(r, bits, ACCT_STR) + 1;
659 660 661
        pmi->palette_colors[idx] = clamp(pmi->palette_colors[idx - 1] + delta,
                                         0, (1 << bit_depth) - 1);
        range -= (pmi->palette_colors[idx] - pmi->palette_colors[idx - 1]);
662 663 664
        bits = AOMMIN(bits, av1_ceil_log2(range));
      }
    }
665 666 667
    merge_colors(pmi->palette_colors, cached_colors, n, n_cached_colors);
  } else {
    memcpy(pmi->palette_colors, cached_colors, n * sizeof(cached_colors[0]));
668 669 670 671 672 673 674 675 676
  }
}

static void read_palette_colors_uv(MACROBLOCKD *const xd, int bit_depth,
                                   PALETTE_MODE_INFO *const pmi,
                                   aom_reader *r) {
  const int n = pmi->palette_size[1];
  // U channel colors.
  uint16_t color_cache[2 * PALETTE_MAX_SIZE];
677
  uint16_t cached_colors[PALETTE_MAX_SIZE];
678
  const int n_cache = av1_get_palette_cache(xd, 1, color_cache);
679 680 681 682 683 684
  int idx = 0;
  for (int i = 0; i < n_cache && idx < n; ++i)
    if (aom_read_bit(r, ACCT_STR)) cached_colors[idx++] = color_cache[i];
  if (idx < n) {
    const int n_cached_colors = idx;
    idx += PALETTE_MAX_SIZE;
685 686 687 688 689 690
    pmi->palette_colors[idx++] = aom_read_literal(r, bit_depth, ACCT_STR);
    if (idx < PALETTE_MAX_SIZE + n) {
      const int min_bits = bit_depth - 3;
      int bits = min_bits + aom_read_literal(r, 2, ACCT_STR);
      int range = (1 << bit_depth) - pmi->palette_colors[idx - 1];
      for (; idx < PALETTE_MAX_SIZE + n; ++idx) {
691
        assert(range >= 0);
692
        const int delta = aom_read_literal(r, bits, ACCT_STR);
693 694 695
        pmi->palette_colors[idx] = clamp(pmi->palette_colors[idx - 1] + delta,
                                         0, (1 << bit_depth) - 1);
        range -= (pmi->palette_colors[idx] - pmi->palette_colors[idx - 1]);
696 697 698
        bits = AOMMIN(bits, av1_ceil_log2(range));
      }
    }
699 700 701 702 703
    merge_colors(pmi->palette_colors + PALETTE_MAX_SIZE, cached_colors, n,
                 n_cached_colors);
  } else {
    memcpy(pmi->palette_colors + PALETTE_MAX_SIZE, cached_colors,
           n * sizeof(cached_colors[0]));
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
  }

  // V channel colors.
  if (aom_read_bit(r, ACCT_STR)) {  // Delta encoding.
    const int min_bits_v = bit_depth - 4;
    const int max_val = 1 << bit_depth;
    int bits = min_bits_v + aom_read_literal(r, 2, ACCT_STR);
    pmi->palette_colors[2 * PALETTE_MAX_SIZE] =
        aom_read_literal(r, bit_depth, ACCT_STR);
    for (int i = 1; i < n; ++i) {
      int delta = aom_read_literal(r, bits, ACCT_STR);
      if (delta && aom_read_bit(r, ACCT_STR)) delta = -delta;
      int val = (int)pmi->palette_colors[2 * PALETTE_MAX_SIZE + i - 1] + delta;
      if (val < 0) val += max_val;
      if (val >= max_val) val -= max_val;
      pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] = val;
    }
  } else {
    for (int i = 0; i < n; ++i) {
      pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
          aom_read_literal(r, bit_depth, ACCT_STR);
    }
  }
}

729
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
730
                                   int mi_row, int mi_col, aom_reader *r) {
Hui Su's avatar
Hui Su committed
731
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
hui su's avatar
hui su committed
732
  const BLOCK_SIZE bsize = mbmi->sb_type;
733
  assert(av1_allow_palette(cm->allow_screen_content_tools, bsize));
734
  PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;
735
  const int bsize_ctx = av1_get_palette_bsize_ctx(bsize);
736

737
  if (mbmi->mode == DC_PRED) {
Hui Su's avatar
Hui Su committed
738
    const int palette_mode_ctx = av1_get_palette_mode_ctx(xd);
739
    const int modev = aom_read_symbol(
Hui Su's avatar
Hui Su committed
740
        r, xd->tile_ctx->palette_y_mode_cdf[bsize_ctx][palette_mode_ctx], 2,
741
        ACCT_STR);
742
    if (modev) {
743
      pmi->palette_size[0] =
744
          aom_read_symbol(r, xd->tile_ctx->palette_y_size_cdf[bsize_ctx],
745 746
                          PALETTE_SIZES, ACCT_STR) +
          2;
747
      read_palette_colors_y(xd, cm->bit_depth, pmi, r);
748 749
    }
  }
750 751 752
  if (mbmi->uv_mode == UV_DC_PRED &&
      is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
                          xd->plane[1].subsampling_y)) {
753
    const int palette_uv_mode_ctx = (pmi->palette_size[0] > 0);
754
    const int modev = aom_read_symbol(
755 756
        r, xd->tile_ctx->palette_uv_mode_cdf[palette_uv_mode_ctx], 2, ACCT_STR);
    if (modev) {
757
      pmi->palette_size[1] =
758
          aom_read_symbol(r, xd->tile_ctx->palette_uv_size_cdf[bsize_ctx],
759 760
                          PALETTE_SIZES, ACCT_STR) +
          2;
761
      read_palette_colors_uv(xd, cm->bit_depth, pmi, r);
762
    }
hui su's avatar
hui su committed
763 764 765
  }
}

766
#if CONFIG_FILTER_INTRA
767
static void read_filter_intra_mode_info(MACROBLOCKD *const xd, aom_reader *r) {
hui su's avatar
hui su committed
768 769
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
770 771
  FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
      &mbmi->filter_intra_mode_info;
hui su's avatar
hui su committed
772

773 774
  if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0 &&
      av1_filter_intra_allowed_txsize(mbmi->tx_size)) {
775
    filter_intra_mode_info->use_filter_intra = aom_read_symbol(
776
        r, xd->tile_ctx->filter_intra_cdfs[mbmi->tx_size], 2, ACCT_STR);
777
    if (filter_intra_mode_info->use_filter_intra) {
778 779
      filter_intra_mode_info->filter_intra_mode = aom_read_symbol(
          r, xd->tile_ctx->filter_intra_mode_cdf, FILTER_INTRA_MODES, ACCT_STR);
hui su's avatar
hui su committed
780 781 782
    }
  }
}
783
#endif  // CONFIG_FILTER_INTRA
784

785 786 787 788 789 790 791
#if CONFIG_EXT_INTRA_MOD
static int read_angle_delta(aom_reader *r, aom_cdf_prob *cdf) {
  const int sym = aom_read_symbol(r, cdf, 2 * MAX_ANGLE_DELTA + 1, ACCT_STR);
  return sym - MAX_ANGLE_DELTA;
}
#endif  // CONFIG_EXT_INTRA_MOD

792
static void read_intra_angle_info(MACROBLOCKD *const xd, aom_reader *r) {
793 794
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
795 796 797 798
#if CONFIG_EXT_INTRA_MOD
  FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
#endif  // CONFIG_EXT_INTRA_MOD

799 800 801
  mbmi->angle_delta[0] = 0;
  mbmi->angle_delta[1] = 0;
  if (!av1_use_angle_delta(bsize)) return;
802

hui su's avatar
hui su committed
803
  if (av1_is_directional_mode(mbmi->mode, bsize)) {
804 805 806 807
#if CONFIG_EXT_INTRA_MOD
    mbmi->angle_delta[0] =
        read_angle_delta(r, ec_ctx->angle_delta_cdf[mbmi->mode - V_PRED]);
#else
808
    mbmi->angle_delta[0] =
809
        av1_read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA;
810
#endif  // CONFIG_EXT_INTRA_MOD
811 812
  }

Luc Trudeau's avatar
Luc Trudeau committed
813
  if (av1_is_directional_mode(get_uv_mode(mbmi->uv_mode), bsize)) {
814 815 816 817
#if CONFIG_EXT_INTRA_MOD
    mbmi->angle_delta[1] =
        read_angle_delta(r, ec_ctx->angle_delta_cdf[mbmi->uv_mode - V_PRED]);
#else
818
    mbmi->angle_delta[1] =
819
        av1_read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA;
820
#endif  // CONFIG_EXT_INTRA_MOD
821 822
  }
}
hui su's avatar
hui su committed
823

824
void av1_read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
Angie Chiang's avatar
Angie Chiang committed
825
#if CONFIG_TXK_SEL
826
                      int blk_row, int blk_col, int plane, TX_SIZE tx_size,
827 828 829
#endif
                      aom_reader *r) {
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
Jingning Han's avatar
Jingning Han committed
830
  const int inter_block = is_inter_block(mbmi);
831
#if !CONFIG_TXK_SEL
832 833
  const TX_SIZE mtx_size =
      get_max_rect_tx_size(xd->mi[0]->mbmi.sb_type, inter_block);
834
  const TX_SIZE tx_size =
835
      inter_block ? AOMMAX(sub_tx_size_map[1][mtx_size], mbmi->min_tx_size)
836
                  : mbmi->tx_size;
837
#endif  // !CONFIG_TXK_SEL
838 839
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;

Angie Chiang's avatar
Angie Chiang committed
840
#if !CONFIG_TXK_SEL
841 842
  TX_TYPE *tx_type = &mbmi->tx_type;
#else
843 844
  // only y plane's tx_type is transmitted
  if (plane > 0) return;
Angie Chiang's avatar
Angie Chiang committed
845
  TX_TYPE *tx_type = &mbmi->txk_type[(blk_row << MAX_MIB_SIZE_LOG2) + blk_col];
846 847
#endif

848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
  const TX_SIZE square_tx_size = txsize_sqr_map[tx_size];
  if (get_ext_tx_types(tx_size, mbmi->sb_type, inter_block,
                       cm->reduced_tx_set_used) > 1 &&
      ((!cm->seg.enabled && cm->base_qindex > 0) ||
       (cm->seg.enabled && xd->qindex[mbmi->segment_id] > 0)) &&
      !mbmi->skip &&
      !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
    const TxSetType tx_set_type = get_ext_tx_set_type(
        tx_size, mbmi->sb_type, inter_block, cm->reduced_tx_set_used);
    const int eset = get_ext_tx_set(tx_size, mbmi->sb_type, inter_block,
                                    cm->reduced_tx_set_used);
    // eset == 0 should correspond to a set with only DCT_DCT and
    // there is no need to read the tx_type
    assert(eset != 0);

    if (inter_block) {
      *tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
          r, ec_ctx->inter_ext_tx_cdf[eset][square_tx_size],
          av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
    } else {
868
#if CONFIG_FILTER_INTRA
869 870 871 872 873 874 875 876 877
      PREDICTION_MODE intra_dir;
      if (mbmi->filter_intra_mode_info.use_filter_intra)
        intra_dir =
            fimode_to_intradir[mbmi->filter_intra_mode_info.filter_intra_mode];
      else
        intra_dir = mbmi->mode;
      *tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
          r, ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][intra_dir],
          av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
878
#else
879 880 881
      *tx_type = av1_ext_tx_inv[tx_set_type][aom_read_symbol(
          r, ec_ctx->intra_ext_tx_cdf[eset][square_tx_size][mbmi->mode],
          av1_num_ext_tx_set[tx_set_type], ACCT_STR)];
882
#endif
Jingning Han's avatar
Jingning Han committed
883
    }
884 885
  } else {
    *tx_type = DCT_DCT;
Jingning Han's avatar
Jingning Han committed
886 887 888
  }
}

889 890
#if CONFIG_INTRABC
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
891
                           nmv_context *ctx, MvSubpelPrecision precision);
892 893 894 895 896 897 898

static INLINE int is_mv_valid(const MV *mv);

static INLINE int assign_dv(AV1_COMMON *cm, MACROBLOCKD *xd, int_mv *mv,
                            const int_mv *ref_mv, int mi_row, int mi_col,
                            BLOCK_SIZE bsize, aom_reader *r) {
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
899
  read_mv(r, &mv->as_mv, &ref_mv->as_mv, &ec_ctx->ndvc, MV_SUBPEL_NONE);
900 901 902
  // DV should not have sub-pel.
  assert((mv->as_mv.col & 7) == 0);
  assert((mv->as_mv.row & 7) == 0);
903 904
  mv->as_mv.col = (mv->as_mv.col >> 3) * 8;
  mv->as_mv.row = (mv->as_mv.row >> 3) * 8;
905
  int valid = is_mv_valid(&mv->as_mv) &&
906 907
              av1_is_dv_valid(mv->as_mv, &xd->tile, mi_row, mi_col, bsize,
                              cm->mib_size_log2);
908 909 910 911
  return valid;
}
#endif  // CONFIG_INTRABC

912 913 914 915 916 917 918 919
#if CONFIG_INTRABC
static void read_intrabc_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                              int mi_row, int mi_col, aom_reader *r) {
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  mbmi->use_intrabc = aom_read_symbol(r, ec_ctx->intrabc_cdf, 2, ACCT_STR);
  if (mbmi->use_intrabc) {
Hui Su's avatar
Hui Su committed
920 921 922 923 924
    const BLOCK_SIZE bsize = mbmi->sb_type;
    const int width = block_size_wide[bsize] >> tx_size_wide_log2[0];
    const int height = block_size_high[bsize] >> tx_size_high_log2[0];
    if ((cm->tx_mode == TX_MODE_SELECT && block_signals_txsize(bsize) &&
         !xd->lossless[mbmi->segment_id] && !mbmi->skip)) {
925
      const TX_SIZE max_tx_size = get_max_rect_tx_size(bsize, 0);
Hui Su's avatar
Hui Su committed
926 927
      const int bh = tx_size_high_unit[max_tx_size];
      const int bw = tx_size_wide_unit[max_tx_size];
928
      mbmi->min_tx_size = TX_SIZES_LARGEST;
929 930
      for (int idy = 0; idy < height; idy += bh) {
        for (int idx = 0; idx < width; idx += bw) {
931
          read_tx_size_vartx(cm, xd, mbmi, max_tx_size, 0, idy, idx, r);
Hui Su's avatar
Hui Su committed
932 933 934 935
        }
      }
    } else {
      mbmi->tx_size = read_tx_size(cm, xd, 1, !mbmi->skip, r);
936 937 938
      for (int idy = 0; idy < height; ++idy)
        for (int idx = 0; idx < width; ++idx)
          mbmi->inter_tx_size[idy >> 1][idx >> 1] = mbmi->tx_size;
939
      mbmi->min_tx_size = mbmi->tx_size;
Hui Su's avatar
Hui Su committed
940 941
      set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, mbmi->skip, xd);
    }
942 943
    mbmi->mode = DC_PRED;
    mbmi->uv_mode = UV_DC_PRED;
944 945 946 947 948 949 950 951 952 953 954
    mbmi->interp_filters = av1_broadcast_interp_filter(BILINEAR);

    int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
    int_mv ref_mvs[MAX_MV_REF_CANDIDATES];

    av1_find_mv_refs(cm, xd, mi, INTRA_FRAME, &xd->ref_mv_count[INTRA_FRAME],
                     xd->ref_mv_stack[INTRA_FRAME], NULL, ref_mvs, mi_row,
                     mi_col, NULL, NULL, inter_mode_ctx);

    int_mv nearestmv, nearmv;

955 956 957 958 959
#if CONFIG_AMVR
    av1_find_best_ref_mvs(0, ref_mvs, &nearestmv, &nearmv, 0);
#else
    av1_find_best_ref_mvs(0, ref_mvs, &nearestmv, &nearmv);
#endif
960
    int_mv dv_ref = nearestmv.as_int == 0 ? nearmv : nearestmv;
Hui Su's avatar
Hui Su committed
961 962
    if (dv_ref.as_int == 0)
      av1_find_ref_dv(&dv_ref, &xd->tile, cm->mib_size, mi_row, mi_col);
963
    // Ref DV should not have sub-pel.
964
    int valid_dv = (dv_ref.as_mv.col & 7) == 0 && (dv_ref.as_mv.row & 7) == 0;
965 966
    dv_ref.as_mv.col = (dv_ref.as_mv.col >> 3) * 8;
    dv_ref.as_mv.row = (dv_ref.as_mv.row >> 3) * 8;
967 968 969
    valid_dv = valid_dv && assign_dv(cm, xd, &mbmi->mv[0], &dv_ref, mi_row,
                                     mi_col, bsize, r);
    if (!valid_dv) {
970 971
      // Intra bc motion vectors are not valid - signal corrupt frame
      aom_merge_corrupted_flag(&xd->corrupted, 1);
972
    }
973
#if !CONFIG_TXK_SEL
974
    av1_read_tx_type(cm, xd, r);
975
#endif  // !CONFIG_TXK_SEL
976 977 978 979
  }
}
#endif  // CONFIG_INTRABC

980
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
981
                                       MACROBLOCKD *const xd, int mi_row,
982
                                       int mi_col, aom_reader *r) {
983 984 985
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
986
  const MODE_INFO *left_mi = xd->left_mi;
987 988
  const BLOCK_SIZE bsize = mbmi->sb_type;

989
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
990

991 992 993 994 995 996 997 998
#if !CONFIG_SPATIAL_SEGMENTATION
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_row, mi_col, bsize, r, 0);
#else
  if (cm->preskip_segid)
    mbmi->segment_id =
        read_intra_segment_id(cm, xd, mi_row, mi_col, bsize, r, 0);
#endif

999
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
1000

1001
#if CONFIG_SPATIAL_SEGMENTATION
1002 1003 1004
  if (!cm->preskip_segid)
    mbmi->segment_id =
        read_intra_segment_id(cm, xd, mi_row, mi_col, bsize, r, mbmi->skip);
1005
#endif
1006

1007 1008
  read_cdef(cm, r, mbmi, mi_col, mi_row);

1009
  if (cm->delta_q_present_flag) {
1010 1011 1012
    xd->current_qindex =
        xd->prev_qindex +
        read_delta_qindex(cm, xd, r, mbmi, mi_col, mi_row) * cm->delta_q_res;
1013 1014
    /* Normative: Clamp to [1,MAXQ] to not interfere with lossless mode */
    xd->current_qindex = clamp(xd->current_qindex, 1, MAXQ);
1015
    xd->prev_qindex = xd->current_qindex;
1016 1017
#if CONFIG_EXT_DELTA_Q
    if (cm->delta_lf_present_flag) {
1018
#if CONFIG_LOOPFILTER_LEVEL
1019 1020
      if (cm->delta_lf_multi) {
        for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
Cheng Chen's avatar
Cheng Chen committed
1021
          const int tmp_lvl =
1022 1023 1024
              xd->prev_delta_lf[lf_id] +
              read_delta_lflevel(cm, xd, r, lf_id, mbmi, mi_col, mi_row) *
                  cm->delta_lf_res;
Cheng Chen's avatar
Cheng Chen committed
1025 1026
          mbmi->curr_delta_lf[lf_id] = xd->curr_delta_lf[lf_id] =
              clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
1027 1028 1029
          xd->prev_delta_lf[lf_id] = xd->curr_delta_lf[lf_id];
        }
      } else {
Cheng Chen's avatar
Cheng Chen committed
1030
        const int tmp_lvl =
1031 1032
            xd->prev_delta_lf_from_base +
            read_delta_lflevel(cm, xd, r, -1, mbmi, mi_col, mi_row) *
1033
                cm->delta_lf_res;
Cheng Chen's avatar
Cheng Chen committed
1034 1035
        mbmi->current_delta_lf_from_base = xd->current_delta_lf_from_base =
            clamp(tmp_lvl, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
1036
        xd->prev_delta_lf_from_base = xd->current_delta_lf_from_base;
1037 1038
      }
#else
1039
      const int current_delta_lf_from_base =
1040 1041 1042
          xd->prev_delta_lf_from_base +
          read_delta_lflevel(cm, xd, r, mbmi, mi_col, mi_row) *
              cm->delta_lf_res;
1043
      mbmi->current_delta_lf_from_base = xd->current_delta_lf_from_base =
Cheng Chen's avatar
Cheng Chen committed
1044
          clamp(current_delta_lf_from_base, -MAX_LOOP_FILTER, MAX_LOOP_FILTER);
1045
      xd->prev_delta_lf_from_base = xd->current_delta_lf_from_base;
1046
#endif  // CONFIG_LOOPFILTER_LEVEL
1047 1048
    }
#endif
1049 1050
  }

1051 1052
  mbmi->current_q_index = xd->current_qindex;

1053
  mbmi->ref_frame[0] = INTRA_FRAME;
Emil Keyder's avatar
Emil Keyder committed
1054
  mbmi->ref_frame[1] = NONE_FRAME;
1055

1056
#if CONFIG_INTRABC
Hui Su's avatar
Hui Su committed
1057 1058 1059 1060 1061 1062
  if (cm->allow_screen_content_tools) {
    xd->above_txfm_context =
        cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
    xd->left_txfm_context = xd->left_txfm_context_buffer +
                            ((mi_row & MAX_MIB_MASK) << TX_UNIT_HIGH_LOG2);
  }
1063
  if (av1_allow_intrabc(cm)) {
1064 1065
    read_intrabc_info(cm, xd, mi_row, mi_col, r);
    if (is_intrabc_block(mbmi)) return;
1066 1067 1068
  }
#endif  // CONFIG_INTRABC

1069
  mbmi->tx_size = read_tx_size(cm, xd, 0, 1, r);
1070
#if CONFIG_INTRABC
Hui Su's avatar
Hui Su committed
1071 1072
  if (cm->allow_screen_content_tools)
    set_txfm_ctxs(mbmi->tx_size, xd->n8_w, xd->n8_h, mbmi->skip, xd);
1073
#endif  // CONFIG_INTRABC
1074

1075
  mbmi->mode = read_intra_mode(r, get_y_mode_cdf(ec_ctx, above_mi, left_mi));
1076

1077
  if (is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
1078
                          xd->plane[1].subsampling_y)) {
1079
#if !CONFIG_CFL
1080
    mbmi->uv_mode = read_intra_mode_uv(ec_ctx, r, mbmi->mode);
1081 1082 1083 1084
#else
    xd->cfl.is_chroma_reference = 1;
    mbmi->uv_mode =
        read_intra_mode_uv(ec_ctx, r, is_cfl_allowed(mbmi), mbmi->mode);
1085
    if (mbmi->uv_mode == UV_CFL_PRED) {
1086
      mbmi->cfl_alpha_idx = read_cfl_alphas(ec_ctx, r, &mbmi->cfl_alpha_signs);
1087
      xd->cfl.store_y = 1;
1088
    } else {
1089
      xd->cfl.store_y = 0;
Luc Trudeau's avatar
Luc Trudeau committed
1090
    }
1091
#endif  // !CONFIG_CFL
1092 1093
  } else {
    // Avoid decoding angle_info if there is is no chroma prediction
Luc Trudeau's avatar
Luc Trudeau committed
1094
    mbmi->uv_mode = UV_DC_PRED;
1095
#if CONFIG_CFL
1096 1097
    xd->cfl.is_chroma_reference = 0;
    xd->cfl.store_y = 1;
1098
#endif
Luc Trudeau's avatar
Luc Trudeau committed
1099 1100
  }

1101
  read_intra_angle_info(xd, r);
hui su's avatar
hui su committed
1102 1103
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
1104
  if (av1_allow_palette(cm->allow_screen_content_tools, bsize))
1105
    read_palette_mode_info(cm, xd, mi_row, mi_col, r);
1106
#if CONFIG_FILTER_INTRA
1107
  mbmi->filter_intra_mode_info.use_filter_intra = 0;
1108
  read_filter_intra_mode_info(xd, r);
1109
#endif  // CONFIG_FILTER_INTRA
hui su's avatar
hui su committed
1110

Angie Chiang's avatar
Angie Chiang committed
1111
#if !CONFIG_TXK_SEL
1112
  av1_read_tx_type(cm, xd, r);
Angie Chiang's avatar
Angie Chiang committed
1113
#endif  // !CONFIG_TXK_SEL