decodemv.c 68.2 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, const 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

252
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
253
254
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
255
256
257
  const int mode =
      aom_read_tree(r, av1_inter_compound_mode_tree,
                    cm->fc->inter_compound_mode_probs[ctx], ACCT_STR);
258
259
  FRAME_COUNTS *counts = xd->counts;

260
  if (counts) ++counts->inter_compound_mode[ctx][mode];
261
262
263
264
265
266

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

Yaowu Xu's avatar
Yaowu Xu committed
267
static int read_segment_id(aom_reader *r,
268
                           const struct segmentation_probs *segp) {
269
#if CONFIG_DAALA_EC
Michael Bebenita's avatar
Michael Bebenita committed
270
  return aom_read_symbol(r, segp->tree_cdf, MAX_SEGMENTS, ACCT_STR);
271
#else
Michael Bebenita's avatar
Michael Bebenita committed
272
  return aom_read_tree(r, av1_segment_tree, segp->tree_probs, ACCT_STR);
273
#endif
Jingning Han's avatar
Jingning Han committed
274
275
}

276
#if CONFIG_VAR_TX
Yaowu Xu's avatar
Yaowu Xu committed
277
static void read_tx_size_vartx(AV1_COMMON *cm, MACROBLOCKD *xd,
278
                               MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
279
                               TX_SIZE tx_size, int blk_row, int blk_col,
Yaowu Xu's avatar
Yaowu Xu committed
280
                               aom_reader *r) {
281
  int is_split = 0;
282
283
  const int tx_row = blk_row >> 1;
  const int tx_col = blk_col >> 1;
284
285
  int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
286
  int ctx = txfm_partition_context(xd->above_txfm_context + tx_col,
287
                                   xd->left_txfm_context + tx_row, tx_size);
clang-format's avatar
clang-format committed
288
  TX_SIZE(*const inter_tx_size)
289
290
  [MAX_MIB_SIZE] =
      (TX_SIZE(*)[MAX_MIB_SIZE]) & mbmi->inter_tx_size[tx_row][tx_col];
291

292
293
  if (xd->mb_to_bottom_edge < 0) max_blocks_high += xd->mb_to_bottom_edge >> 5;
  if (xd->mb_to_right_edge < 0) max_blocks_wide += xd->mb_to_right_edge >> 5;
294

295
  if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
296

Michael Bebenita's avatar
Michael Bebenita committed
297
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
298
299
300

  if (is_split) {
    BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
301
    int bsl = b_width_log2_lookup[bsize];
302
    int i;
303

304
    if (counts) ++counts->txfm_partition[ctx][1];
305

306
    if (tx_size == TX_8X8) {
307
308
309
310
      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);
311
312
313
314
315
316
      return;
    }

    assert(bsl > 0);
    --bsl;
    for (i = 0; i < 4; ++i) {
317
318
      int offsetr = blk_row + ((i >> 1) << bsl);
      int offsetc = blk_col + ((i & 0x01) << bsl);
319
320
      read_tx_size_vartx(cm, xd, mbmi, counts, tx_size - 1, offsetr, offsetc,
                         r);
321
322
    }
  } else {
323
    int idx, idy;
324
    inter_tx_size[0][0] = tx_size;
325
326
    for (idy = 0; idy < num_4x4_blocks_high_txsize_lookup[tx_size] / 2; ++idy)
      for (idx = 0; idx < num_4x4_blocks_wide_txsize_lookup[tx_size] / 2; ++idx)
327
328
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
329
    if (counts) ++counts->txfm_partition[ctx][0];
330
331
    txfm_partition_update(xd->above_txfm_context + tx_col,
                          xd->left_txfm_context + tx_row, tx_size);
332
333
334
335
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
336
337
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
338
339
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
Michael Bebenita's avatar
Michael Bebenita committed
340
341
342
  int tx_size =
      aom_read_tree(r, av1_tx_size_tree[tx_size_cat],
                    cm->fc->tx_size_probs[tx_size_cat][ctx], ACCT_STR);
343
  if (counts) ++counts->tx_size[tx_size_cat][ctx][tx_size];
Jingning Han's avatar
Jingning Han committed
344
345
346
  return (TX_SIZE)tx_size;
}

Yaowu Xu's avatar
Yaowu Xu committed
347
348
static TX_SIZE read_tx_size_intra(AV1_COMMON *cm, MACROBLOCKD *xd,
                                  aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
349
350
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
351
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
352
353
  if (bsize >= BLOCK_8X8) {
    if (tx_mode == TX_MODE_SELECT) {
354
355
356
357
      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;
358
    } else {
359
      return tx_size_from_tx_mode(bsize, cm->tx_mode, 0);
360
361
362
363
364
365
    }
  } else {
    return TX_4X4;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
366
367
static TX_SIZE read_tx_size_inter(AV1_COMMON *cm, MACROBLOCKD *xd,
                                  int allow_select, aom_reader *r) {
368
369
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
370
  if (xd->lossless[xd->mi[0]->mbmi.segment_id]) return TX_4X4;
371
372
  if (bsize >= BLOCK_8X8) {
    if (allow_select && tx_mode == TX_MODE_SELECT) {
373
374
      const TX_SIZE coded_tx_size =
          read_selected_tx_size(cm, xd, inter_tx_size_cat_lookup[bsize], r);
375
#if CONFIG_EXT_TX && CONFIG_RECT_TX
376
377
378
379
      if (coded_tx_size > max_txsize_lookup[bsize]) {
        assert(coded_tx_size == max_txsize_lookup[bsize] + 1);
        return max_txsize_rect_lookup[bsize];
      }
380
381
382
#else
      assert(coded_tx_size <= max_txsize_lookup[bsize]);
#endif  // CONFIG_EXT_TX && CONFIG_RECT_TX
383
      return coded_tx_size;
384
    } else {
385
      return tx_size_from_tx_mode(bsize, cm->tx_mode, 1);
386
387
    }
  } else {
388
#if CONFIG_EXT_TX && CONFIG_RECT_TX
Debargha Mukherjee's avatar
Debargha Mukherjee committed
389
    assert(IMPLIES(tx_mode == ONLY_4X4, bsize == BLOCK_4X4));
390
391
392
    return max_txsize_rect_lookup[bsize];
#else
    return TX_4X4;
393
#endif
394
  }
Jingning Han's avatar
Jingning Han committed
395
396
}

Yaowu Xu's avatar
Yaowu Xu committed
397
static int dec_get_segment_id(const AV1_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
398
399
400
401
402
                              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++)
403
      segment_id =
Yaowu Xu's avatar
Yaowu Xu committed
404
          AOMMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
405
406
407
408
409

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

Yaowu Xu's avatar
Yaowu Xu committed
410
static void set_segment_id(AV1_COMMON *cm, int mi_offset, int x_mis, int y_mis,
411
                           int segment_id) {
Jingning Han's avatar
Jingning Han committed
412
413
414
415
416
417
418
419
420
  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
421
static int read_intra_segment_id(AV1_COMMON *const cm, MACROBLOCKD *const xd,
422
                                 int mi_offset, int x_mis, int y_mis,
Yaowu Xu's avatar
Yaowu Xu committed
423
                                 aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
424
  struct segmentation *const seg = &cm->seg;
425
426
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
427
428
  int segment_id;

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

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

433
  segment_id = read_segment_id(r, segp);
434
  if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
435
436
437
438
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
439
static void copy_segment_id(const AV1_COMMON *cm,
440
441
442
                            const uint8_t *last_segment_ids,
                            uint8_t *current_segment_ids, int mi_offset,
                            int x_mis, int y_mis) {
443
444
445
446
  int x, y;

  for (y = 0; y < y_mis; y++)
    for (x = 0; x < x_mis; x++)
447
448
449
      current_segment_ids[mi_offset + y * cm->mi_cols + x] =
          last_segment_ids ? last_segment_ids[mi_offset + y * cm->mi_cols + x]
                           : 0;
450
451
}

Yaowu Xu's avatar
Yaowu Xu committed
452
453
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
454
  struct segmentation *const seg = &cm->seg;
455
456
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
457
458
459
  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
460
461
  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
462
463

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

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

469
470
471
472
  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
473
474
475
476
477
478
479
480

  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
481
482
    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
483
    mbmi->seg_id_predicted = aom_read(r, pred_prob, ACCT_STR);
484
    if (counts) ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
485
486
487
488
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
489
      if (counts) ++counts->seg.tree_mispred[segment_id];
490
    }
Jingning Han's avatar
Jingning Han committed
491
  } else {
492
    segment_id = read_segment_id(r, segp);
493
    if (counts) ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
494
495
496
497
498
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
499
500
static int read_skip(AV1_COMMON *cm, const MACROBLOCKD *xd, int segment_id,
                     aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
501
502
503
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
Yaowu Xu's avatar
Yaowu Xu committed
504
    const int ctx = av1_get_skip_context(xd);
Michael Bebenita's avatar
Michael Bebenita committed
505
    const int skip = aom_read(r, cm->fc->skip_probs[ctx], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
506
    FRAME_COUNTS *counts = xd->counts;
507
    if (counts) ++counts->skip[ctx][skip];
Jingning Han's avatar
Jingning Han committed
508
509
510
511
    return skip;
  }
}

512
#if CONFIG_PALETTE
Yaowu Xu's avatar
Yaowu Xu committed
513
514
static void read_palette_mode_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                   aom_reader *r) {
hui su's avatar
hui su committed
515
516
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
517
  const MODE_INFO *const above_mi = xd->above_mi;
518
  const MODE_INFO *const left_mi = xd->left_mi;
hui su's avatar
hui su committed
519
  const BLOCK_SIZE bsize = mbmi->sb_type;
520
521
522
523
524
525
526
527
  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
528
529
530
    if (aom_read(
            r, av1_default_palette_y_mode_prob[bsize - BLOCK_8X8][palette_ctx],
            ACCT_STR)) {
531
      pmi->palette_size[0] =
Yaowu Xu's avatar
Yaowu Xu committed
532
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
533
534
                        av1_default_palette_y_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
535
          2;
536
537
      n = pmi->palette_size[0];
      for (i = 0; i < n; ++i)
Michael Bebenita's avatar
Michael Bebenita committed
538
        pmi->palette_colors[i] = aom_read_literal(r, cm->bit_depth, ACCT_STR);
hui su's avatar
hui su committed
539

540
541
542
543
      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
544

545
  if (mbmi->uv_mode == DC_PRED) {
Michael Bebenita's avatar
Michael Bebenita committed
546
547
    if (aom_read(r, av1_default_palette_uv_mode_prob[pmi->palette_size[0] > 0],
                 ACCT_STR)) {
548
      pmi->palette_size[1] =
Yaowu Xu's avatar
Yaowu Xu committed
549
          aom_read_tree(r, av1_palette_size_tree,
Michael Bebenita's avatar
Michael Bebenita committed
550
551
                        av1_default_palette_uv_size_prob[bsize - BLOCK_8X8],
                        ACCT_STR) +
552
          2;
553
554
555
      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
556
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
557
        pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
Michael Bebenita's avatar
Michael Bebenita committed
558
            aom_read_literal(r, cm->bit_depth, ACCT_STR);
559
560
561
562
      }
      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
563
564
  }
}
565
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
566

567
568
569
#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
570
571
572
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
573
574
  FILTER_INTRA_MODE_INFO *filter_intra_mode_info =
      &mbmi->filter_intra_mode_info;
hui su's avatar
hui su committed
575

576
577
578
579
580
  if (mbmi->mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[0] == 0
#endif  // CONFIG_PALETTE
      ) {
581
582
583
584
    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
585
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
586
    }
587
588
589
590
    if (counts) {
      ++counts->filter_intra[0]
                            [filter_intra_mode_info->use_filter_intra_mode[0]];
    }
hui su's avatar
hui su committed
591
  }
592
593
594
595
596
  if (mbmi->uv_mode == DC_PRED
#if CONFIG_PALETTE
      && mbmi->palette_mode_info.palette_size[1] == 0
#endif  // CONFIG_PALETTE
      ) {
597
598
599
600
    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
601
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
602
    }
603
604
605
606
    if (counts) {
      ++counts->filter_intra[1]
                            [filter_intra_mode_info->use_filter_intra_mode[1]];
    }
hui su's avatar
hui su committed
607
608
  }
}
609
#endif  // CONFIG_FILTER_INTRA
610

611
#if CONFIG_EXT_INTRA
Yaowu Xu's avatar
Yaowu Xu committed
612
613
static void read_intra_angle_info(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                                  aom_reader *r) {
614
615
  MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
Yaowu Xu's avatar
Yaowu Xu committed
616
  const int ctx = av1_get_pred_context_intra_interp(xd);
617
618
  int p_angle;

619
  if (bsize < BLOCK_8X8) return;
620
621
622
623
624

  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
625
    if (av1_is_intra_filter_switchable(p_angle)) {
626
      FRAME_COUNTS *counts = xd->counts;
Michael Bebenita's avatar
Michael Bebenita committed
627
628
      mbmi->intra_filter = aom_read_tree(
          r, av1_intra_filter_tree, cm->fc->intra_filter_probs[ctx], ACCT_STR);
629
      if (counts) ++counts->intra_filter[ctx][mbmi->intra_filter];
630
631
632
633
634
635
636
637
638
639
    } 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
640
641
#endif  // CONFIG_EXT_INTRA

Yaowu Xu's avatar
Yaowu Xu committed
642
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
643
                                       MACROBLOCKD *const xd, int mi_row,
Yaowu Xu's avatar
Yaowu Xu committed
644
                                       int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
645
646
647
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
648
  const MODE_INFO *left_mi = xd->left_mi;
Jingning Han's avatar
Jingning Han committed
649
650
651
652
653
654
655
  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
656
657
  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
658

659
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
660
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
661
662
663

#if CONFIG_DELTA_Q
  if (cm->delta_q_present_flag) {
664
665
666
667
    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;
668
669
670
  }
#endif

671
  mbmi->tx_size = read_tx_size_intra(cm, xd, r);
Jingning Han's avatar
Jingning Han committed
672
673
674
675
676
677
678
  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 =
679
#if CONFIG_DAALA_EC
680
            read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, i));
681
#else
682
            read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
683
#endif
Jingning Han's avatar
Jingning Han committed
684
685
686
687
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode =
688
#if CONFIG_DAALA_EC
689
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
690
#else
691
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
692
#endif
Jingning Han's avatar
Jingning Han committed
693
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
694
#if CONFIG_DAALA_EC
695
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 1));
696
#else
697
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
698
#endif
Jingning Han's avatar
Jingning Han committed
699
700
701
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode =
702
#if CONFIG_DAALA_EC
703
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
704
#else
705
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
706
#endif
Jingning Han's avatar
Jingning Han committed
707
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
708
#if CONFIG_DAALA_EC
709
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 2));
710
#else
711
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
712
#endif
Jingning Han's avatar
Jingning Han committed
713
714
      break;
    default:
715
      mbmi->mode =
716
#if CONFIG_DAALA_EC
717
          read_intra_mode(r, get_y_mode_cdf(cm, mi, above_mi, left_mi, 0));
718
#else
719
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
720
#endif
Jingning Han's avatar
Jingning Han committed
721
722
  }

723
  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
724
#if CONFIG_EXT_INTRA
725
726
  read_intra_angle_info(cm, xd, r);
#endif  // CONFIG_EXT_INTRA
727
#if CONFIG_PALETTE
hui su's avatar
hui su committed
728
729
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
730
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
hui su's avatar
hui su committed
731
    read_palette_mode_info(cm, xd, r);
732
#endif  // CONFIG_PALETTE
733
734
735
736
737
#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
738

739
  if (!FIXED_TX_TYPE) {
740
#if CONFIG_EXT_TX
741
742
    if (get_ext_tx_types(mbmi->tx_size, mbmi->sb_type, 0) > 1 &&
        cm->base_qindex > 0 && !mbmi->skip &&
743
744
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
        ALLOW_INTRA_EXT_TX) {
Jingning Han's avatar
Jingning Han committed
745
      FRAME_COUNTS *counts = xd->counts;
746
747
      int eset = get_ext_tx_set(mbmi->tx_size, mbmi->sb_type, 0);
      if (eset > 0) {
Yaowu Xu's avatar
Yaowu Xu committed
748
749
        mbmi->tx_type = aom_read_tree(
            r, av1_ext_tx_intra_tree[eset],
Michael Bebenita's avatar
Michael Bebenita committed
750
751
            cm->fc->intra_ext_tx_prob[eset][mbmi->tx_size][mbmi->mode],
            ACCT_STR);
752
        if (counts)
clang-format's avatar
clang-format committed
753
754
          ++counts->intra_ext_tx[eset][mbmi->tx_size][mbmi->mode]
                                [mbmi->tx_type];
755
      }
756
    } else {
hui su's avatar
hui su committed
757
      mbmi->tx_type = DCT_DCT;
758
    }
759
#else
760
    if (mbmi->tx_size < TX_32X32 && cm->base_qindex > 0 && !mbmi->skip &&
761
762
763
        !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];
764
765
766
767
768
#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
769
770
771
      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);
772
#endif
773
774
775
776
777
      if (counts)
        ++counts->intra_ext_tx[mbmi->tx_size][tx_type_nom][mbmi->tx_type];
    } else {
      mbmi->tx_type = DCT_DCT;
    }
778
#endif  // CONFIG_EXT_TX
779
  }
Jingning Han's avatar
Jingning Han committed
780
781
}

Yaowu Xu's avatar
Yaowu Xu committed
782
static int read_mv_component(aom_reader *r, const nmv_component *mvcomp,
783
                             int usehp) {
Jingning Han's avatar
Jingning Han committed
784
  int mag, d, fr, hp;
Michael Bebenita's avatar
Michael Bebenita committed
785
786
787
  const int sign = aom_read(r, mvcomp->sign, ACCT_STR);
  const int mv_class =
      aom_read_tree(r, av1_mv_class_tree, mvcomp->classes, ACCT_STR);
Jingning Han's avatar
Jingning Han committed
788
789
790
791
  const int class0 = mv_class == MV_CLASS_0;

  // Integer part
  if (class0) {
792
    d = aom_read(r, mvcomp->class0[0], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
793
794
795
796
797
798
    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
799
    for (i = 0; i < n; ++i) d |= aom_read(r, mvcomp->bits[i], ACCT_STR) << i;
Jingning Han's avatar
Jingning Han committed
800
801
802
803
    mag = CLASS0_SIZE << (mv_class + 2);
  }

  // Fractional part
Yaowu Xu's avatar
Yaowu Xu committed
804
  fr = aom_read_tree(r, av1_mv_fp_tree,
Michael Bebenita's avatar
Michael Bebenita committed
805
                     class0 ? mvcomp->class0_fp[d] : mvcomp->fp, ACCT_STR);
Jingning Han's avatar
Jingning Han committed
806
807

  // High precision part (if hp is not used, the default value of the hp is 1)
Michael Bebenita's avatar
Michael Bebenita committed
808
809
  hp = usehp ? aom_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp, ACCT_STR)
             : 1;
Jingning Han's avatar
Jingning Han committed
810
811
812
813
814
815

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

Yaowu Xu's avatar
Yaowu Xu committed
816
static INLINE void read_mv(aom_reader *r, MV *mv, const MV *ref,
817
818
                           const nmv_context *ctx, nmv_context_counts *counts,
                           int allow_hp) {
819
  MV_JOINT_TYPE joint_type;
Yaowu Xu's avatar
Yaowu Xu committed
820
  const int use_hp = allow_hp && av1_use_mv_hp(ref);
821
  MV diff = { 0, 0 };
Michael Bebenita's avatar
Michael Bebenita committed
822
823
  joint_type =
      (MV_JOINT_TYPE)aom_read_tree(r, av1_mv_joint_tree, ctx->joints, ACCT_STR);
824

Jingning Han's avatar
Jingning Han committed
825
826
827
828
829
830
  if (mv_joint_vertical(joint_type))
    diff.row = read_mv_component(r, &ctx->comps[0], use_hp);

  if (mv_joint_horizontal(joint_type))
    diff.col = read_mv_component(r, &ctx->comps[1], use_hp);

Yaowu Xu's avatar
Yaowu Xu committed
831
  av1_inc_mv(&diff, counts, use_hp);
Jingning Han's avatar
Jingning Han committed
832
833
834
835
836

  mv->row = ref->row + diff.row;
  mv->col = ref->col + diff.col;
}

Yaowu Xu's avatar
Yaowu Xu committed
837
static REFERENCE_MODE read_block_reference_mode(AV1_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
838
                                                const MACROBLOCKD *xd,
Yaowu Xu's avatar
Yaowu Xu committed
839
                                                aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
840
  if (cm->reference_mode == REFERENCE_MODE_SELECT) {
Yaowu Xu's avatar
Yaowu Xu committed
841
    const int ctx = av1_get_reference_mode_context(cm, xd);
Jingning Han's avatar
Jingning Han committed
842
    const REFERENCE_MODE mode =
Michael Bebenita's avatar
Michael Bebenita committed
843
        (REFERENCE_MODE)aom_read(r, cm->fc->comp_inter_prob[ctx], ACCT_STR);
Jingning Han's avatar
Jingning Han committed
844
    FRAME_COUNTS *counts = xd->counts;
845
    if (counts) ++counts->comp_inter[ctx][mode];
Jingning Han's avatar
Jingning Han committed
846
847
848
849
850
851
852
    return mode;  // SINGLE_REFERENCE or COMPOUND_REFERENCE
  } else {
    return cm->reference_mode;
  }
}

// Read the referncence frame
Yaowu Xu's avatar
Yaowu Xu committed
853
854
static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                            aom_reader *r, int segment_id,
855
                            MV_REFERENCE_FRAME ref_frame[2]) {
Jingning Han's avatar
Jingning Han committed
856
857
858
859
860
861
862
863
864
865
866
  FRAME_CONTEXT *const fc = cm->fc;
  FRAME_COUNTS *counts = xd->counts;

  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
    ref_frame[0] = (MV_REFERENCE_FRAME)get_segdata(&cm->seg, segment_id,
                                                   SEG_LVL_REF_FRAME);
    ref_frame[1] = NONE;
  } else {
    const REFERENCE_MODE mode = read_block_reference_mode(cm, xd, r);
    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
    if (mode == COMPOUND_REFERENCE) {
867
#if CONFIG_EXT_REFS
868
869
      const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#else
Jingning Han's avatar
Jingning Han committed
870
      const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
871
#endif  // CONFIG_EXT_REFS
Yaowu Xu's avatar
Yaowu Xu committed
872
      const int ctx = av1_get_pred_context_comp_ref_p(cm, xd);
Michael Bebenita's avatar
Michael Bebenita committed
873
      const int bit = aom_read(r, fc->comp_ref_prob[ctx][0], ACCT_STR);
874