decodemv.c 82.1 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
#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

Yaowu Xu's avatar
Yaowu Xu committed
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) {
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
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);
Thomas Davies's avatar
Thomas Davies committed
83
84
  FRAME_CONTEXT *ec_ctx = xd->tile_ctx;
  (void)cm;
85

Pavel Frolov's avatar
Pavel Frolov committed
86
  if ((bsize != cm->sb_size || mbmi->skip == 0) && read_delta_q_flag) {
Thomas Davies's avatar
Thomas Davies committed
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);
Thomas Davies's avatar
Thomas Davies committed
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;
}
Fangwen Fu's avatar
Fangwen Fu committed
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
Fangwen Fu's avatar
Fangwen Fu committed
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);
Fangwen Fu's avatar
Fangwen Fu committed
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
Fangwen Fu's avatar
Fangwen Fu committed
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);
Fangwen Fu's avatar
Fangwen Fu committed
136
    if (!smallval) {
137
138
      const int rem_bits = aom_read_literal(r, 3, ACCT_STR) + 1;
      const int thr = (1 << rem_bits) + 1;
Fangwen Fu's avatar
Fangwen Fu committed
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
Jingning Han's avatar
Jingning Han committed
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;
}

Yunqing Wang's avatar
Yunqing Wang committed
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;
Yunqing Wang's avatar
Yunqing Wang committed
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;
Yunqing Wang's avatar
Yunqing Wang committed
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;
Yunqing Wang's avatar
Yunqing Wang committed
216
  if (is_refmv)
217
    return NEARESTMV;
Yunqing Wang's avatar
Yunqing Wang committed
218
  else
219
    return NEARMV;
Jingning Han's avatar
Jingning Han committed
220
221
}

222
static void read_drl_idx(FRAME_CONTEXT *ec_ctx, MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
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) {
Yaowu Xu's avatar
Yaowu Xu committed
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
      }
    }
  }
David Barker's avatar
David Barker committed
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) {
Yaowu Xu's avatar
Yaowu Xu committed
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;
Thomas Davies's avatar
Thomas Davies committed
254

Zoe Liu's avatar
Zoe Liu committed
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 =
Luc Trudeau's avatar
Luc Trudeau committed
260
      motion_mode_allowed(xd->global_motion, xd, mi);
Yue Chen's avatar
Yue Chen committed
261
  int motion_mode;
Yaowu Xu's avatar
Yaowu Xu committed
262

Yue Chen's avatar
Yue Chen committed
263
  if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return SIMPLE_TRANSLATION;
Yue Chen's avatar
Yue Chen committed
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 {
Yaowu Xu's avatar
Yaowu Xu committed
270
    motion_mode =
Thomas Davies's avatar
Thomas Davies committed
271
272
        aom_read_symbol(r, xd->tile_ctx->motion_mode_cdf[mbmi->sb_type],
                        MOTION_MODES, ACCT_STR);
Yaowu Xu's avatar
Yaowu Xu committed
273
274
275
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  }
}
276

Yaowu Xu's avatar
Yaowu Xu committed
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

Yaowu Xu's avatar
Yaowu Xu committed
350
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
Yunqing Wang's avatar
Yunqing Wang committed
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;
David Barker's avatar
David Barker committed
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

David Barker's avatar
David Barker committed
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;
Yunqing Wang's avatar
Yunqing Wang committed
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
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
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;
Jingning Han's avatar
Jingning Han committed
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 {
Debargha Mukherjee's avatar
Debargha Mukherjee committed
456
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
457
    return get_max_rect_tx_size(bsize, is_inter);
458
  }
Jingning Han's avatar
Jingning Han committed
459
460
}

Yaowu Xu's avatar
Yaowu Xu committed
461
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
462
                              int mi_offset, int x_mis, int y_mis) {
463
  int segment_id = INT_MAX;
Jingning Han's avatar
Jingning Han committed
464

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

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

Yaowu Xu's avatar
Yaowu Xu committed
474
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
475
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
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++)
Jingning Han's avatar
Jingning Han committed
480
481
482
      cm->current_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
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) {
Jingning Han's avatar
Jingning Han committed
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);
Jingning Han's avatar
Jingning Han committed
492

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

495
  assert(seg->update_map && !seg->temporal_update);
Jingning Han's avatar
Jingning Han committed
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
Jingning Han's avatar
Jingning Han committed
504
505
506
507
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
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
}

Yaowu Xu's avatar
Yaowu Xu committed
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) {
Jingning Han's avatar
Jingning Han committed
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;

Jingning Han's avatar
Jingning Han committed
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];
Jingning Han's avatar
Jingning Han committed
531
532

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

536
  if (!seg->enabled) return 0;  // Default for disabled segmentation
Jingning Han's avatar
Jingning Han committed
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;
Jingning Han's avatar
Jingning Han committed
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;
Jingning Han's avatar
Jingning Han committed
565
  if (seg->temporal_update) {
Yaowu Xu's avatar
Yaowu Xu committed
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
    }
Jingning Han's avatar
Jingning Han committed
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
Jingning Han's avatar
Jingning Han committed
584
585
586
587
588
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Zoe Liu's avatar
Zoe Liu committed
589
590
591
#if CONFIG_EXT_SKIP
static int read_skip_mode(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                          aom_reader *r) {
Zoe Liu's avatar
Zoe Liu committed
592
  if (!cm->skip_mode_flag) return 0;
Zoe Liu's avatar
Zoe Liu committed
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;
  }
Zoe Liu's avatar
Zoe Liu committed
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;
Zoe Liu's avatar
Zoe Liu committed
606
607
608
}
#endif  // CONFIG_EXT_SKIP

Yaowu Xu's avatar
Yaowu Xu committed
609
610
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
611
612
613
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
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);
Jingning Han's avatar
Jingning Han committed
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);
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
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;
Hui Su's avatar
Hui Su committed
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,
Hui Su's avatar
Hui Su committed
741
        ACCT_STR);
742
    if (modev) {
743
      pmi->palette_size[0] =
Hui Su's avatar
Hui Su committed
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] =
Hui Su's avatar
Hui Su committed
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

Joe Young's avatar
Joe Young committed
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

Hui Su's avatar
Hui Su committed
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;
Joe Young's avatar
Joe Young committed
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)) {
Joe Young's avatar
Joe Young committed
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;
Joe Young's avatar
Joe Young committed
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)) {
Joe Young's avatar
Joe Young committed
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;
Joe Young's avatar
Joe Young committed
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
Luc Trudeau's avatar
Luc Trudeau committed
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 {
Yue Chen's avatar
Yue Chen committed
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)];
Yue Chen's avatar
Yue Chen committed
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)];
Yue Chen's avatar
Yue Chen committed
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
  }
}

Alex Converse's avatar
Alex Converse committed
889
890
#if CONFIG_INTRABC
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
891
                           nmv_context *ctx, MvSubpelPrecision precision);
Alex Converse's avatar
Alex Converse committed
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);
Hui Su's avatar
Hui Su committed
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;
Alex Converse's avatar
Alex Converse committed
905
  int valid = is_mv_valid(&mv->as_mv) &&
Hui Su's avatar
Hui Su committed
906
907
              av1_is_dv_valid(mv->as_mv, &xd->tile, mi_row, mi_col, bsize,
                              cm->mib_size_log2);
Alex Converse's avatar
Alex Converse committed
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) {
Yunqing Wang's avatar
Yunqing Wang committed
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);
Hui Su's avatar
Hui Su committed
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;