decodemv.c 68.3 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
  joint_type =
823 824 825
#if CONFIG_DAALA_EC
      (MV_JOINT_TYPE)aom_read_symbol(r, ctx->joint_cdf, MV_JOINTS, ACCT_STR);
#else
Michael Bebenita's avatar
Michael Bebenita committed
826
      (MV_JOINT_TYPE)aom_read_tree(r, av1_mv_joint_tree, ctx->joints, ACCT_STR);
827
#endif
828

Jingning Han's avatar
Jingning Han committed
829 830 831 832 833 834
  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
835
  av1_inc_mv(&diff, counts, use_hp);
Jingning Han's avatar
Jingning Han committed
836 837 838 839 840

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

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

// Read the referncence frame
Yaowu Xu's avatar
Yaowu Xu committed
857 858
static void read_ref_frames(AV1_COMMON *const cm, MACROBLOCKD *const xd,
                            aom_reader *r, int segment_id,
859
                            MV_REFERENCE_FRAME ref_frame[2]) {
Jingning Han's avatar
Jingning Han committed
860 861 862 863 864 865 866 867 868 869 870
  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) {
871
#if CONFIG_EXT_REFS
872 873
      const int idx = cm->ref_frame_sign_bias[cm->comp_bwd_ref[0]];
#else
Jingning Han's avatar
Jingning Han committed
874
      const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
875
#endif  // CONFIG_EXT_REFS
Yaowu Xu's avatar
Yaowu Xu committed
876
      const int ctx = av1_get_pred_context_comp_ref_p(cm, xd);
Michael Bebenita's avatar
Michael Bebenita committed
877
      const int bit = aom_read(r, fc->comp_ref_prob[ctx][0], ACCT_STR);
878

879
      if (counts) ++counts->comp_ref[ctx][0][bit];
880

881
#if CONFIG_EXT_REFS
882
      // Decode forward references.
883
      if (!bit) {
Yaowu Xu's avatar
Yaowu Xu committed
884
        const int ctx1 = av1_get_pred_context_comp_ref_p1(cm, xd);
Michael Bebenita's avatar
Michael Bebenita committed
885
        const int bit1 = aom_read(r, fc->comp_ref_prob[ctx1][1], ACCT_STR);
886
        if (counts) ++counts->comp_ref[ctx1][1][bit1];
887
        ref_frame[!idx] = cm->comp_fwd_ref[bit1 ? 0 : 1];
888
      } else {
Yaowu Xu's avatar
Yaowu Xu committed
889
        const int ctx2 = av1_get_pred_context_comp_ref_p2(cm, xd);
Michael Bebenita's avatar
Michael Bebenita committed
890
        const int bit2 = aom_read(r, fc->comp_ref_prob[ctx2][2], ACCT_STR);
891
        if (counts) ++counts->comp_ref[ctx2][2][bit2];
892
        ref_frame[!idx] = cm->comp_fwd_ref[bit2 ? 3 : 2];