decodemv.c 68.1 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
Yaowu Xu's avatar
Yaowu Xu committed
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
Yaowu Xu's avatar
Yaowu Xu committed
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11 12 13
 */

#include <assert.h>

14 15 16 17 18 19 20 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
        inter_tx_size[idy][idx] = tx_size;
    mbmi->tx_size = tx_size;
318
    mbmi->min_tx_size = AOMMIN(mbmi->min_tx_size, get_min_tx_size(tx_size));
319 320 321 322 323 324
    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
325
  is_split = aom_read(r, cm->fc->txfm_partition_prob[ctx], ACCT_STR);
326 327

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

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

334
    if (tx_size == TX_8X8) {
335 336
      inter_tx_size[0][0] = TX_4X4;
      mbmi->tx_size = TX_4X4;
337
      mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
338 339
      txfm_partition_update(xd->above_txfm_context + tx_col,
                            xd->left_txfm_context + tx_row, TX_4X4);
340 341 342 343 344
      return;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

498 499 500 501
  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
502 503 504 505 506 507 508 509

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

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

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

569 570 571 572
      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
573

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

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

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

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

648
  if (bsize < BLOCK_8X8) return;
649 650 651 652 653

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

Jingning Han's avatar
Jingning Han committed
671 672 673 674 675 676 677
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);
678 679 680
#if CONFIG_VAR_TX
  const TX_SIZE tx_size = inter_block ? mbmi->min_tx_size : mbmi->tx_size;
#else
Jingning Han's avatar
Jingning Han committed
681
  const TX_SIZE tx_size = mbmi->tx_size;
682
#endif
Jingning Han's avatar
Jingning Han committed
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 745 746 747 748 749 750 751
  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
752
static void read_intra_frame_mode_info(AV1_COMMON *const cm,
753
                                       MACROBLOCKD *const xd, int mi_row,
Yaowu Xu's avatar
Yaowu Xu committed
754
                                       int mi_col, aom_reader *r) {
Jingning Han's avatar
Jingning Han committed
755 756 757
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
758
  const MODE_INFO *left_mi = xd->left_mi;
Jingning Han's avatar
Jingning Han committed
759 760 761 762 763 764 765
  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
766 767
  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
768

769
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
770
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
771 772 773

#if CONFIG_DELTA_Q
  if (cm->delta_q_present_flag) {
774 775 776 777
    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;
778 779 780
  }
#endif

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