decodemv.c 69 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
21
22
23
#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"
#include "av1/common/seg_common.h"

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

Yaowu Xu's avatar
Yaowu Xu committed
26
#include "aom_dsp/aom_dsp_common.h"
27

Michael Bebenita's avatar
Michael Bebenita committed
28
#define ACCT_STR __func__
29
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
30
static INLINE int read_uniform(aom_reader *r, int n) {
hui su's avatar
hui su committed
31
32
  int l = get_unsigned_bits(n);
  int m = (1 << l) - n;
Michael Bebenita's avatar
Michael Bebenita committed
33
  int v = aom_read_literal(r, l - 1, ACCT_STR);
hui su's avatar
hui su committed
34
35
36
37
38
39

  assert(l != 0);

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

44
#if CONFIG_DAALA_EC
45
static PREDICTION_MODE read_intra_mode(aom_reader *r, aom_cdf_prob *cdf) {
46
47
48
  return (PREDICTION_MODE)
      av1_intra_mode_inv[aom_read_symbol(r, cdf, INTRA_MODES, ACCT_STR)];
}
49
#else
Yaowu Xu's avatar
Yaowu Xu committed
50
static PREDICTION_MODE read_intra_mode(aom_reader *r, const aom_prob *p) {
Michael Bebenita's avatar
Michael Bebenita committed
51
  return (PREDICTION_MODE)aom_read_tree(r, av1_intra_mode_tree, p, ACCT_STR);
Jingning Han's avatar
Jingning Han committed
52
}
53
#endif
Jingning Han's avatar
Jingning Han committed
54

55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#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);
  int rem_bits, thr, bit = 1;

  if ((bsize != BLOCK_64X64 || mbmi->skip == 0) && read_delta_q_flag) {
    abs = 0;
    while (abs < DELTA_Q_SMALL && bit) {
      bit = aom_read(r, cm->fc->delta_q_prob[abs], ACCT_STR);
      if (counts) counts->delta_q[abs][bit]++;
      abs += bit;
    }
    if (abs == DELTA_Q_SMALL) {
      rem_bits = aom_read_literal(r, 3, ACCT_STR);
      thr = (1 << rem_bits) + 1;
      abs = aom_read_literal(r, rem_bits, ACCT_STR) + thr;
    }

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

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

Yaowu Xu's avatar
Yaowu Xu committed
91
92
static PREDICTION_MODE read_intra_mode_y(AV1_COMMON *cm, MACROBLOCKD *xd,
                                         aom_reader *r, int size_group) {
Jingning Han's avatar
Jingning Han committed
93
  const PREDICTION_MODE y_mode =
94
#if CONFIG_DAALA_EC
95
      read_intra_mode(r, cm->fc->y_mode_cdf[size_group]);
96
#else
Jingning Han's avatar
Jingning Han committed
97
      read_intra_mode(r, cm->fc->y_mode_prob[size_group]);
98
#endif
Jingning Han's avatar
Jingning Han committed
99
  FRAME_COUNTS *counts = xd->counts;
100
  if (counts) ++counts->y_mode[size_group][y_mode];
Jingning Han's avatar
Jingning Han committed
101
102
103
  return y_mode;
}

Yaowu Xu's avatar
Yaowu Xu committed
104
105
static PREDICTION_MODE read_intra_mode_uv(AV1_COMMON *cm, MACROBLOCKD *xd,
                                          aom_reader *r,
Jingning Han's avatar
Jingning Han committed
106
                                          PREDICTION_MODE y_mode) {
107
  const PREDICTION_MODE uv_mode =
108
109
110
#if CONFIG_DAALA_EC
      read_intra_mode(r, cm->fc->uv_mode_cdf[y_mode]);
#else
111
      read_intra_mode(r, cm->fc->uv_mode_prob[y_mode]);
112
#endif
Jingning Han's avatar
Jingning Han committed
113
  FRAME_COUNTS *counts = xd->counts;
114
  if (counts) ++counts->uv_mode[y_mode][uv_mode];
Jingning Han's avatar
Jingning Han committed
115
116
117
  return uv_mode;
}

118
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
119
120
121
static INTERINTRA_MODE read_interintra_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                            aom_reader *r, int size_group) {
  const INTERINTRA_MODE ii_mode = (INTERINTRA_MODE)aom_read_tree(
Michael Bebenita's avatar
Michael Bebenita committed
122
123
      r, av1_interintra_mode_tree, cm->fc->interintra_mode_prob[size_group],
      ACCT_STR);
124
  FRAME_COUNTS *counts = xd->counts;
125
  if (counts) ++counts->interintra_mode[size_group][ii_mode];
126
127
128
129
  return ii_mode;
}
#endif  // CONFIG_EXT_INTER

Yaowu Xu's avatar
Yaowu Xu committed
130
static PREDICTION_MODE read_inter_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
Yue Chen's avatar
Yue Chen committed
131
132
133
#if CONFIG_REF_MV && CONFIG_EXT_INTER
                                       MB_MODE_INFO *mbmi,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
134
                                       aom_reader *r, int16_t ctx) {
135
136
#if CONFIG_REF_MV
  FRAME_COUNTS *counts = xd->counts;
137
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
Yaowu Xu's avatar
Yaowu Xu committed
138
  aom_prob mode_prob = cm->fc->newmv_prob[mode_ctx];
139

Michael Bebenita's avatar
Michael Bebenita committed
140
  if (aom_read(r, mode_prob, ACCT_STR) == 0) {
141
    if (counts) ++counts->newmv_mode[mode_ctx][0];
Yue Chen's avatar
Yue Chen committed
142
143
144
145

#if CONFIG_EXT_INTER
    if (has_second_ref(mbmi)) {
#endif  // CONFIG_EXT_INTER
146
      return NEWMV;
Yue Chen's avatar
Yue Chen committed
147
148
149
#if CONFIG_EXT_INTER
    } else {
      mode_prob = cm->fc->new2mv_prob;
Michael Bebenita's avatar
Michael Bebenita committed
150
      if (aom_read(r, mode_prob, ACCT_STR) == 0) {
151
        if (counts) ++counts->new2mv_mode[0];
Yue Chen's avatar
Yue Chen committed
152
153
        return NEWMV;
      } else {
154
        if (counts) ++counts->new2mv_mode[1];
Yue Chen's avatar
Yue Chen committed
155
156
157
158
        return NEWFROMNEARMV;
      }
    }
#endif  // CONFIG_EXT_INTER
159
  }
160
  if (counts) ++counts->newmv_mode[mode_ctx][1];
161

162
  if (ctx & (1 << ALL_ZERO_FLAG_OFFSET)) return ZEROMV;
163

164
  mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
165
166

  mode_prob = cm->fc->zeromv_prob[mode_ctx];
Michael Bebenita's avatar
Michael Bebenita committed
167
  if (aom_read(r, mode_prob, ACCT_STR) == 0) {
168
    if (counts) ++counts->zeromv_mode[mode_ctx][0];
169
170
    return ZEROMV;
  }
171
  if (counts) ++counts->zeromv_mode[mode_ctx][1];
172

173
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
174

175
176
177
  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;
178

179
  mode_prob = cm->fc->refmv_prob[mode_ctx];
180

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

184
185
    return NEARESTMV;
  } else {
186
    if (counts) ++counts->refmv_mode[mode_ctx][1];
187
188
189
190
191
    return NEARMV;
  }

  // Invalid prediction mode.
  assert(0);
192
193
194
195
#else
#if CONFIG_DAALA_EC
  const int mode = av1_inter_mode_inv[aom_read_symbol(
      r, cm->fc->inter_mode_cdf[ctx], INTER_MODES, ACCT_STR)];
196
#else
Michael Bebenita's avatar
Michael Bebenita committed
197
198
  const int mode = aom_read_tree(r, av1_inter_mode_tree,
                                 cm->fc->inter_mode_probs[ctx], ACCT_STR);
199
#endif
Jingning Han's avatar
Jingning Han committed
200
  FRAME_COUNTS *counts = xd->counts;
201
  if (counts) ++counts->inter_mode[ctx][mode];
Jingning Han's avatar
Jingning Han committed
202
203

  return NEARESTMV + mode;
204
#endif
Jingning Han's avatar
Jingning Han committed
205
206
}

207
#if CONFIG_REF_MV
Yaowu Xu's avatar
Yaowu Xu committed
208
209
210
static void read_drl_idx(const AV1_COMMON *cm, MACROBLOCKD *xd,
                         MB_MODE_INFO *mbmi, aom_reader *r) {
  uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
211
212
  mbmi->ref_mv_idx = 0;

213
214
215
216
  if (mbmi->mode == NEWMV) {
    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
217
218
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
Michael Bebenita's avatar
Michael Bebenita committed
219
        if (!aom_read(r, drl_prob, ACCT_STR)) {
220
          mbmi->ref_mv_idx = idx;
221
          if (xd->counts) ++xd->counts->drl_mode[drl_ctx][0];
222
223
224
          return;
        }
        mbmi->ref_mv_idx = idx + 1;
225
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][1];
226
227
228
229
      }
    }
  }

230
231
232
233
234
235
236
  if (mbmi->mode == NEARMV) {
    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
237
238
        uint8_t drl_ctx = av1_drl_ctx(xd->ref_mv_stack[ref_frame_type], idx);
        aom_prob drl_prob = cm->fc->drl_prob[drl_ctx];
Michael Bebenita's avatar
Michael Bebenita committed
239
        if (!aom_read(r, drl_prob, ACCT_STR)) {
240
          mbmi->ref_mv_idx = idx - 1;
241
          if (xd->counts) ++xd->counts->drl_mode[drl_ctx][0];
242
243
          return;
        }
244
        mbmi->ref_mv_idx = idx;
245
        if (xd->counts) ++xd->counts->drl_mode[drl_ctx][1];
246
247
248
249
250
251
      }
    }
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                    MB_MODE_INFO *mbmi, aom_reader *r) {
  if (is_motion_variation_allowed(mbmi)) {
    int motion_mode;
    FRAME_COUNTS *counts = xd->counts;

    motion_mode =
        aom_read_tree(r, av1_motion_mode_tree,
                      cm->fc->motion_mode_prob[mbmi->sb_type], ACCT_STR);
    if (counts) ++counts->motion_mode[mbmi->sb_type][motion_mode];
    return (MOTION_MODE)(SIMPLE_TRANSLATION + motion_mode);
  } else {
    return SIMPLE_TRANSLATION;
  }
}
#endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION

270
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
271
272
static PREDICTION_MODE read_inter_compound_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                                aom_reader *r, int16_t ctx) {
Michael Bebenita's avatar
Michael Bebenita committed
273
274
275
  const int mode =
      aom_read_tree(r, av1_inter_compound_mode_tree,
                    cm->fc->inter_compound_mode_probs[ctx], ACCT_STR);
276
277
  FRAME_COUNTS *counts = xd->counts;

278
  if (counts) ++counts->inter_compound_mode[ctx][mode];
279
280
281
282
283
284

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

285
static int read_segment_id(aom_reader *r, struct segmentation_probs *segp) {
286
#if CONFIG_DAALA_EC
Michael Bebenita's avatar
Michael Bebenita committed
287
  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
288
#else
Michael Bebenita's avatar
Michael Bebenita committed
289
  return aom_read_tree(r, av1_segment_tree, segp->tree_probs, ACCT_STR);
290
#endif
Jingning Han's avatar
Jingning Han committed
291
292
}

293
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
294
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
295
                               MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
296
297
                               TX_SIZE tx_size, int depth, int blk_row,
                               int blk_col, aom_reader *r) {
298
  int is_split = 0;
299
300
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
301
302
  int max_blocks_high = block_size_high[mbmi->sb_type];
  int max_blocks_wide = block_size_wide[mbmi->sb_type];
303
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
304
305
                                   xd->left_txfm_context + tx_row,
                                   mbmi->sb_type, tx_size);
clang-format's avatar
clang-format committed
306
  TX_SIZE(*const inter_tx_size)
307
308
  [MAX_MIB_SIZE] =
      (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
309

310
311
312
313
314
315
  if (xd->mb_to_bottom_edge < 0) max_blocks_high += xd->mb_to_bottom_edge >> 3;
  if (xd->mb_to_right_edge < 0) max_blocks_wide += xd->mb_to_right_edge >> 3;

  // Scale to transform block unit.
  max_blocks_high >>= tx_size_wide_log2[0];
  max_blocks_wide >>= tx_size_wide_log2[0];
316

317
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
318

Jingning Han's avatar
Jingning Han committed
319
  if (depth == MAX_VARTX_DEPTH) {
320
321
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
322
323
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
324
325
326
327
328
329
330
331
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
    if (counts) ++counts->txfm_partition[ctx][0];
    txfm_partition_update(xd->above_txfm_context + tx_col,
                          xd->left_txfm_context + tx_row, tx_size);
    return;
  }

Michael Bebenita's avatar
Michael Bebenita committed
332
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
333
334
335

  if (is_split) {
    BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
336
337
    // Half the block size in transform block unit.
    int bsl = block_size_wide[bsize] >> (tx_size_wide_log2[0] + 1);
338
    int i;
339

340
    if (counts) ++counts->txfm_partition[ctx][1];
341

342
    if (tx_size == TX_8X8) {
343
344
345
346
      inter_tx_size[0][0] = TX_4X4;
      mbmi->tx_size = TX_4X4;
      txfm_partition_update(xd->above_txfm_context + tx_col,
                            xd->left_txfm_context + tx_row, TX_4X4);
347
348
349
350
351
      return;
    }

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
352
353
      int offsetr = blk_row + ((i >> 1) * bsl);
      int offsetc = blk_col + ((i & 0x01) * bsl);
354
355
      read_tx_size_vartx(cm, xd, mbmi, counts, tx_size - 1, depth + 1, offsetr,
                         offsetc, r);
356
357
    }
  } else {
358
    int idx, idy;
359
    inter_tx_size[0][0] = tx_size;
360
361
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
362
363
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
364
    if (counts) ++counts->txfm_partition[ctx][0];
365
366
    txfm_partition_update(xd->above_txfm_context + tx_col,
                          xd->left_txfm_context + tx_row, tx_size);
367
368
369
370
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
371
372
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
373
374
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
375
376
377
  int depth = aom_read_tree(r, av1_tx_size_tree[tx_size_cat],
                            cm->fc->tx_size_probs[tx_size_cat][ctx], ACCT_STR);
  TX_SIZE tx_size = depth_to_tx_size(depth);
378
  if (counts) ++counts->tx_size[tx_size_cat][ctx][depth];
379
  return tx_size;
Jingning Han's avatar
Jingning Han committed
380
381
}

Yaowu Xu's avatar
Yaowu Xu committed
382
383
static TX_SIZE read_tx_size_intra(AV1_COMMON *cm, MACROBLOCKD *xd,
                                  aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
384
385
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
386
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
387
388
  if (bsize >= BLOCK_8X8) {
    if (tx_mode == TX_MODE_SELECT) {
389
390
391
392
      const TX_SIZE tx_size =
          read_selected_tx_size(cm, xd, intra_tx_size_cat_lookup[bsize], r);
      assert(tx_size <= max_txsize_lookup[bsize]);
      return tx_size;
393
    } else {
394
      return tx_size_from_tx_mode(bsize, cm->tx_mode, 0);
395
396
397
398
399
400
    }
  } else {
    return TX_4X4;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
401
402
static TX_SIZE read_tx_size_inter(AV1_COMMON *cm, MACROBLOCKD *xd,
                                  int allow_select, aom_reader *r) {
403
404
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
405
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
406
407
  if (bsize >= BLOCK_8X8) {
    if (allow_select && tx_mode == TX_MODE_SELECT) {
408
409
      const TX_SIZE coded_tx_size =
          read_selected_tx_size(cm, xd, inter_tx_size_cat_lookup[bsize], r);
410
#if CONFIG_EXT_TX && CONFIG_RECT_TX
411
412
413
414
      if (coded_tx_size > max_txsize_lookup[bsize]) {
        assert(coded_tx_size == max_txsize_lookup[bsize] + 1);
        return max_txsize_rect_lookup[bsize];
      }
415
416
417
#else
      assert(coded_tx_size <= max_txsize_lookup[bsize]);
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX
418
      return coded_tx_size;
419
    } else {
420
      return tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
421
422
    }
  } else {
423
#if CONFIG_EXT_TX && CONFIG_RECT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
424
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
425
426
427
    return max_txsize_rect_lookup[bsize];
#else
    return TX_4X4;
428
#endif
429
  }
Jingning Han's avatar
Jingning Han committed
430
431
}

Yaowu Xu's avatar
Yaowu Xu committed
432
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
433
434
435
436
437
                              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++)
438
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
439
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
440
441
442
443
444

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

Yaowu Xu's avatar
Yaowu Xu committed
445
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
446
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
447
448
449
450
451
452
453
454
455
  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
456
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
457
                                 int mi_offset, int x_mis, int y_mis,
Yaowu Xu's avatar
Yaowu Xu committed
458
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
459
  struct segmentation *const seg = &cm->seg;
460
461
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
462
463
  int segment_id;

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

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

468
  segment_id = read_segment_id(r, segp);
469
  if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
470
471
472
473
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
474
static void copy_segment_id(const AV1_COMMON *cm,
475
476
477
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
478
479
480
481
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
482
483
484
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
485
486
}

Yaowu Xu's avatar
Yaowu Xu committed
487
488
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
489
  struct segmentation *const seg = &cm->seg;
490
491
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
492
493
494
  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;
Geza Lore's avatar
Geza Lore committed
495
496
  const int bw = num_8x8_blocks_wide_lookup[mbmi->sb_type];
  const int bh = num_8x8_blocks_high_lookup[mbmi->sb_type];
Jingning Han's avatar
Jingning Han committed
497
498

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

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

504
505
506
507
  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
508
509
510
511
512
513
514
515

  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
516
517
    const int ctx = av1_get_pred_context_seg_id(xd);
    const aom_prob pred_prob = segp->pred_probs[ctx];
Michael Bebenita's avatar
Michael Bebenita committed
518
    mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
519
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
520
521
522
523
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
524
      if (counts) ++counts->seg.tree_mispred[segment_id];
525
    }
Jingning Han's avatar
Jingning Han committed
526
  } else {
527
    segment_id = read_segment_id(r, segp);
528
    if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
529
530
531
532
533
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
534
535
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
536
537
538
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
539
    const int ctx = av1_get_skip_context(xd);
Michael Bebenita's avatar
Michael Bebenita committed
540
    const int skip = aom_read(r, cm->fc->skip_probs[ctx], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
541
    FRAME_COUNTS *counts = xd->counts;
542
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
543
544
545
546
    return skip;
  }
}

547
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
548
549
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                   aom_reader *r) {
hui su's avatar
hui su committed
550
551
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
552
  const MODE_INFO *const above_mi = xd->above_mi;
553
  const MODE_INFO *const left_mi = xd->left_mi;
hui su's avatar
hui su committed
554
  const BLOCK_SIZE bsize = mbmi->sb_type;
555
556
557
558
559
560
561
562
  int i, n, palette_ctx = 0;
  PALETTE_MODE_INFO *const pmi = &mbmi->palette_mode_info;

  if (mbmi->mode == DC_PRED) {
    if (above_mi)
      palette_ctx += (above_mi->mbmi.palette_mode_info.palette_size[0] > 0);
    if (left_mi)
      palette_ctx += (left_mi->mbmi.palette_mode_info.palette_size[0] > 0);
Michael Bebenita's avatar
Michael Bebenita committed
563
564
565
    if (aom_read(
            r, av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
            ACCT_STR)) {
566
      pmi->palette_size[0] =
Yaowu Xu's avatar
Yaowu Xu committed
567
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
568
569
                        av1_default_palette_y_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
570
          2;
571
572
      n = pmi->palette_size[0];
      for (i = 0; i < n; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
573
        pmi->palette_colors[i] = aom_read_literal(r, cm->bit_depth, ACCT_STR);
hui su's avatar
hui su committed
574

575
576
577
578
      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
579

580
  if (mbmi->uv_mode == DC_PRED) {
Michael Bebenita's avatar
Michael Bebenita committed
581
582
    if (aom_read(r, av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0],
                 ACCT_STR)) {
583
      pmi->palette_size[1] =
Yaowu Xu's avatar
Yaowu Xu committed
584
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
585
586
                        av1_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
587
          2;
588
589
590
      n = pmi->palette_size[1];
      for (i = 0; i < n; ++i) {
        pmi->palette_colors[PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
591
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
592
        pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
593
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
594
595
596
597
      }
      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
598
599
  }
}
600
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
601

602
603
604
#if CONFIG_FILTER_INTRA
static void read_filter_intra_mode_info(AV1_COMMON *const cm,
                                        MACROBLOCKD *const xd, aom_reader *r) {
hui su's avatar
hui su committed
605
606
607
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
608
609
  FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
      &mbmi->filter_intra_mode_info;
hui su's avatar
hui su committed
610

611
612
613
614
615
  if (mbmi->mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[0] == 0
#endif  // CONFIG_PALETTE
      ) {
616
617
618
619
    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
620
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
621
    }
622
623
624
625
    if (counts) {
      ++counts->filter_intra[0]
                            [filter_intra_mode_info->use_filter_intra_mode[0]];
    }
hui su's avatar
hui su committed
626
  }
627
628
629
630
631
  if (mbmi->uv_mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[1] == 0
#endif  // CONFIG_PALETTE
      ) {
632
633
634
635
    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
636
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
637
    }
638
639
640
641
    if (counts) {
      ++counts->filter_intra[1]
                            [filter_intra_mode_info->use_filter_intra_mode[1]];
    }
hui su's avatar
hui su committed
642
643
  }
}
644
#endif  // CONFIG_FILTER_INTRA
645

646
#if CONFIG_EXT_INTRA
Yaowu Xu's avatar
Yaowu Xu committed
647
648
static void read_intra_angle_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  aom_reader *r) {
649
650
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xu's avatar
Yaowu Xu committed
651
  const int ctx = av1_get_pred_context_intra_interp(xd);
652
653
  int p_angle;

654
  if (bsize < BLOCK_8X8) return;
655
656
657
658
659

  if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
    mbmi->angle_delta[0] =
        read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
    p_angle = mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
Yaowu Xu's avatar
Yaowu Xu committed
660
    if (av1_is_intra_filter_switchable(p_angle)) {
661
      FRAME_COUNTS *counts = xd->counts;
Michael Bebenita's avatar
Michael Bebenita committed
662
663
      mbmi->intra_filter = aom_read_tree(
          r, av1_intra_filter_tree, cm->fc->intra_filter_probs[ctx], ACCT_STR);
664
      if (counts) ++counts->intra_filter[ctx][mbmi->intra_filter];
665
666
667
668
669
670
671
672
673
674
    } else {
      mbmi->intra_filter = INTRA_FILTER_LINEAR;
    }
  }

  if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED) {
    mbmi->angle_delta[1] =
        read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
  }
}
hui su's avatar
hui su committed
675
676
#endif  // CONFIG_EXT_INTRA

Yaowu Xu's avatar
Yaowu Xu committed
677
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
678
                                       MACROBLOCKD *const xd, int mi_row,
Yaowu Xu's avatar
Yaowu Xu committed
679
                                       int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
680
681
682
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
683
  const MODE_INFO *left_mi = xd->left_mi;
Jingning Han's avatar
Jingning Han committed
684
685
686
687
688
689
690
  const BLOCK_SIZE bsize = mbmi->sb_type;
  int i;
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = xd->plane[0].n4_w >> 1;
  const int bh = xd->plane[0].n4_h >> 1;

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

694
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
695
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
696
697
698

#if CONFIG_DELTA_Q
  if (cm->delta_q_present_flag) {
699
700
701
702
    xd->current_qindex =
        xd->prev_qindex +
        read_delta_qindex(cm, xd, r, mbmi, mi_col, mi_row) * cm->delta_q_res;
    xd->prev_qindex = xd->current_qindex;
703
704
705
  }
#endif

706
  mbmi->tx_size = read_tx_size_intra(cm, xd, r);
Jingning Han's avatar
Jingning Han committed
707
708
709
710
711
712
713
  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

  switch (bsize) {
    case BLOCK_4X4:
      for (i = 0; i < 4; ++i)
        mi->bmi[i].as_mode =
714
#if CONFIG_DAALA_EC
715
            read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, i));
716
#else
717
            read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
718
#endif
Jingning Han's avatar
Jingning Han committed
719
720
721
722
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode =
723
#if CONFIG_DAALA_EC
724
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
725
#else
726
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
727
#endif
Jingning Han's avatar
Jingning Han committed
728
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
729
#if CONFIG_DAALA_EC
730
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 1));
731
#else
732
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
733
#endif
Jingning Han's avatar
Jingning Han committed
734
735
736
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode =
737
#if CONFIG_DAALA_EC
738
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
739
#else
740
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
741
#endif
Jingning Han's avatar
Jingning Han committed
742
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
743
#if CONFIG_DAALA_EC
744
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 2));
745
#else
746
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
747
#endif
Jingning Han's avatar
Jingning Han committed
748
749
      break;
    default:
750
      mbmi->mode =
751
#if CONFIG_DAALA_EC
752
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
753
#else
754
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
755
#endif
Jingning Han's avatar
Jingning Han committed
756
757
  }

758
  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
759
#if CONFIG_EXT_INTRA
760
761
  read_intra_angle_info(cm, xd, r);
#endif  // CONFIG_EXT_INTRA
762
#if CONFIG_PALETTE
hui su's avatar
hui su committed
763
764
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
765
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
hui su's avatar
hui su committed
766
    read_palette_mode_info(cm, xd, r);
767
#endif  // CONFIG_PALETTE
768
769
770
771
772
#if CONFIG_FILTER_INTRA
  mbmi->filter_intra_mode_info.use_filter_intra_mode[0] = 0;
  mbmi->filter_intra_mode_info.use_filter_intra_mode[1] = 0;
  if (bsize >= BLOCK_8X8) read_filter_intra_mode_info(cm, xd, r);
#endif  // CONFIG_FILTER_INTRA
hui su's avatar
hui su committed
773

774
  if (!FIXED_TX_TYPE) {
775
#if CONFIG_EXT_TX
776
777
    if (get_ext_tx_types(mbmi->tx_size, mbmi->sb_type, 0) > 1 &&
        cm->base_qindex > 0 && !mbmi->skip &&
778
779
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
        ALLOW_INTRA_EXT_TX) {
Jingning Han's avatar
Jingning Han committed
780
      FRAME_COUNTS *counts = xd->counts;
781
782
      int eset = get_ext_tx_set(mbmi->tx_size, mbmi->sb_type, 0);
      if (eset > 0) {
Yaowu Xu's avatar
Yaowu Xu committed
783
784
        mbmi->tx_type = aom_read_tree(
            r, av1_ext_tx_intra_tree[eset],
Michael Bebenita's avatar
Michael Bebenita committed
785
786
            cm->fc->intra_ext_tx_prob[eset][mbmi->tx_size][mbmi->mode],
            ACCT_STR);
787
        if (counts)
clang-format's avatar
clang-format committed
788
789
          ++counts->intra_ext_tx[eset][mbmi->tx_size][mbmi->mode]
                                [mbmi->tx_type];
790
      }
791
    } else {
hui su's avatar
hui su committed
792
      mbmi->tx_type = DCT_DCT;
793
    }
794
#else
795
    if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
796
797
798
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
      FRAME_COUNTS *counts = xd->counts;
      TX_TYPE tx_type_nom = intra_mode_to_tx_type_context[mbmi->mode];
799
800
801
802
803
#if CONFIG_DAALA_EC
      mbmi->tx_type = av1_ext_tx_inv[aom_read_symbol(
          r, cm->fc->intra_ext_tx_cdf[mbmi->tx_size][tx_type_nom], TX_TYPES,
          ACCT_STR)];
#else
Michael Bebenita's avatar
Michael Bebenita committed
804
805
806
      mbmi->tx_type = aom_read_tree(
          r, av1_ext_tx_tree,
          cm->fc->intra_ext_tx_prob[mbmi->tx_size][tx_type_nom], ACCT_STR);
807
#endif
808
809
810
811
812
      if (counts)
        ++counts->intra_ext_tx[mbmi->tx_size][tx_type_nom][mbmi->tx_type];
    } else {
      mbmi->tx_type = DCT_DCT;
    }
813
#endif  // CONFIG_EXT_TX
814
  }
Jingning Han's avatar
Jingning Han committed
815
816
}

817
static int read_mv_component(aom_reader *r, nmv_component *mvcomp, int usehp) {
Jingning Han's avatar
Jingning Han committed
818
  int mag, d, fr, hp;
Michael Bebenita's avatar
Michael Bebenita committed
819
820
  const int sign = aom_read(r, mvcomp->sign, ACCT_STR);
  const int mv_class =
821
#if CONFIG_EC_MULTISYMBOL
822
823
      aom_read_symbol(r, mvcomp->class_cdf, MV_CLASSES, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
824
      aom_read_tree(r, av1_mv_class_tree, mvcomp->classes, ACCT_STR);
825
#endif
Jingning Han's avatar
Jingning Han committed
826
827
828
829
  const int class0 = mv_class == MV_CLASS_0;

  // Integer part
  if (class0) {
830
    d = aom_read(r, mvcomp->class0[0], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
831
832
833
834
835
836
    mag = 0;
  } else {
    int i;
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits

    d = 0;
Michael Bebenita's avatar
Michael Bebenita committed
837
    for (i = 0; i < n; ++i) d |= aom_read(r, mvcomp->bits[i], ACCT_STR) << i;
Jingning Han's avatar
Jingning Han committed
838
839
840
    mag = CLASS0_SIZE << (mv_class + 2);
  }

841
// Fractional part
842
#if CONFIG_EC_MULTISYMBOL
843
844
845
  fr = aom_read_symbol(r, class0 ? mvcomp->class0_fp_cdf[d] : mvcomp->fp_cdf,
                       MV_FP_SIZE, ACCT_STR);
#else
Yaowu Xu's avatar
Yaowu Xu committed
846
  fr = aom_read_tree(r, av1_mv_fp_tree,
Michael Bebenita's avatar
Michael Bebenita committed
847
                     class0 ? mvcomp->class0_fp[d] : mvcomp->fp, ACCT_STR);
848
#endif
Jingning Han's avatar
Jingning Han committed
849
850

  // High precision part (if hp is not used, the default value of the hp is 1)
Michael Bebenita's avatar
Michael Bebenita committed
851
852
  hp = usehp ? aom_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp, ACCT_STR)
             : 1;
Jingning Han's avatar
Jingning Han committed
853
854
855
856
857
858

  // Result
  mag += ((d << 3) | (fr << 1) | hp) + 1;
  return sign ? -mag : mag;
}

Yaowu Xu's avatar
Yaowu Xu committed
859
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
860
                           nmv_context *ctx, nmv_context_counts *counts,
861
                           int allow_hp) {
862
  MV_JOINT_TYPE joint_type;
863
  MV diff = { 0, 0 };
Michael Bebenita's avatar
Michael Bebenita committed
864
  joint_type =
865
#if CONFIG_EC_MULTISYMBOL
866
867
      (MV_JOINT_TYPE)aom_read_symbol(r, ctx->joint_cdf, MV_JOINTS, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
868
      (MV_JOINT_TYPE)aom_read_tree(r, av1_mv_joint_tree, ctx->joints, ACCT_STR);
869
#endif
870

Jingning Han's avatar
Jingning Han committed
871
  if (mv_joint_vertical(joint_type))
Alex Converse's avatar
Alex Converse committed
872
    diff.row = read_mv_component(r, &ctx->comps[0], allow_hp);
Jingning Han's avatar
Jingning Han committed
873
874

  if (mv_joint_horizontal(joint_type))
Alex Converse's avatar
Alex Converse committed
875
    diff.col = read_mv_component(r, &ctx->comps[1], allow_hp);
Jingning Han's avatar
Jingning Han committed
876

Alex Converse's avatar
Alex Converse committed
877
  av1_inc_mv(&diff, counts, allow_hp);
Jingning Han's avatar
Jingning Han committed
878
879
880
881
882