decodemv.c 109 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

36
#define DEC_MISMATCH_DEBUG 0
37

38
static PREDICTION_MODE read_intra_mode(aom_reader *r, aom_cdf_prob *cdf) {
Hui Su's avatar
Hui Su committed
39
  return (PREDICTION_MODE)aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR);
40
}
Jingning Han's avatar
Jingning Han committed
41

42 43 44 45 46 47 48 49
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
50 51 52 53
  int rem_bits, thr;
  int i, smallval;
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
54

55
  if ((bsize != BLOCK_LARGEST || mbmi->skip == 0) && read_delta_q_flag) {
Thomas Davies's avatar
Thomas Davies committed
56 57 58 59 60 61 62 63
    abs = aom_read_symbol(r, ec_ctx->delta_q_cdf, DELTA_Q_PROBS + 1, ACCT_STR);
    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) {
64
      rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
65 66 67 68 69 70 71 72 73 74 75 76 77 78
      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;
}
Fangwen Fu's avatar
Fangwen Fu committed
79 80
#if CONFIG_EXT_DELTA_Q
static int read_delta_lflevel(AV1_COMMON *cm, MACROBLOCKD *xd, aom_reader *r,
81 82 83
#if CONFIG_LOOPFILTER_LEVEL
                              int lf_id,
#endif
Fangwen Fu's avatar
Fangwen Fu committed
84 85 86 87 88 89 90 91 92 93 94 95 96
                              MB_MODE_INFO *const mbmi, int mi_col,
                              int mi_row) {
  FRAME_COUNTS *counts = xd->counts;
  int sign, abs, reduced_delta_lflevel = 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_lf_flag = (b_col == 0 && b_row == 0);
  int rem_bits, thr;
  int i, smallval;
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;

97
  if ((bsize != cm->sb_size || mbmi->skip == 0) && read_delta_lf_flag) {
98
#if CONFIG_LOOPFILTER_LEVEL
99 100 101 102 103 104 105 106
    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);
    }
107
#else
Fangwen Fu's avatar
Fangwen Fu committed
108 109
    abs =
        aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1, ACCT_STR);
110
#endif  // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu's avatar
Fangwen Fu committed
111 112
    smallval = (abs < DELTA_LF_SMALL);
    if (counts) {
113
#if CONFIG_LOOPFILTER_LEVEL
114 115 116 117 118 119 120
      if (cm->delta_lf_multi) {
        for (i = 0; i < abs; ++i) counts->delta_lf_multi[lf_id][i][1]++;
        if (smallval) counts->delta_lf_multi[lf_id][abs][0]++;
      } else {
        for (i = 0; i < abs; ++i) counts->delta_lf[i][1]++;
        if (smallval) counts->delta_lf[abs][0]++;
      }
121
#else
Fangwen Fu's avatar
Fangwen Fu committed
122 123
      for (i = 0; i < abs; ++i) counts->delta_lf[i][1]++;
      if (smallval) counts->delta_lf[abs][0]++;
124
#endif  // CONFIG_LOOPFILTER_LEVEL
Fangwen Fu's avatar
Fangwen Fu committed
125 126
    }
    if (!smallval) {
127
      rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
Fangwen Fu's avatar
Fangwen Fu committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
      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_lflevel = sign ? -abs : abs;
  }
  return reduced_delta_lflevel;
}
#endif
143

Luc Trudeau's avatar
Luc Trudeau committed
144
static UV_PREDICTION_MODE read_intra_mode_uv(FRAME_CONTEXT *ec_ctx,
145
                                             aom_reader *r,
Luc Trudeau's avatar
Luc Trudeau committed
146 147
                                             PREDICTION_MODE y_mode) {
  const UV_PREDICTION_MODE uv_mode =
148 149 150
#if CONFIG_CFL
      aom_read_symbol(r, ec_ctx->uv_mode_cdf[y_mode], UV_INTRA_MODES, ACCT_STR);
#else
151
      read_intra_mode(r, ec_ctx->uv_mode_cdf[y_mode]);
152
#endif  // CONFIG_CFL
Jingning Han's avatar
Jingning Han committed
153 154 155
  return uv_mode;
}

Luc Trudeau's avatar
Luc Trudeau committed
156
#if CONFIG_CFL
157
static int read_cfl_alphas(FRAME_CONTEXT *const ec_ctx, aom_reader *r,
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
                           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
174 175 176
}
#endif

177
#if CONFIG_INTERINTRA
Yaowu Xu's avatar
Yaowu Xu committed
178 179
static INTERINTRA_MODE read_interintra_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                            aom_reader *r, int size_group) {
180 181 182 183
  (void)cm;
  const INTERINTRA_MODE ii_mode = (INTERINTRA_MODE)aom_read_symbol(
      r, xd->tile_ctx->interintra_mode_cdf[size_group], INTERINTRA_MODES,
      ACCT_STR);
184
  FRAME_COUNTS *counts = xd->counts;
185
  if (counts) ++counts->interintra_mode[size_group][ii_mode];
186 187
  return ii_mode;
}
188
#endif  // CONFIG_INTERINTRA
189

190
static PREDICTION_MODE read_inter_mode(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
191
                                       aom_reader *r, int16_t ctx) {
192
  FRAME_COUNTS *counts = xd->counts;
193
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
194 195 196 197 198 199
  int is_newmv, is_zeromv, is_refmv;
#if CONFIG_NEW_MULTISYMBOL
  is_newmv = aom_read_symbol(r, ec_ctx->newmv_cdf[mode_ctx], 2, ACCT_STR) == 0;
#else
  is_newmv = aom_read(r, ec_ctx->newmv_prob[mode_ctx], ACCT_STR) == 0;
#endif
200

201
  if (is_newmv) {
202
    if (counts) ++counts->newmv_mode[mode_ctx][0];
203
    return NEWMV;
204
  }
205
  if (counts) ++counts->newmv_mode[mode_ctx][1];
206

207
  if (ctx & (1 << ALL_ZERO_FLAG_OFFSET)) return ZEROMV;
208

209
  mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
210

211 212 213 214 215 216 217
#if CONFIG_NEW_MULTISYMBOL
  is_zeromv =
      aom_read_symbol(r, ec_ctx->zeromv_cdf[mode_ctx], 2, ACCT_STR) == 0;
#else
  is_zeromv = aom_read(r, ec_ctx->zeromv_prob[mode_ctx], ACCT_STR) == 0;
#endif
  if (is_zeromv) {
218
    if (counts) ++counts->zeromv_mode[mode_ctx][0];
219 220
    return ZEROMV;
  }
221
  if (counts) ++counts->zeromv_mode[mode_ctx][1];
222

223
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
224

225 226 227
  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;
228

229 230 231 232 233
#if CONFIG_NEW_MULTISYMBOL
  is_refmv = aom_read_symbol(r, ec_ctx->refmv_cdf[mode_ctx], 2, ACCT_STR) == 0;
#else
  is_refmv = aom_read(r, ec_ctx->refmv_prob[mode_ctx], ACCT_STR) == 0;
#endif
234

235
  if (is_refmv) {
236
    if (counts) ++counts->refmv_mode[mode_ctx][0];
237

238 239
    return NEARESTMV;
  } else {
240
    if (counts) ++counts->refmv_mode[mode_ctx][1];
241 242 243 244 245
    return NEARMV;
  }

  // Invalid prediction mode.
  assert(0);
Jingning Han's avatar
Jingning Han committed
246 247
}

248
static void read_drl_idx(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
249 250
                         MB_MODE_INFO *mbmi, aom_reader *r) {
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
251 252
  mbmi->ref_mv_idx = 0;

253
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV
254
#if CONFIG_COMPOUND_SINGLEREF
255
      || mbmi->mode == SR_NEW_NEWMV
256
#endif  // CONFIG_COMPOUND_SINGLEREF
257
      ) {
258 259 260
    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
261
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
262 263 264 265 266 267 268 269
#if CONFIG_NEW_MULTISYMBOL
        int drl_idx = aom_read_symbol(r, ec_ctx->drl_cdf[drl_ctx], 2, ACCT_STR);
#else
        int drl_idx = aom_read(r, ec_ctx->drl_prob[drl_ctx], ACCT_STR);
#endif
        mbmi->ref_mv_idx = idx + drl_idx;
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][drl_idx];
        if (!drl_idx) return;
270 271 272 273
      }
    }
  }

David Barker's avatar
David Barker committed
274
  if (have_nearmv_in_inter_mode(mbmi->mode)) {
275 276 277 278 279 280
    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
281
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
282 283 284 285 286 287 288 289
#if CONFIG_NEW_MULTISYMBOL
        int drl_idx = aom_read_symbol(r, ec_ctx->drl_cdf[drl_ctx], 2, ACCT_STR);
#else
        int drl_idx = aom_read(r, ec_ctx->drl_prob[drl_ctx], ACCT_STR);
#endif
        mbmi->ref_mv_idx = idx + drl_idx - 1;
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][drl_idx];
        if (!drl_idx) return;
290 291 292 293 294
      }
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
295 296
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
297 298
                                    MODE_INFO *mi, aom_reader *r) {
  MB_MODE_INFO *mbmi = &mi->mbmi;
299 300
#if !CONFIG_MOTION_VAR || !CONFIG_WARPED_MOTION || CONFIG_NEW_MULTISYMBOL || \
    CONFIG_NCOBMC_ADAPT_WEIGHT
Thomas Davies's avatar
Thomas Davies committed
301 302 303
  (void)cm;
#endif

304
  const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
305
#if CONFIG_GLOBAL_MOTION
306
      0, xd->global_motion,
307
#endif  // CONFIG_GLOBAL_MOTION
308 309 310
#if CONFIG_WARPED_MOTION
      xd,
#endif
311
      mi);
Yue Chen's avatar
Yue Chen committed
312 313
  int motion_mode;
  FRAME_COUNTS *counts = xd->counts;
Yaowu Xu's avatar
Yaowu Xu committed
314

Yue Chen's avatar
Yue Chen committed
315 316
  if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return SIMPLE_TRANSLATION;
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
317 318 319 320 321 322 323 324 325 326 327 328 329
#if CONFIG_NCOBMC_ADAPT_WEIGHT
  if (last_motion_mode_allowed == NCOBMC_ADAPT_WEIGHT) {
    motion_mode = aom_read_symbol(r, xd->tile_ctx->ncobmc_cdf[mbmi->sb_type],
                                  OBMC_FAMILY_MODES, ACCT_STR);
    if (counts) ++counts->ncobmc[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else if (last_motion_mode_allowed == OBMC_CAUSAL) {
    motion_mode =
        aom_read_symbol(r, xd->tile_ctx->obmc_cdf[mbmi->sb_type], 2, ACCT_STR);
    if (counts) ++counts->obmc[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else {
#else
Yue Chen's avatar
Yue Chen committed
330
  if (last_motion_mode_allowed == OBMC_CAUSAL) {
331 332 333 334
#if CONFIG_NEW_MULTISYMBOL
    motion_mode =
        aom_read_symbol(r, xd->tile_ctx->obmc_cdf[mbmi->sb_type], 2, ACCT_STR);
#else
Yue Chen's avatar
Yue Chen committed
335
    motion_mode = aom_read(r, cm->fc->obmc_prob[mbmi->sb_type], ACCT_STR);
336
#endif
Yue Chen's avatar
Yue Chen committed
337 338 339
    if (counts) ++counts->obmc[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else {
340
#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
Yue Chen's avatar
Yue Chen committed
341
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
342
    motion_mode =
Thomas Davies's avatar
Thomas Davies committed
343 344
        aom_read_symbol(r, xd->tile_ctx->motion_mode_cdf[mbmi->sb_type],
                        MOTION_MODES, ACCT_STR);
Yaowu Xu's avatar
Yaowu Xu committed
345 346
    if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
Yue Chen's avatar
Yue Chen committed
347
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
348
  }
Yue Chen's avatar
Yue Chen committed
349
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
350
}
351 352

#if CONFIG_NCOBMC_ADAPT_WEIGHT
353
static void read_ncobmc_mode(MACROBLOCKD *xd, MODE_INFO *mi,
354
                             NCOBMC_MODE ncobmc_mode[2], aom_reader *r) {
355 356 357
  MB_MODE_INFO *mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
  ADAPT_OVERLAP_BLOCK ao_block = adapt_overlap_block_lookup[mbmi->sb_type];
358
  if (mbmi->motion_mode != NCOBMC_ADAPT_WEIGHT) return;
359

360 361
  ncobmc_mode[0] = aom_read_symbol(r, xd->tile_ctx->ncobmc_mode_cdf[ao_block],
                                   MAX_NCOBMC_MODES, ACCT_STR);
362 363 364
  if (counts) ++counts->ncobmc_mode[ao_block][ncobmc_mode[0]];

  if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
365 366
    ncobmc_mode[1] = aom_read_symbol(r, xd->tile_ctx->ncobmc_mode_cdf[ao_block],
                                     MAX_NCOBMC_MODES, ACCT_STR);
367 368 369
    if (counts) ++counts->ncobmc_mode[ao_block][ncobmc_mode[1]];
  }
}
370
#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
Yaowu Xu's avatar
Yaowu Xu committed
371 372
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION

Yaowu Xu's avatar
Yaowu Xu committed
373 374
static PREDICTION_MODE read_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                                aom_reader *r, int16_t ctx) {
375 376 377 378
  (void)cm;
  const int mode =
      aom_read_symbol(r, xd->tile_ctx->inter_compound_mode_cdf[ctx],
                      INTER_COMPOUND_MODES, ACCT_STR);
379 380
  FRAME_COUNTS *counts = xd->counts;

381
  if (counts) ++counts->inter_compound_mode[ctx][mode];
382 383 384 385

  assert(is_inter_compound_mode(NEAREST_NEARESTMV + mode));
  return NEAREST_NEARESTMV + mode;
}
386 387

#if CONFIG_COMPOUND_SINGLEREF
388
static PREDICTION_MODE read_inter_singleref_comp_mode(MACROBLOCKD *xd,
389 390 391
                                                      aom_reader *r,
                                                      int16_t ctx) {
  const int mode =
392 393
      aom_read_symbol(r, xd->tile_ctx->inter_singleref_comp_mode_cdf[ctx],
                      INTER_SINGLEREF_COMP_MODES, ACCT_STR);
394 395 396 397 398 399 400 401
  FRAME_COUNTS *counts = xd->counts;

  if (counts) ++counts->inter_singleref_comp_mode[ctx][mode];

  assert(is_inter_singleref_comp_mode(SR_NEAREST_NEARMV + mode));
  return SR_NEAREST_NEARMV + mode;
}
#endif  // CONFIG_COMPOUND_SINGLEREF
402

403
static int read_segment_id(aom_reader *r, struct segmentation_probs *segp) {
Michael Bebenita's avatar
Michael Bebenita committed
404
  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
Jingning Han's avatar
Jingning Han committed
405 406
}

407
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
408
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
409
                               MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
410 411
                               TX_SIZE tx_size, int depth, int blk_row,
                               int blk_col, aom_reader *r) {
412 413 414 415
#if CONFIG_NEW_MULTISYMBOL
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#endif
416
  int is_split = 0;
417 418
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
419 420
  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);
421 422
  int ctx = txfm_partition_context(xd->above_txfm_context + blk_col,
                                   xd->left_txfm_context + blk_row,
423
                                   mbmi->sb_type, tx_size);
clang-format's avatar
clang-format committed
424
  TX_SIZE(*const inter_tx_size)
425 426 427
  [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;
David Barker's avatar
David Barker committed
428
  assert(tx_size > TX_4X4);
429

Jingning Han's avatar
Jingning Han committed
430
  if (depth == MAX_VARTX_DEPTH) {
431 432
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
433 434
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
435 436
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
437
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
438 439
    txfm_partition_update(xd->above_txfm_context + blk_col,
                          xd->left_txfm_context + blk_row, tx_size, tx_size);
440 441 442
    return;
  }

443 444 445
#if CONFIG_NEW_MULTISYMBOL
  is_split = aom_read_symbol(r, ec_ctx->txfm_partition_cdf[ctx], 2, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
446
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
447
#endif
448 449

  if (is_split) {
450 451
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
452
    int i;
453

454
    if (counts) ++counts->txfm_partition[ctx][1];
455

David Barker's avatar
David Barker committed
456
    if (sub_txs == TX_4X4) {
457
      int idx, idy;
458
      inter_tx_size[0][0] = sub_txs;
459 460
      for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
        for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
461
          inter_tx_size[idy][idx] = inter_tx_size[0][0];
462
      mbmi->tx_size = sub_txs;
463
      mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
464 465
      txfm_partition_update(xd->above_txfm_context + blk_col,
                            xd->left_txfm_context + blk_row, sub_txs, tx_size);
466 467 468 469 470
      return;
    }

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
471 472 473
      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,
474
                         offsetc, r);
475 476
    }
  } else {
477
    int idx, idy;
478
    inter_tx_size[0][0] = tx_size;
479 480
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
481 482
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
483
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
484
    if (counts) ++counts->txfm_partition[ctx][0];
485 486
    txfm_partition_update(xd->above_txfm_context + blk_col,
                          xd->left_txfm_context + blk_row, tx_size, tx_size);
487 488 489 490
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
491
static TX_SIZE read_selected_tx_size(AV1_COMMON *cm, MACROBLOCKD *xd,
492
                                     int32_t tx_size_cat, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
493 494
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
495 496 497
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;

498 499
  const int depth = aom_read_symbol(r, ec_ctx->tx_size_cdf[tx_size_cat][ctx],
                                    tx_size_cat + 2, ACCT_STR);
500 501 502 503
  const TX_SIZE tx_size = depth_to_tx_size(depth);
#if CONFIG_RECT_TX
  assert(!is_rect_tx(tx_size));
#endif  // CONFIG_RECT_TX
504
  if (counts) ++counts->tx_size[tx_size_cat][ctx][depth];
505
  return tx_size;
Jingning Han's avatar
Jingning Han committed
506 507
}

508 509 510 511
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;
512
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
513 514

  if (block_signals_txsize(bsize)) {
515 516 517
    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];
518
      const TX_SIZE coded_tx_size =
519
          read_selected_tx_size(cm, xd, tx_size_cat, r);
520
#if CONFIG_RECT_TX && (CONFIG_EXT_TX || CONFIG_VAR_TX)
521 522
      if (coded_tx_size > max_txsize_lookup[bsize]) {
        assert(coded_tx_size == max_txsize_lookup[bsize] + 1);
Yue Chen's avatar
Yue Chen committed
523
#if CONFIG_RECT_TX_EXT
524
        if (is_quarter_tx_allowed(xd, &xd->mi[0]->mbmi, is_inter)) {
Yue Chen's avatar
Yue Chen committed
525
          int quarter_tx;
526

Yue Chen's avatar
Yue Chen committed
527
          if (quarter_txsize_lookup[bsize] != max_txsize_lookup[bsize]) {
528 529 530 531
#if CONFIG_NEW_MULTISYMBOL
            quarter_tx =
                aom_read_symbol(r, cm->fc->quarter_tx_size_cdf, 2, ACCT_STR);
#else
Yue Chen's avatar
Yue Chen committed
532 533 534
            quarter_tx = aom_read(r, cm->fc->quarter_tx_size_prob, ACCT_STR);
            FRAME_COUNTS *counts = xd->counts;
            if (counts) ++counts->quarter_tx_size[quarter_tx];
535
#endif
Yue Chen's avatar
Yue Chen committed
536 537 538
          } else {
            quarter_tx = 1;
          }
539 540 541
          return quarter_tx ? quarter_txsize_lookup[bsize]
                            : max_txsize_rect_lookup[bsize];
        }
Yue Chen's avatar
Yue Chen committed
542
#endif  // CONFIG_RECT_TX_EXT
543

544 545
        return max_txsize_rect_lookup[bsize];
      }
546 547
#else
      assert(coded_tx_size <= max_txsize_lookup[bsize]);
548
#endif  // CONFIG_RECT_TX && (CONFIG_EXT_TX || CONFIG_VAR_TX)
549
      return coded_tx_size;
550
    } else {
551
      return tx_size_from_tx_mode(bsize, tx_mode, is_inter);
552 553
    }
  } else {
554
#if CONFIG_EXT_TX && CONFIG_RECT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
555
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
556 557 558
    return max_txsize_rect_lookup[bsize];
#else
    return TX_4X4;
559
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX
560
  }
Jingning Han's avatar
Jingning Han committed
561 562
}

Yaowu Xu's avatar
Yaowu Xu committed
563
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
564 565 566 567 568
                              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++)
569
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
570
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
571 572 573 574 575

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

Yaowu Xu's avatar
Yaowu Xu committed
576
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
577
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
578 579 580 581 582 583 584 585 586
  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
587
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
588
                                 int mi_offset, int x_mis, int y_mis,
Yaowu Xu's avatar
Yaowu Xu committed
589
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
590
  struct segmentation *const seg = &cm->seg;
591
  FRAME_COUNTS *counts = xd->counts;
592 593
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  struct segmentation_probs *const segp = &ec_ctx->seg;
Jingning Han's avatar
Jingning Han committed
594 595
  int segment_id;

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

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

600
  segment_id = read_segment_id(r, segp);
601
  if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
602 603 604 605
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
606
static void copy_segment_id(const AV1_COMMON *cm,
607 608 609
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
610 611 612 613
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
614 615 616
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
617 618
}

Yaowu Xu's avatar
Yaowu Xu committed
619 620
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
621
  struct segmentation *const seg = &cm->seg;
622
  FRAME_COUNTS *counts = xd->counts;
623 624 625
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  struct segmentation_probs *const segp = &ec_ctx->seg;

Jingning Han's avatar
Jingning Han committed
626 627 628
  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;
629 630
  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
631 632

  // TODO(slavarnway): move x_mis, y_mis into xd ?????
Yaowu Xu's avatar
Yaowu Xu committed
633 634
  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
635

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

638 639 640 641
  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
642 643 644 645 646 647 648 649

  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
650
    const int ctx = av1_get_pred_context_seg_id(xd);
651 652 653 654
#if CONFIG_NEW_MULTISYMBOL
    aom_cdf_prob *pred_cdf = segp->pred_cdf[ctx];
    mbmi->seg_id_predicted = aom_read_symbol(r, pred_cdf, 2, ACCT_STR);
#else
Yaowu Xu's avatar
Yaowu Xu committed
655
    const aom_prob pred_prob = segp->pred_probs[ctx];
Michael Bebenita's avatar
Michael Bebenita committed
656
    mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
657
#endif
658
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
659 660 661 662
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
663
      if (counts) ++counts->seg.tree_mispred[segment_id];
664
    }
Jingning Han's avatar
Jingning Han committed
665
  } else {
666
    segment_id = read_segment_id(r, segp);
667
    if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
668 669 670 671 672
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
673 674
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
675 676 677
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
678
    const int ctx = av1_get_skip_context(xd);
679 680 681 682
#if CONFIG_NEW_MULTISYMBOL
    FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
    const int skip = aom_read_symbol(r, ec_ctx->skip_cdfs[ctx], 2, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
683
    const int skip = aom_read(r, cm->fc->skip_probs[ctx], ACCT_STR);
684
#endif
Jingning Han's avatar
Jingning Han committed
685
    FRAME_COUNTS *counts = xd->counts;
686
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
687 688 689 690
    return skip;
  }
}

691
#if CONFIG_PALETTE_DELTA_ENCODING
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
// 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++];
    }
  }
709 710 711 712 713
}

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];
714
  uint16_t cached_colors[PALETTE_MAX_SIZE];
715
  const int n_cache = av1_get_palette_cache(xd, 0, color_cache);
716 717 718
  const int n = pmi->palette_size[0];
  int idx = 0;
  for (int i = 0; i < n_cache && idx < n; ++i)
719
    if (aom_read_bit(r, ACCT_STR)) cached_colors[idx++] = color_cache[i];
720
  if (idx < n) {
721
    const int n_cached_colors = idx;
722 723 724 725 726 727
    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) {
728
        assert(range >= 0);
729
        const int delta = aom_read_literal(r, bits, ACCT_STR) + 1;
730 731 732
        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]);
733 734 735
        bits = AOMMIN(bits, av1_ceil_log2(range));
      }
    }
736 737 738
    merge_colors(pmi->palette_colors, cached_colors, n, n_cached_colors);
  } else {
    memcpy(pmi->palette_colors, cached_colors, n * sizeof(cached_colors[0]));
739 740 741 742 743 744 745 746 747
  }
}

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];
748
  uint16_t cached_colors[PALETTE_MAX_SIZE];
749
  const int n_cache = av1_get_palette_cache(xd, 1, color_cache);
750 751 752 753 754 755
  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;
756 757 758 759 760 761
    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) {
762
        assert(range >= 0);
763
        const int delta = aom_read_literal(r, bits, ACCT_STR);
764 765 766
        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]);
767 768 769
        bits = AOMMIN(bits, av1_ceil_log2(range));
      }
    }
770 771 772 773 774
    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]));
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
  }

  // 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);
    }
  }
}
#endif  // CONFIG_PALETTE_DELTA_ENCODING

Yaowu Xu's avatar
Yaowu Xu committed
801 802
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                   aom_reader *r) {
hui su's avatar
hui su committed
803 804
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
805
  const MODE_INFO *const above_mi = xd->above_mi;
806
  const MODE_INFO *const left_mi = xd->left_mi;
hui su's avatar
hui su committed
807
  const BLOCK_SIZE bsize = mbmi->sb_type;
808 809
  PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;

810 811
  assert(bsize >= BLOCK_8X8 && bsize <= BLOCK_LARGEST);
  const int block_palette_idx = bsize - BLOCK_8X8;
812
  int modev;
813

814
  if (mbmi->mode == DC_PRED) {
815
    int palette_y_mode_ctx = 0;
816
    if (above_mi) {
817 818
      palette_y_mode_ctx +=
          (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
819 820
    }
    if (left_mi) {
821 822
      palette_y_mode_ctx +=
          (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
823
    }
824 825 826 827 828 829 830 831 832 833 834 835
#if CONFIG_NEW_MULTISYMBOL
    modev = aom_read_symbol(
        r,
        xd->tile_ctx->palette_y_mode_cdf[block_palette_idx][palette_y_mode_ctx],
        2, ACCT_STR);
#else
    modev = aom_read(
        r,
        av1_default_palette_y_mode_prob[block_palette_idx][palette_y_mode_ctx],
        ACCT_STR);
#endif
    if (modev) {
836
      pmi->palette_size[0] =