decodemv.c 67.5 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
  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);
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
309
  [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;
310

Jingning Han's avatar
Jingning Han committed
311
  if (depth == MAX_VARTX_DEPTH) {
312
313
    int idx, idy;
    inter_tx_size[0][0] = tx_size;
314
315
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
316
317
318
319
320
321
322
323
        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
324
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
325
326

  if (is_split) {
327
328
    const TX_SIZE sub_txs = sub_tx_size_map[tx_size];
    const int bsl = tx_size_wide_unit[sub_txs];
329
    int i;
330

331
    if (counts) ++counts->txfm_partition[ctx][1];
332

333
    if (tx_size == TX_8X8) {
334
335
336
337
      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);
338
339
340
341
342
      return;
    }

    assert(bsl > 0);
    for (i = 0; i < 4; ++i) {
343
344
345
      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,
346
                         offsetc, r);
347
348
    }
  } else {
349
    int idx, idy;
350
    inter_tx_size[0][0] = tx_size;
351
352
    for (idy = 0; idy < tx_size_high_unit[tx_size] / 2; ++idy)
      for (idx = 0; idx < tx_size_wide_unit[tx_size] / 2; ++idx)
353
354
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
355
    if (counts) ++counts->txfm_partition[ctx][0];
356
357
    txfm_partition_update(xd->above_txfm_context + tx_col,
                          xd->left_txfm_context + tx_row, tx_size);
358
359
360
361
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
362
363
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
364
365
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
366
367
368
  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);
369
  if (counts) ++counts->tx_size[tx_size_cat][ctx][depth];
370
  return tx_size;
Jingning Han's avatar
Jingning Han committed
371
372
}

Yaowu Xu's avatar
Yaowu Xu committed
373
374
static TX_SIZE read_tx_size_intra(AV1_COMMON *cm, MACROBLOCKD *xd,
                                  aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
375
376
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
377
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
378
379
  if (bsize >= BLOCK_8X8) {
    if (tx_mode == TX_MODE_SELECT) {
380
381
382
383
      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;
384
    } else {
385
      return tx_size_from_tx_mode(bsize, cm->tx_mode, 0);
386
387
388
389
390
391
    }
  } else {
    return TX_4X4;
  }
}

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

Yaowu Xu's avatar
Yaowu Xu committed
423
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
424
425
426
427
428
                              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++)
429
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
430
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
431
432
433
434
435

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

Yaowu Xu's avatar
Yaowu Xu committed
436
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
437
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
438
439
440
441
442
443
444
445
446
  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
447
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
448
                                 int mi_offset, int x_mis, int y_mis,
Yaowu Xu's avatar
Yaowu Xu committed
449
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
450
  struct segmentation *const seg = &cm->seg;
451
452
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
453
454
  int segment_id;

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

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

459
  segment_id = read_segment_id(r, segp);
460
  if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
461
462
463
464
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
465
static void copy_segment_id(const AV1_COMMON *cm,
466
467
468
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
469
470
471
472
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
473
474
475
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
476
477
}

Yaowu Xu's avatar
Yaowu Xu committed
478
479
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
480
  struct segmentation *const seg = &cm->seg;
481
482
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
483
484
485
  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
486
487
  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
488
489

  // TODO(slavarnway): move x_mis, y_mis into xd ?????
Yaowu Xu's avatar
Yaowu Xu committed
490
491
  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
496
497
498
  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
499
500
501
502
503
504
505
506

  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
507
508
    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
509
    mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
510
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
511
512
513
514
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
515
      if (counts) ++counts->seg.tree_mispred[segment_id];
516
    }
Jingning Han's avatar
Jingning Han committed
517
  } else {
518
    segment_id = read_segment_id(r, segp);
519
    if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
520
521
522
523
524
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
525
526
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
527
528
529
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
530
    const int ctx = av1_get_skip_context(xd);
Michael Bebenita's avatar
Michael Bebenita committed
531
    const int skip = aom_read(r, cm->fc->skip_probs[ctx], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
532
    FRAME_COUNTS *counts = xd->counts;
533
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
534
535
536
537
    return skip;
  }
}

538
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
539
540
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                   aom_reader *r) {
hui su's avatar
hui su committed
541
542
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
543
  const MODE_INFO *const above_mi = xd->above_mi;
544
  const MODE_INFO *const left_mi = xd->left_mi;
hui su's avatar
hui su committed
545
  const BLOCK_SIZE bsize = mbmi->sb_type;
546
547
548
549
550
551
552
553
  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
554
555
556
    if (aom_read(
            r, av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
            ACCT_STR)) {
557
      pmi->palette_size[0] =
Yaowu Xu's avatar
Yaowu Xu committed
558
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
559
560
                        av1_default_palette_y_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
561
          2;
562
563
      n = pmi->palette_size[0];
      for (i = 0; i < n; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
564
        pmi->palette_colors[i] = aom_read_literal(r, cm->bit_depth, ACCT_STR);
hui su's avatar
hui su committed
565

566
567
568
569
      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
570

571
  if (mbmi->uv_mode == DC_PRED) {
Michael Bebenita's avatar
Michael Bebenita committed
572
573
    if (aom_read(r, av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0],
                 ACCT_STR)) {
574
      pmi->palette_size[1] =
Yaowu Xu's avatar
Yaowu Xu committed
575
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
576
577
                        av1_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
578
          2;
579
580
581
      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
582
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
583
        pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
584
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
585
586
587
588
      }
      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
589
590
  }
}
591
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
592

593
594
595
#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
596
597
598
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
599
600
  FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
      &mbmi->filter_intra_mode_info;
hui su's avatar
hui su committed
601

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

637
#if CONFIG_EXT_INTRA
Yaowu Xu's avatar
Yaowu Xu committed
638
639
static void read_intra_angle_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  aom_reader *r) {
640
641
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xu's avatar
Yaowu Xu committed
642
  const int ctx = av1_get_pred_context_intra_interp(xd);
643
644
  int p_angle;

645
  if (bsize < BLOCK_8X8) return;
646
647
648
649
650

  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
651
    if (av1_is_intra_filter_switchable(p_angle)) {
652
      FRAME_COUNTS *counts = xd->counts;
Michael Bebenita's avatar
Michael Bebenita committed
653
654
      mbmi->intra_filter = aom_read_tree(
          r, av1_intra_filter_tree, cm->fc->intra_filter_probs[ctx], ACCT_STR);
655
      if (counts) ++counts->intra_filter[ctx][mbmi->intra_filter];
656
657
658
659
660
661
662
663
664
665
    } 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
666
667
#endif  // CONFIG_EXT_INTRA

Jingning Han's avatar
Jingning Han committed
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
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
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
static void read_tx_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
                         MB_MODE_INFO *mbmi,
#if CONFIG_SUPERTX
                         int supertx_enabled,
#endif
                         aom_reader *r) {
  const int inter_block = is_inter_block(mbmi);
  const TX_SIZE tx_size = mbmi->tx_size;
  if (!FIXED_TX_TYPE) {
#if CONFIG_EXT_TX
    if (get_ext_tx_types(tx_size, mbmi->sb_type, inter_block) > 1 &&
        cm->base_qindex > 0 && !mbmi->skip &&
#if CONFIG_SUPERTX
        !supertx_enabled &&
#endif  // CONFIG_SUPERTX
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
      int eset = get_ext_tx_set(tx_size, mbmi->sb_type, inter_block);
      FRAME_COUNTS *counts = xd->counts;

      if (inter_block) {
        if (eset > 0) {
          mbmi->tx_type = aom_read_tree(
              r, av1_ext_tx_inter_tree[eset],
              cm->fc->inter_ext_tx_prob[eset][txsize_sqr_map[tx_size]],
              ACCT_STR);
          if (counts)
            ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]]
                                  [mbmi->tx_type];
        }
      } else if (ALLOW_INTRA_EXT_TX) {
        if (eset > 0) {
          mbmi->tx_type = aom_read_tree(
              r, av1_ext_tx_intra_tree[eset],
              cm->fc->intra_ext_tx_prob[eset][tx_size][mbmi->mode], ACCT_STR);
          if (counts)
            ++counts->intra_ext_tx[eset][tx_size][mbmi->mode][mbmi->tx_type];
        }
      }
    } else {
      mbmi->tx_type = DCT_DCT;
    }
#else
    if (tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
#if CONFIG_SUPERTX
        !supertx_enabled &&
#endif  // CONFIG_SUPERTX
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
      FRAME_COUNTS *counts = xd->counts;
      if (inter_block) {
#if CONFIG_DAALA_EC
        mbmi->tx_type = av1_ext_tx_inv[aom_read_symbol(
            r, cm->fc->inter_ext_tx_cdf[tx_size], TX_TYPES, ACCT_STR)];
#else
        mbmi->tx_type = aom_read_tree(
            r, av1_ext_tx_tree, cm->fc->inter_ext_tx_prob[tx_size], ACCT_STR);
#endif
        if (counts) ++counts->inter_ext_tx[tx_size][mbmi->tx_type];
      } else {
        const TX_TYPE tx_type_nom = intra_mode_to_tx_type_context[mbmi->mode];
#if CONFIG_DAALA_EC
        mbmi->tx_type = av1_ext_tx_inv[aom_read_symbol(
            r, cm->fc->intra_ext_tx_cdf[tx_size][tx_type_nom], TX_TYPES,
            ACCT_STR)];
#else
        mbmi->tx_type = aom_read_tree(
            r, av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[tx_size][tx_type_nom],
            ACCT_STR);
#endif
        if (counts) ++counts->intra_ext_tx[tx_size][tx_type_nom][mbmi->tx_type];
      }
    } else {
      mbmi->tx_type = DCT_DCT;
    }
#endif  // CONFIG_EXT_TX
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
745
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
746
                                       MACROBLOCKD *const xd, int mi_row,
Yaowu Xu's avatar
Yaowu Xu committed
747
                                       int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
748
749
750
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
751
  const MODE_INFO *left_mi = xd->left_mi;
Jingning Han's avatar
Jingning Han committed
752
753
754
755
756
757
758
  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
759
760
  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
761

762
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
763
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
764
765
766

#if CONFIG_DELTA_Q
  if (cm->delta_q_present_flag) {
767
768
769
770
    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;
771
772
773
  }
#endif

774
  mbmi->tx_size = read_tx_size_intra(cm, xd, r);
Jingning Han's avatar
Jingning Han committed
775
776
777
778
779
780
781
  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 =
782
#if CONFIG_DAALA_EC
783
            read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, i));
784
#else
785
            read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
786
#endif
Jingning Han's avatar
Jingning Han committed
787
788
789
790
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode =
791
#if CONFIG_DAALA_EC
792
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
793
#else
794
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
795
#endif
Jingning Han's avatar
Jingning Han committed
796
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
797
#if CONFIG_DAALA_EC
798
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 1));
799
#else
800
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
801
#endif
Jingning Han's avatar
Jingning Han committed
802
803
804
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode =
805
#if CONFIG_DAALA_EC
806
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
807
#else
808
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
809
#endif
Jingning Han's avatar
Jingning Han committed
810
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
811
#if CONFIG_DAALA_EC
812
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 2));
813
#else
814
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
815
#endif
Jingning Han's avatar
Jingning Han committed
816
817
      break;
    default:
818
      mbmi->mode =
819
#if CONFIG_DAALA_EC
820
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
821
#else
822
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
823
#endif
Jingning Han's avatar
Jingning Han committed
824
825
  }

826
  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
827
#if CONFIG_EXT_INTRA
828
829
  read_intra_angle_info(cm, xd, r);
#endif  // CONFIG_EXT_INTRA
830
#if CONFIG_PALETTE
hui su's avatar
hui su committed
831
832
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
833
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
hui su's avatar
hui su committed
834
    read_palette_mode_info(cm, xd, r);
835
#endif  // CONFIG_PALETTE
836
837
838
839
840
#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
841

Jingning Han's avatar
Jingning Han committed
842
843
844
  read_tx_type(cm, xd, mbmi,
#if CONFIG_SUPERTX
               0,
845
#endif
Jingning Han's avatar
Jingning Han committed
846
               r);
Jingning Han's avatar
Jingning Han committed
847
848
}

849
static int read_mv_component(aom_reader *r, nmv_component *mvcomp, int usehp) {
Jingning Han's avatar
Jingning Han committed
850
  int mag, d, fr, hp;
Michael Bebenita's avatar
Michael Bebenita committed
851
852
  const int sign = aom_read(r, mvcomp->sign, ACCT_STR);
  const int mv_class =
853
#if CONFIG_EC_MULTISYMBOL
854
855
      aom_read_symbol(r, mvcomp->class_cdf, MV_CLASSES, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
856
      aom_read_tree(r, av1_mv_class_tree, mvcomp->classes, ACCT_STR);
857
#endif
Jingning Han's avatar
Jingning Han committed
858
859
860
861
  const int class0 = mv_class == MV_CLASS_0;

  // Integer part
  if (class0) {
862
    d = aom_read(r, mvcomp->class0[0], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
863
864
865
866
867
868
    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
869
    for (i = 0; i < n; ++i) d |= aom_read(r, mvcomp->bits[i], ACCT_STR) << i;
Jingning Han's avatar
Jingning Han committed
870
871
872
    mag = CLASS0_SIZE << (mv_class + 2);
  }

873
// Fractional part
874
#if CONFIG_EC_MULTISYMBOL
875
876
877
  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
878
  fr = aom_read_tree(r, av1_mv_fp_tree,
Michael Bebenita's avatar
Michael Bebenita committed
879
                     class0 ? mvcomp->class0_fp[d] : mvcomp->fp, ACCT_STR);
880
#endif
Jingning Han's avatar
Jingning Han committed
881
882

  // High precision part (if hp is not used, the default value of the hp is 1)
Michael Bebenita's avatar
Michael Bebenita committed
883
884
  hp = usehp ? aom_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp, ACCT_STR)
             : 1;
Jingning Han's avatar
Jingning Han committed
885
886
887
888
889
890

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

Yaowu Xu's avatar
Yaowu Xu committed
891
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
892
                           nmv_context *ctx, nmv_context_counts *counts,
893
                           int allow_hp) {
894
  MV_JOINT_TYPE joint_type;
895
  MV diff = { 0, 0 };
Michael Bebenita's avatar
Michael Bebenita committed
896
  joint_type =
897
#if CONFIG_EC_MULTISYMBOL
898
899
      (MV_JOINT_TYPE)aom_read_symbol(r, ctx->joint_cdf, MV_JOINTS, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
900
      (MV_JOINT_TYPE)aom_read_tree(r, av1_mv_joint_tree, ctx->joints, ACCT_STR);
901
#endif
902

Jingning Han's avatar
Jingning Han committed
903
  if (mv_joint_vertical(joint_type))
Alex Converse's avatar
Alex Converse committed
904
    diff.row = read_mv_component(r, &ctx->comps[0], allow_hp);
Jingning Han's avatar
Jingning Han committed
905
906

  if (mv_joint_horizontal(joint_type))
Alex Converse's avatar