decodemv.c 104 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
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
39
static INLINE int read_uniform(aom_reader *r, int n) {
40
41
42
  const int l = get_unsigned_bits(n);
  const int m = (1 << l) - n;
  const int v = aom_read_literal(r, l - 1, ACCT_STR);
hui su's avatar
hui su committed
43
44
45
46
  assert(l != 0);
  if (v < m)
    return v;
  else
Michael Bebenita's avatar
Michael Bebenita committed
47
    return (v << 1) - m + aom_read_literal(r, 1, ACCT_STR);
hui su's avatar
hui su committed
48
}
49
#endif  // CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
hui su's avatar
hui su committed
50

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)];
}
Jingning Han's avatar
Jingning Han committed
55

56
57
58
59
60
61
62
63
64
#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
65
66
67
68
  int rem_bits, thr;
  int i, smallval;
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
69

70
  if ((bsize != BLOCK_LARGEST || mbmi->skip == 0) && read_delta_q_flag) {
Thomas Davies's avatar
Thomas Davies committed
71
72
73
74
75
76
77
78
    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) {
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
      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;
}
Fangwen Fu's avatar
Fangwen Fu committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#if CONFIG_EXT_DELTA_Q
static int read_delta_lflevel(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_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;

  if ((bsize != BLOCK_64X64 || mbmi->skip == 0) && read_delta_lf_flag) {
    abs =
        aom_read_symbol(r, ec_ctx->delta_lf_cdf, DELTA_LF_PROBS + 1, ACCT_STR);
    smallval = (abs < DELTA_LF_SMALL);
    if (counts) {
      for (i = 0; i < abs; ++i) counts->delta_lf[i][1]++;
      if (smallval) counts->delta_lf[abs][0]++;
    }
    if (!smallval) {
      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_lflevel = sign ? -abs : abs;
  }
  return reduced_delta_lflevel;
}
#endif
134
135
#endif

136
static PREDICTION_MODE read_intra_mode_y(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
137
                                         aom_reader *r, int size_group) {
Jingning Han's avatar
Jingning Han committed
138
  const PREDICTION_MODE y_mode =
139
      read_intra_mode(r, ec_ctx->y_mode_cdf[size_group]);
140
#if CONFIG_ENTROPY_STATS
Jingning Han's avatar
Jingning Han committed
141
  FRAME_COUNTS *counts = xd->counts;
142
  if (counts) ++counts->y_mode[size_group][y_mode];
143
144
145
#else
  /* TODO(negge): Can we remove this parameter? */
  (void)xd;
146
#endif  // CONFIG_ENTROPY_STATS
Jingning Han's avatar
Jingning Han committed
147
148
149
  return y_mode;
}

150
151
static PREDICTION_MODE read_intra_mode_uv(FRAME_CONTEXT *ec_ctx,
                                          MACROBLOCKD *xd, aom_reader *r,
Jingning Han's avatar
Jingning Han committed
152
                                          PREDICTION_MODE y_mode) {
153
  const PREDICTION_MODE uv_mode =
154
      read_intra_mode(r, ec_ctx->uv_mode_cdf[y_mode]);
155
#if CONFIG_ENTROPY_STATS
Jingning Han's avatar
Jingning Han committed
156
  FRAME_COUNTS *counts = xd->counts;
157
  if (counts) ++counts->uv_mode[y_mode][uv_mode];
158
159
160
#else
  /* TODO(negge): Can we remove this parameter? */
  (void)xd;
161
#endif  // CONFIG_ENTROPY_STATS
Jingning Han's avatar
Jingning Han committed
162
163
164
  return uv_mode;
}

Luc Trudeau's avatar
Luc Trudeau committed
165
#if CONFIG_CFL
166
static int read_cfl_alphas(FRAME_CONTEXT *const ec_ctx, aom_reader *r,
167
                           CFL_SIGN_TYPE signs_out[CFL_PRED_PLANES]) {
168
169
170
171
172
173
174
175
176
177
178
179
180
  const int ind =
      aom_read_symbol(r, ec_ctx->cfl_alpha_cdf, CFL_ALPHABET_SIZE, "cfl:alpha");
  // Signs are only coded for nonzero values
  // sign == 0 implies negative alpha
  // sign == 1 implies positive alpha
  signs_out[CFL_PRED_U] = cfl_alpha_codes[ind][CFL_PRED_U]
                              ? aom_read_bit(r, "cfl:sign")
                              : CFL_SIGN_POS;
  signs_out[CFL_PRED_V] = cfl_alpha_codes[ind][CFL_PRED_V]
                              ? aom_read_bit(r, "cfl:sign")
                              : CFL_SIGN_POS;

  return ind;
Luc Trudeau's avatar
Luc Trudeau committed
181
182
183
}
#endif

184
#if CONFIG_EXT_INTER && CONFIG_INTERINTRA
Yaowu Xu's avatar
Yaowu Xu committed
185
186
static INTERINTRA_MODE read_interintra_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                            aom_reader *r, int size_group) {
187
188
189
190
  (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);
191
  FRAME_COUNTS *counts = xd->counts;
192
  if (counts) ++counts->interintra_mode[size_group][ii_mode];
193
194
  return ii_mode;
}
195
#endif  // CONFIG_EXT_INTER && CONFIG_INTERINTRA
196

197
static PREDICTION_MODE read_inter_mode(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
198
                                       aom_reader *r, int16_t ctx) {
199
  FRAME_COUNTS *counts = xd->counts;
200
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
201
202
203
204
205
206
  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
207

208
  if (is_newmv) {
209
    if (counts) ++counts->newmv_mode[mode_ctx][0];
210
    return NEWMV;
211
  }
212
  if (counts) ++counts->newmv_mode[mode_ctx][1];
213

214
  if (ctx & (1 << ALL_ZERO_FLAG_OFFSET)) return ZEROMV;
215

216
  mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
217

218
219
220
221
222
223
224
#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) {
225
    if (counts) ++counts->zeromv_mode[mode_ctx][0];
226
227
    return ZEROMV;
  }
228
  if (counts) ++counts->zeromv_mode[mode_ctx][1];
229

230
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
231

232
233
234
  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;
235

236
237
238
239
240
#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
241

242
  if (is_refmv) {
243
    if (counts) ++counts->refmv_mode[mode_ctx][0];
244

245
246
    return NEARESTMV;
  } else {
247
    if (counts) ++counts->refmv_mode[mode_ctx][1];
248
249
250
251
252
    return NEARMV;
  }

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

255
static void read_drl_idx(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
256
257
                         MB_MODE_INFO *mbmi, aom_reader *r) {
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
258
259
  mbmi->ref_mv_idx = 0;

260
#if CONFIG_EXT_INTER
261
262
263
264
#if CONFIG_COMPOUND_SINGLEREF
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV ||
      mbmi->mode == SR_NEW_NEWMV) {
#else   // !CONFIG_COMPOUND_SINGLEREF
265
  if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
266
267
#endif  // CONFIG_COMPOUND_SINGLEREF
#else   // !CONFIG_EXT_INTER
268
  if (mbmi->mode == NEWMV) {
269
#endif  // CONFIG_EXT_INTER
270
271
272
    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
273
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
274
275
276
277
278
279
280
281
#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;
282
283
284
285
      }
    }
  }

David Barker's avatar
David Barker committed
286
  if (have_nearmv_in_inter_mode(mbmi->mode)) {
287
288
289
290
291
292
    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
293
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
294
295
296
297
298
299
300
301
#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;
302
303
304
305
306
      }
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
307
308
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
309
310
                                    MODE_INFO *mi, aom_reader *r) {
  MB_MODE_INFO *mbmi = &mi->mbmi;
Thomas Davies's avatar
Thomas Davies committed
311
312
313
314
#if CONFIG_NEW_MULTISYMBOL
  (void)cm;
#endif

315
316
317
#if CONFIG_NCOBMC_ADAPT_WEIGHT
  const MOTION_MODE last_motion_mode_allowed =
      motion_mode_allowed_wrapper(0,
318
#if CONFIG_GLOBAL_MOTION
319
                                  0, xd->global_motion,
320
#endif  // CONFIG_GLOBAL_MOTION
321
322
323
#if CONFIG_WARPED_MOTION
                                  xd,
#endif
324
325
                                  mi);
#else
326
  const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
327
#if CONFIG_GLOBAL_MOTION
328
      0, xd->global_motion,
329
#endif  // CONFIG_GLOBAL_MOTION
330
331
332
#if CONFIG_WARPED_MOTION
      xd,
#endif
333
      mi);
334
#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
Yue Chen's avatar
Yue Chen committed
335
336
  int motion_mode;
  FRAME_COUNTS *counts = xd->counts;
Yaowu Xu's avatar
Yaowu Xu committed
337

Yue Chen's avatar
Yue Chen committed
338
339
340
  if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return SIMPLE_TRANSLATION;
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
  if (last_motion_mode_allowed == OBMC_CAUSAL) {
341
342
343
344
#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
345
    motion_mode = aom_read(r, cm->fc->obmc_prob[mbmi->sb_type], ACCT_STR);
346
#endif
Yue Chen's avatar
Yue Chen committed
347
348
349
350
    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
351
    motion_mode =
Thomas Davies's avatar
Thomas Davies committed
352
353
        aom_read_symbol(r, xd->tile_ctx->motion_mode_cdf[mbmi->sb_type],
                        MOTION_MODES, ACCT_STR);
Yaowu Xu's avatar
Yaowu Xu committed
354
355
    if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
Yue Chen's avatar
Yue Chen committed
356
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
357
  }
Yue Chen's avatar
Yue Chen committed
358
#endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
Yaowu Xu's avatar
Yaowu Xu committed
359
}
360
361

#if CONFIG_NCOBMC_ADAPT_WEIGHT
362
363
364
365
366
367
368
static void read_ncobmc_mode(MACROBLOCKD *xd, MODE_INFO *mi,
#ifndef TRAINING_WEIGHTS
                             NCOBMC_MODE ncobmc_mode[2],
#else
                             NCOBMC_MODE ncobmc_mode[][4],
#endif
                             aom_reader *r) {
369
370
371
  MB_MODE_INFO *mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
  ADAPT_OVERLAP_BLOCK ao_block = adapt_overlap_block_lookup[mbmi->sb_type];
372
  if (mbmi->motion_mode != NCOBMC_ADAPT_WEIGHT) return;
373

374
375
376
#ifndef TRAINING_WEIGHTS
  ncobmc_mode[0] = aom_read_symbol(r, xd->tile_ctx->ncobmc_mode_cdf[ao_block],
                                   MAX_NCOBMC_MODES, ACCT_STR);
377
378
379
  if (counts) ++counts->ncobmc_mode[ao_block][ncobmc_mode[0]];

  if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
380
381
    ncobmc_mode[1] = aom_read_symbol(r, xd->tile_ctx->ncobmc_mode_cdf[ao_block],
                                     MAX_NCOBMC_MODES, ACCT_STR);
382
383
    if (counts) ++counts->ncobmc_mode[ao_block][ncobmc_mode[1]];
  }
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
#else
  int i;
  for (i = 0; i < 4; ++i) {
    ncobmc_mode[0][i] = aom_read_symbol(
        r, xd->tile_ctx->ncobmc_mode_cdf[ao_block], MAX_NCOBMC_MODES, ACCT_STR);
    if (counts) ++counts->ncobmc_mode[ao_block][ncobmc_mode[0][i]];
  }
  if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
    for (i = 0; i < 4; ++i) {
      ncobmc_mode[1][i] =
          aom_read_symbol(r, xd->tile_ctx->ncobmc_mode_cdf[ao_block],
                          MAX_NCOBMC_MODES, ACCT_STR);
      if (counts) ++counts->ncobmc_mode[ao_block][ncobmc_mode[1][i]];
    }
  }
#endif
400
401
}
#endif
Yaowu Xu's avatar
Yaowu Xu committed
402
403
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION

404
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
405
406
static PREDICTION_MODE read_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                                aom_reader *r, int16_t ctx) {
407
408
409
410
  (void)cm;
  const int mode =
      aom_read_symbol(r, xd->tile_ctx->inter_compound_mode_cdf[ctx],
                      INTER_COMPOUND_MODES, ACCT_STR);
411
412
  FRAME_COUNTS *counts = xd->counts;

413
  if (counts) ++counts->inter_compound_mode[ctx][mode];
414
415
416
417

  assert(is_inter_compound_mode(NEAREST_NEARESTMV + mode));
  return NEAREST_NEARESTMV + mode;
}
418
419

#if CONFIG_COMPOUND_SINGLEREF
420
static PREDICTION_MODE read_inter_singleref_comp_mode(MACROBLOCKD *xd,
421
422
423
                                                      aom_reader *r,
                                                      int16_t ctx) {
  const int mode =
424
425
      aom_read_symbol(r, xd->tile_ctx->inter_singleref_comp_mode_cdf[ctx],
                      INTER_SINGLEREF_COMP_MODES, ACCT_STR);
426
427
428
429
430
431
432
433
  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
434
435
#endif  // CONFIG_EXT_INTER

436
static int read_segment_id(aom_reader *r, struct segmentation_probs *segp) {
Michael Bebenita's avatar
Michael Bebenita committed
437
  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
Jingning Han's avatar
Jingning Han committed
438
439
}

440
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
441
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
442
                               MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
443
444
                               TX_SIZE tx_size, int depth, int blk_row,
                               int blk_col, aom_reader *r) {
445
446
447
448
#if CONFIG_NEW_MULTISYMBOL
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
#endif
449
  int is_split = 0;
450
451
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
452
453
  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);
454
455
  int ctx = txfm_partition_context(xd->above_txfm_context + blk_col,
                                   xd->left_txfm_context + blk_row,
456
                                   mbmi->sb_type, tx_size);
clang-format's avatar
clang-format committed
457
  TX_SIZE(*const inter_tx_size)
458
459
460
  [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;
461

Jingning Han's avatar
Jingning Han committed
462
  if (depth == MAX_VARTX_DEPTH) {
463
464
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
465
466
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
467
468
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
469
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
470
    if (counts) ++counts->txfm_partition[ctx][0];
471
472
    txfm_partition_update(xd->above_txfm_context + blk_col,
                          xd->left_txfm_context + blk_row, tx_size, tx_size);
473
474
475
    return;
  }

476
477
478
#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
479
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
480
#endif
481
482

  if (is_split) {
483
484
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
485
    int i;
486

487
    if (counts) ++counts->txfm_partition[ctx][1];
488

489
    if (tx_size == TX_8X8) {
490
      int idx, idy;
491
      inter_tx_size[0][0] = sub_txs;
492
493
      for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
        for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
494
          inter_tx_size[idy][idx] = inter_tx_size[0][0];
495
      mbmi->tx_size = sub_txs;
496
      mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
497
498
      txfm_partition_update(xd->above_txfm_context + blk_col,
                            xd->left_txfm_context + blk_row, sub_txs, tx_size);
499
500
501
502
503
      return;
    }

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
504
505
506
      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,
507
                         offsetc, r);
508
509
    }
  } else {
510
    int idx, idy;
511
    inter_tx_size[0][0] = tx_size;
512
513
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
514
515
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
516
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
517
    if (counts) ++counts->txfm_partition[ctx][0];
518
519
    txfm_partition_update(xd->above_txfm_context + blk_col,
                          xd->left_txfm_context + blk_row, tx_size, tx_size);
520
521
522
523
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
524
525
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
526
527
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
528
529
530
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;

531
532
  const int depth = aom_read_symbol(r, ec_ctx->tx_size_cdf[tx_size_cat][ctx],
                                    tx_size_cat + 2, ACCT_STR);
533
534
535
536
  const TX_SIZE tx_size = depth_to_tx_size(depth);
#if CONFIG_RECT_TX
  assert(!is_rect_tx(tx_size));
#endif  // CONFIG_RECT_TX
537
  if (counts) ++counts->tx_size[tx_size_cat][ctx][depth];
538
  return tx_size;
Jingning Han's avatar
Jingning Han committed
539
540
}

541
542
543
544
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;
545
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
546
#if CONFIG_CB4X4 && (CONFIG_VAR_TX || CONFIG_EXT_TX) && CONFIG_RECT_TX
547
  if (bsize > BLOCK_4X4) {
548
#else
549
  if (bsize >= BLOCK_8X8) {
550
551
552
553
#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];
554
      const TX_SIZE coded_tx_size =
555
          read_selected_tx_size(cm, xd, tx_size_cat, r);
556
#if CONFIG_RECT_TX && (CONFIG_EXT_TX || CONFIG_VAR_TX)
557
558
      if (coded_tx_size > max_txsize_lookup[bsize]) {
        assert(coded_tx_size == max_txsize_lookup[bsize] + 1);
559
#if CONFIG_EXT_TX && CONFIG_RECT_TX_EXT
560
561
562
563
564
565
566
567
        if (is_quarter_tx_allowed(xd, &xd->mi[0]->mbmi, is_inter)) {
          int 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];
          return quarter_tx ? quarter_txsize_lookup[bsize]
                            : max_txsize_rect_lookup[bsize];
        }
568
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX_EXT
569

570
571
        return max_txsize_rect_lookup[bsize];
      }
572
573
#else
      assert(coded_tx_size <= max_txsize_lookup[bsize]);
574
#endif  // CONFIG_RECT_TX && (CONFIG_EXT_TX || CONFIG_VAR_TX)
575
      return coded_tx_size;
576
    } else {
577
      return tx_size_from_tx_mode(bsize, tx_mode, is_inter);
578
579
    }
  } else {
580
#if CONFIG_EXT_TX && CONFIG_RECT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
581
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
582
583
584
    return max_txsize_rect_lookup[bsize];
#else
    return TX_4X4;
585
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX
586
  }
Jingning Han's avatar
Jingning Han committed
587
588
}

Yaowu Xu's avatar
Yaowu Xu committed
589
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
590
591
592
593
594
                              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++)
595
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
596
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
597
598
599
600
601

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

Yaowu Xu's avatar
Yaowu Xu committed
602
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
603
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
604
605
606
607
608
609
610
611
612
  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
613
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
614
                                 int mi_offset, int x_mis, int y_mis,
Yaowu Xu's avatar
Yaowu Xu committed
615
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
616
  struct segmentation *const seg = &cm->seg;
617
  FRAME_COUNTS *counts = xd->counts;
618
619
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  struct segmentation_probs *const segp = &ec_ctx->seg;
Jingning Han's avatar
Jingning Han committed
620
621
  int segment_id;

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

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

626
  segment_id = read_segment_id(r, segp);
627
  if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
628
629
630
631
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
632
static void copy_segment_id(const AV1_COMMON *cm,
633
634
635
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
636
637
638
639
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
640
641
642
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
643
644
}

Yaowu Xu's avatar
Yaowu Xu committed
645
646
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
647
  struct segmentation *const seg = &cm->seg;
648
  FRAME_COUNTS *counts = xd->counts;
649
650
651
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  struct segmentation_probs *const segp = &ec_ctx->seg;

Jingning Han's avatar
Jingning Han committed
652
653
654
  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;
655
656
  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
657
658

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

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

664
665
666
667
  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
668
669
670
671
672
673
674
675

  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
676
    const int ctx = av1_get_pred_context_seg_id(xd);
677
678
679
680
#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
681
    const aom_prob pred_prob = segp->pred_probs[ctx];
Michael Bebenita's avatar
Michael Bebenita committed
682
    mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
683
#endif
684
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
685
686
687
688
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
689
      if (counts) ++counts->seg.tree_mispred[segment_id];
690
    }
Jingning Han's avatar
Jingning Han committed
691
  } else {
692
    segment_id = read_segment_id(r, segp);
693
    if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
694
695
696
697
698
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
699
700
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
701
702
703
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
704
    const int ctx = av1_get_skip_context(xd);
705
706
707
708
#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
709
    const int skip = aom_read(r, cm->fc->skip_probs[ctx], ACCT_STR);
710
#endif
Jingning Han's avatar
Jingning Han committed
711
    FRAME_COUNTS *counts = xd->counts;
712
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
713
714
715
716
    return skip;
  }
}

717
#if CONFIG_PALETTE
718
719
#if CONFIG_PALETTE_DELTA_ENCODING
static int uint16_compare(const void *a, const void *b) {
720
721
  const uint16_t va = *(const uint16_t *)a;
  const uint16_t vb = *(const uint16_t *)b;
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
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
801
802
803
804
  return va - vb;
}

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];
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const int n_cache = av1_get_palette_cache(above_mi, left_mi, 0, color_cache);
  const int n = pmi->palette_size[0];
  int idx = 0;
  for (int i = 0; i < n_cache && idx < n; ++i)
    if (aom_read_bit(r, ACCT_STR)) pmi->palette_colors[idx++] = color_cache[i];
  if (idx < n) {
    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) {
        const int delta = aom_read_literal(r, bits, ACCT_STR) + 1;
        pmi->palette_colors[idx] = pmi->palette_colors[idx - 1] + delta;
        range -= delta;
        bits = AOMMIN(bits, av1_ceil_log2(range));
      }
    }
  }
  qsort(pmi->palette_colors, n, sizeof(pmi->palette_colors[0]), uint16_compare);
}

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];
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi = xd->left_mi;
  const int n_cache = av1_get_palette_cache(above_mi, left_mi, 1, color_cache);
  int idx = PALETTE_MAX_SIZE;
  for (int i = 0; i < n_cache && idx < PALETTE_MAX_SIZE + n; ++i)
    if (aom_read_bit(r, ACCT_STR)) pmi->palette_colors[idx++] = color_cache[i];
  if (idx < PALETTE_MAX_SIZE + n) {
    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) {
        const int delta = aom_read_literal(r, bits, ACCT_STR);
        pmi->palette_colors[idx] = pmi->palette_colors[idx - 1] + delta;
        range -= delta;
        bits = AOMMIN(bits, av1_ceil_log2(range));
      }
    }
  }
  qsort(pmi->palette_colors + PALETTE_MAX_SIZE, n,
        sizeof(pmi->palette_colors[0]), uint16_compare);

  // 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
805
806
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                   aom_reader *r) {
hui su's avatar
hui su committed
807
808
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
809
  const MODE_INFO *const above_mi = xd->above_mi;
810
  const MODE_INFO *const left_mi = xd->left_mi;
hui su's avatar
hui su committed
811
  const BLOCK_SIZE bsize = mbmi->sb_type;
812
  int n;
813
814
815
  PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;

  if (mbmi->mode == DC_PRED) {
816
    int palette_y_mode_ctx = 0;
817
    if (above_mi)
818
819
      palette_y_mode_ctx +=
          (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
820
    if (left_mi)
821
822
823
824
825
      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)) {
826
      pmi->palette_size[0] =
827
828
829
830
831
832
#if CONFIG_NEW_MULTISYMBOL
          aom_read_symbol(r,
                          xd->tile_ctx->palette_y_size_cdf[bsize - BLOCK_8X8],
                          PALETTE_SIZES, ACCT_STR) +
          2;
#else
Yaowu Xu's avatar
Yaowu Xu committed
833
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
834
835
                        av1_default_palette_y_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
836
          2;
837
#endif
838
      n = pmi->palette_size[0];
hui su's avatar
hui su committed
839
#if CONFIG_PALETTE_DELTA_ENCODING
840
      read_palette_colors_y(xd, cm->bit_depth, pmi, r);
hui su's avatar
hui su committed
841
#else
842
      int i;
843
      for (i = 0; i < n; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
844
        pmi->palette_colors[i] = aom_read_literal(r, cm->bit_depth, ACCT_STR);
hui su's avatar
hui su committed
845
#endif  // CONFIG_PALETTE_DELTA_ENCODING
846
847
848
849
      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
850

851
  if (mbmi->uv_mode == DC_PRED) {
852
853
    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
854
                 ACCT_STR)) {
855
      pmi->palette_size[1] =
856
857
858
859
860
861
#if CONFIG_NEW_MULTISYMBOL
          aom_read_symbol(r,
                          xd->tile_ctx->palette_uv_size_cdf[bsize - BLOCK_8X8],
                          PALETTE_SIZES, ACCT_STR) +
          2;
#else
Yaowu Xu's avatar
Yaowu Xu committed
862
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
863
864
                        av1_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
865
          2;
866
#endif
867
      n = pmi->palette_size[1];
hui su's avatar
hui su committed
868
#if CONFIG_PALETTE_DELTA_ENCODING
869
      read_palette_colors_uv(xd, cm->bit_depth, pmi, r);
hui su's avatar
hui su committed
870
#else
871
      int i;
872
873
      for (i = 0; i < n; ++i) {
        pmi->palette_colors[PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
874
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
875
        pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
876
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
877
      }
hui su's avatar
hui su committed
878
#endif  // CONFIG_PALETTE_DELTA_ENCODING
879
880
881
      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
882
883
  }
}
884
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
885

886
887
#if CONFIG_FILTER_INTRA
static void read_filter_intra_mode_info(AV1_COMMON *const cm,
888
889
                                        MACROBLOCKD *const xd, int mi_row,
                                        int mi_col, aom_reader *r) {
hui su's avatar
hui su committed
890
891
892
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
893
894
  FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
      &mbmi->filter_intra_mode_info;
hui su's avatar
hui su committed
895

896
897
898
899
900
  if (mbmi->mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[0] == 0
#endif  // CONFIG_PALETTE
      ) {
901
902
903
904
    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
905
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
906
    }
907
    if (counts) {
clang-format's avatar
clang-format committed
908
909
      ++counts
            ->filter_intra[0][filter_intra_mode_info->use_filter_intra_mode[0]];
910
    }
hui su's avatar
hui su committed
911
  }
912
913
914
915
916
917

#if CONFIG_CB4X4
  if (!is_chroma_reference(mi_row, mi_col, mbmi->sb_type,
                           xd->plane[1].subsampling_x,
                           xd->plane[1].subsampling_y))
    return;
918
919
920
921
#else
  (void)mi_row;
  (void)mi_col;
#endif  // CONFIG_CB4X4
922

923
924
925
926
927
  if (mbmi->uv_mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[1] == 0
#endif  // CONFIG_PALETTE
      ) {
928
929
930
931
    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
932
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
933
    }
934
    if (counts) {
clang-format's avatar
clang-format committed
935
936
      ++counts
            ->filter_intra[1][filter_intra_mode_info->use_filter_intra_mode[1]];
937
    }
hui su's avatar
hui su committed
938
939
  }
}
940
#endif  // CONFIG_FILTER_INTRA
941

942
#if CONFIG_EXT_INTRA
Yaowu Xu's avatar
Yaowu Xu committed
943
944
static void read_intra_angle_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  aom_reader *r) {
945
946
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
hui su's avatar
hui su committed
947
#if CONFIG_INTRA_INTERP
948
  FRAME_CONTEXT *const ec_ctx = xd->tile_ctx;
Yaowu Xu's avatar
Yaowu Xu committed
949
  const int ctx = av1_get_pred_context_intra_interp(xd);
950
  int p_angle;
hui su's avatar
hui su committed
951
#endif  // CONFIG_INTRA_INTERP
952

hui su's avatar
hui su committed
953
  (void)cm;
954
955
956
957
958

  mbmi->angle_delta[0] = 0;
  mbmi->angle_delta[1] = 0;

  if (!av1_use_angle_delta(bsize)) return;
959

hui su's avatar
hui su committed
960
  if (av1_is_directional_mode(mbmi->mode, bsize)) {
961
    mbmi->angle_delta[0] =
hui su's avatar
hui su committed
962
        read_uniform(r, 2 * MAX_ANGLE_DELTA + 1) - MAX_ANGLE_DELTA;
hui su's avatar
hui su committed
963
#if CONFIG_INTRA_INTERP
hui su's avatar
hui su committed
964
    p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xu's avatar
Yaowu Xu committed
965
    if (av1_is_intra_filter_switchable(p_angle)) {
966
      FRAME_COUNTS *counts = xd->counts;
967
968
      mbmi->intra_filter = aom_read_symbol(r, ec_ctx->intra_filter_cdf[ctx],
                                           INTRA_FILTERS