decodemv.c 57.7 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1 2 3 4 5 6 7 8 9 10 11 12
/*
  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>

13 14 15 16 17 18 19 20
#include "vp10/common/common.h"
#include "vp10/common/entropy.h"
#include "vp10/common/entropymode.h"
#include "vp10/common/entropymv.h"
#include "vp10/common/mvref_common.h"
#include "vp10/common/pred_common.h"
#include "vp10/common/reconinter.h"
#include "vp10/common/seg_common.h"
Jingning Han's avatar
Jingning Han committed
21

22 23
#include "vp10/decoder/decodemv.h"
#include "vp10/decoder/decodeframe.h"
Jingning Han's avatar
Jingning Han committed
24

25 26
#include "vpx_dsp/vpx_dsp_common.h"

hui su's avatar
hui su committed
27 28 29 30 31 32 33 34 35 36 37 38 39
static INLINE int read_uniform(vpx_reader *r, int n) {
  int l = get_unsigned_bits(n);
  int m = (1 << l) - n;
  int v = vpx_read_literal(r, l-1);

  assert(l != 0);

  if (v < m)
    return v;
  else
    return (v << 1) - m + vpx_read_literal(r, 1);
}

Jingning Han's avatar
Jingning Han committed
40 41 42 43
static PREDICTION_MODE read_intra_mode(vpx_reader *r, const vpx_prob *p) {
  return (PREDICTION_MODE)vpx_read_tree(r, vp10_intra_mode_tree, p);
}

Yaowu Xu's avatar
Yaowu Xu committed
44
static PREDICTION_MODE read_intra_mode_y(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
45 46 47 48 49 50 51 52 53
                                         vpx_reader *r, int size_group) {
  const PREDICTION_MODE y_mode =
      read_intra_mode(r, cm->fc->y_mode_prob[size_group]);
  FRAME_COUNTS *counts = xd->counts;
  if (counts)
    ++counts->y_mode[size_group][y_mode];
  return y_mode;
}

Yaowu Xu's avatar
Yaowu Xu committed
54
static PREDICTION_MODE read_intra_mode_uv(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
55 56 57 58 59 60 61 62 63 64
                                          vpx_reader *r,
                                          PREDICTION_MODE y_mode) {
  const PREDICTION_MODE uv_mode = read_intra_mode(r,
                                         cm->fc->uv_mode_prob[y_mode]);
  FRAME_COUNTS *counts = xd->counts;
  if (counts)
    ++counts->uv_mode[y_mode][uv_mode];
  return uv_mode;
}

Yaowu Xu's avatar
Yaowu Xu committed
65
static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
Yue Chen's avatar
Yue Chen committed
66 67 68
#if CONFIG_REF_MV && CONFIG_EXT_INTER
                                       MB_MODE_INFO *mbmi,
#endif
69
                                       vpx_reader *r, int16_t ctx) {
70 71
#if CONFIG_REF_MV
  FRAME_COUNTS *counts = xd->counts;
72
  int16_t mode_ctx = ctx & NEWMV_CTX_MASK;
73 74 75 76 77
  vpx_prob mode_prob = cm->fc->newmv_prob[mode_ctx];

  if (vpx_read(r, mode_prob) == 0) {
    if (counts)
      ++counts->newmv_mode[mode_ctx][0];
Yue Chen's avatar
Yue Chen committed
78 79 80 81

#if CONFIG_EXT_INTER
    if (has_second_ref(mbmi)) {
#endif  // CONFIG_EXT_INTER
82
    return NEWMV;
Yue Chen's avatar
Yue Chen committed
83 84 85 86 87 88 89 90 91 92 93 94 95 96
#if CONFIG_EXT_INTER
    } else {
      mode_prob = cm->fc->new2mv_prob;
      if (vpx_read(r, mode_prob) == 0) {
        if (counts)
          ++counts->new2mv_mode[0];
        return NEWMV;
      } else {
        if (counts)
          ++counts->new2mv_mode[1];
        return NEWFROMNEARMV;
      }
    }
#endif  // CONFIG_EXT_INTER
97 98 99 100
  }
  if (counts)
    ++counts->newmv_mode[mode_ctx][1];

101 102
  if (ctx & (1 << ALL_ZERO_FLAG_OFFSET))
    return ZEROMV;
103

104
  mode_ctx = (ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
105 106 107 108 109 110 111 112 113 114

  mode_prob = cm->fc->zeromv_prob[mode_ctx];
  if (vpx_read(r, mode_prob) == 0) {
    if (counts)
      ++counts->zeromv_mode[mode_ctx][0];
    return ZEROMV;
  }
  if (counts)
    ++counts->zeromv_mode[mode_ctx][1];

115
  mode_ctx = (ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
116 117 118 119 120 121 122 123

  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;

124
  mode_prob = cm->fc->refmv_prob[mode_ctx];
125

126 127 128
  if (vpx_read(r, mode_prob) == 0) {
    if (counts)
      ++counts->refmv_mode[mode_ctx][0];
129

130 131 132 133 134 135 136 137 138 139
    return NEARESTMV;
  } else {
    if (counts)
      ++counts->refmv_mode[mode_ctx][1];
    return NEARMV;
  }

  // Invalid prediction mode.
  assert(0);
#else
Jingning Han's avatar
Jingning Han committed
140 141 142 143 144 145 146
  const int mode = vpx_read_tree(r, vp10_inter_mode_tree,
                                 cm->fc->inter_mode_probs[ctx]);
  FRAME_COUNTS *counts = xd->counts;
  if (counts)
    ++counts->inter_mode[ctx][mode];

  return NEARESTMV + mode;
147
#endif
Jingning Han's avatar
Jingning Han committed
148 149
}

150 151 152 153 154 155 156 157 158
#if CONFIG_REF_MV
static void read_drl_idx(const VP10_COMMON *cm,
                         MACROBLOCKD *xd,
                         MB_MODE_INFO *mbmi,
                         vpx_reader *r) {
  uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
  mbmi->ref_mv_idx = 0;

  if (xd->ref_mv_count[ref_frame_type] > 2) {
Jingning Han's avatar
Jingning Han committed
159
    uint8_t drl0_ctx = vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 1);
160 161 162 163 164 165 166
    vpx_prob drl0_prob = cm->fc->drl_prob0[drl0_ctx];
    if (vpx_read(r, drl0_prob)) {
      mbmi->ref_mv_idx = 1;
      if (xd->counts)
        ++xd->counts->drl_mode0[drl0_ctx][1];
      if (xd->ref_mv_count[ref_frame_type] > 3) {
        uint8_t drl1_ctx =
Jingning Han's avatar
Jingning Han committed
167
            vp10_drl_ctx(xd->ref_mv_stack[ref_frame_type], 2);
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
        vpx_prob drl1_prob = cm->fc->drl_prob1[drl1_ctx];
        if (vpx_read(r, drl1_prob)) {
          mbmi->ref_mv_idx = 2;
          if (xd->counts)
            ++xd->counts->drl_mode1[drl1_ctx][1];

          return;
        }

        if (xd->counts)
          ++xd->counts->drl_mode1[drl1_ctx][0];
      }
      return;
    }

    if (xd->counts)
      ++xd->counts->drl_mode0[drl0_ctx][0];
  }
}
#endif

189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
#if CONFIG_EXT_INTER
static PREDICTION_MODE read_inter_compound_mode(VP10_COMMON *cm,
                                                MACROBLOCKD *xd,
                                                vpx_reader *r, int16_t ctx) {
  const int mode = vpx_read_tree(r, vp10_inter_compound_mode_tree,
                                 cm->fc->inter_compound_mode_probs[ctx]);
  FRAME_COUNTS *counts = xd->counts;

  if (counts)
    ++counts->inter_compound_mode[ctx][mode];

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

205 206 207
static int read_segment_id(vpx_reader *r,
    const struct segmentation_probs *segp) {
  return vpx_read_tree(r, vp10_segment_tree, segp->tree_probs);
Jingning Han's avatar
Jingning Han committed
208 209
}

210
#if CONFIG_VAR_TX
211
static void read_tx_size_inter(VP10_COMMON *cm, MACROBLOCKD *xd,
212
                               MB_MODE_INFO *mbmi, FRAME_COUNTS *counts,
213
                               TX_SIZE tx_size, int blk_row, int blk_col,
214
                               vpx_reader *r) {
215 216 217 218
  int is_split = 0;
  const int tx_idx = (blk_row >> 1) * 8 + (blk_col >> 1);
  int max_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
  int max_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
219 220 221 222
  int ctx = txfm_partition_context(xd->above_txfm_context + (blk_col >> 1),
                                   xd->left_txfm_context + (blk_row >> 1),
                                   tx_size);

223 224 225 226 227 228 229 230
  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;

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

231
  is_split = vpx_read(r, cm->fc->txfm_partition_prob[ctx]);
232 233 234

  if (is_split) {
    BLOCK_SIZE bsize = txsize_to_bsize[tx_size];
235
    int bsl = b_width_log2_lookup[bsize];
236
    int i;
237 238 239 240

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

241
    if (tx_size == TX_8X8) {
242 243
      mbmi->inter_tx_size[tx_idx] = TX_4X4;
      mbmi->tx_size = mbmi->inter_tx_size[tx_idx];
244 245
      txfm_partition_update(xd->above_txfm_context + (blk_col >> 1),
                            xd->left_txfm_context + (blk_row >> 1), TX_4X4);
246 247 248 249 250 251
      return;
    }

    assert(bsl > 0);
    --bsl;
    for (i = 0; i < 4; ++i) {
252 253
      int offsetr = blk_row + ((i >> 1) << bsl);
      int offsetc = blk_col + ((i & 0x01) << bsl);
254 255
      read_tx_size_inter(cm, xd, mbmi, counts,
                         tx_size - 1, offsetr, offsetc, r);
256 257
    }
  } else {
258
    int idx, idy;
259
    mbmi->inter_tx_size[tx_idx] = tx_size;
260 261 262
    for (idy = 0; idy < (1 << tx_size) / 2; ++idy)
      for (idx = 0; idx < (1 << tx_size) / 2; ++idx)
        mbmi->inter_tx_size[tx_idx + (idy << 3) + idx] = tx_size;
263
    mbmi->tx_size = mbmi->inter_tx_size[tx_idx];
264 265 266 267
    if (counts)
      ++counts->txfm_partition[ctx][0];
    txfm_partition_update(xd->above_txfm_context + (blk_col >> 1),
                          xd->left_txfm_context + (blk_row >> 1), tx_size);
268 269 270 271
  }
}
#endif

Yaowu Xu's avatar
Yaowu Xu committed
272
static TX_SIZE read_selected_tx_size(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
273 274 275
                                     TX_SIZE max_tx_size, vpx_reader *r) {
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
276 277 278
  const int tx_size_cat = max_tx_size - TX_8X8;
  int tx_size = vpx_read_tree(r, vp10_tx_size_tree[tx_size_cat],
                              cm->fc->tx_size_probs[tx_size_cat][ctx]);
Jingning Han's avatar
Jingning Han committed
279
  if (counts)
280
    ++counts->tx_size[tx_size_cat][ctx][tx_size];
Jingning Han's avatar
Jingning Han committed
281 282 283
  return (TX_SIZE)tx_size;
}

Yaowu Xu's avatar
Yaowu Xu committed
284
static TX_SIZE read_tx_size(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
285 286 287 288
                            int allow_select, vpx_reader *r) {
  TX_MODE tx_mode = cm->tx_mode;
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
  const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
289 290
  if (xd->lossless[xd->mi[0]->mbmi.segment_id])
    return TX_4X4;
Jingning Han's avatar
Jingning Han committed
291 292 293
  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
    return read_selected_tx_size(cm, xd, max_tx_size, r);
  else
294
    return VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]);
Jingning Han's avatar
Jingning Han committed
295 296
}

Yaowu Xu's avatar
Yaowu Xu committed
297
static int dec_get_segment_id(const VP10_COMMON *cm, const uint8_t *segment_ids,
Jingning Han's avatar
Jingning Han committed
298 299 300 301 302
                              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++)
303 304
      segment_id =
          VPXMIN(segment_id, segment_ids[mi_offset + y * cm->mi_cols + x]);
Jingning Han's avatar
Jingning Han committed
305 306 307 308 309

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

Yaowu Xu's avatar
Yaowu Xu committed
310
static void set_segment_id(VP10_COMMON *cm, int mi_offset,
Jingning Han's avatar
Jingning Han committed
311 312 313 314 315 316 317 318 319 320
                           int x_mis, int y_mis, int segment_id) {
  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;
}

321 322
static int read_intra_segment_id(VP10_COMMON *const cm, MACROBLOCKD *const xd,
                                 int mi_offset, int x_mis, int y_mis,
Jingning Han's avatar
Jingning Han committed
323 324
                                 vpx_reader *r) {
  struct segmentation *const seg = &cm->seg;
325 326
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
327 328 329 330 331
  int segment_id;

  if (!seg->enabled)
    return 0;  // Default for disabled segmentation

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

334 335 336
  segment_id = read_segment_id(r, segp);
  if (counts)
    ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
337 338 339 340
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

341 342 343 344 345 346 347 348 349 350 351 352
static void copy_segment_id(const VP10_COMMON *cm,
                           const uint8_t *last_segment_ids,
                           uint8_t *current_segment_ids,
                           int mi_offset, int x_mis, int y_mis) {
  int x, y;

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

Yaowu Xu's avatar
Yaowu Xu committed
353
static int read_inter_segment_id(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
354 355
                                 int mi_row, int mi_col, vpx_reader *r) {
  struct segmentation *const seg = &cm->seg;
356 357
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
358 359 360 361 362 363 364
  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;
  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 ?????
365 366
  const int x_mis = VPXMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = VPXMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381

  if (!seg->enabled)
    return 0;  // Default for disabled segmentation

  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;

  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) {
382 383
    const int ctx = vp10_get_pred_context_seg_id(xd);
    const vpx_prob pred_prob = segp->pred_probs[ctx];
Jingning Han's avatar
Jingning Han committed
384
    mbmi->seg_id_predicted = vpx_read(r, pred_prob);
385 386 387 388 389 390 391 392 393
    if (counts)
      ++counts->seg.pred[ctx][mbmi->seg_id_predicted];
    if (mbmi->seg_id_predicted) {
      segment_id = predicted_segment_id;
    } else {
      segment_id = read_segment_id(r, segp);
      if (counts)
        ++counts->seg.tree_mispred[segment_id];
    }
Jingning Han's avatar
Jingning Han committed
394
  } else {
395 396 397
    segment_id = read_segment_id(r, segp);
    if (counts)
      ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
398 399 400 401 402
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
403
static int read_skip(VP10_COMMON *cm, const MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
404 405 406 407 408 409 410 411 412 413 414 415 416
                     int segment_id, vpx_reader *r) {
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
    return 1;
  } else {
    const int ctx = vp10_get_skip_context(xd);
    const int skip = vpx_read(r, cm->fc->skip_probs[ctx]);
    FRAME_COUNTS *counts = xd->counts;
    if (counts)
      ++counts->skip[ctx][skip];
    return skip;
  }
}

hui su's avatar
hui su committed
417 418 419 420 421
static void read_palette_mode_info(VP10_COMMON *const cm,
                                   MACROBLOCKD *const xd,
                                   vpx_reader *r) {
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
422 423
  const MODE_INFO *const above_mi = xd->above_mi;
  const MODE_INFO *const left_mi  = xd->left_mi;
hui su's avatar
hui su committed
424
  const BLOCK_SIZE bsize = mbmi->sb_type;
425 426 427 428 429 430 431 432 433 434 435
  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);
    if (vpx_read(r, vp10_default_palette_y_mode_prob[bsize - BLOCK_8X8]
                                                     [palette_ctx])) {
      pmi->palette_size[0] =
hui su's avatar
hui su committed
436 437
        vpx_read_tree(r, vp10_palette_size_tree,
                      vp10_default_palette_y_size_prob[bsize - BLOCK_8X8]) + 2;
438 439 440
      n = pmi->palette_size[0];
      for (i = 0; i < n; ++i)
        pmi->palette_colors[i] = vpx_read_literal(r, cm->bit_depth);
hui su's avatar
hui su committed
441

442 443 444 445
      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
446

447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463
  if (mbmi->uv_mode == DC_PRED) {
    if (vpx_read(r,
                 vp10_default_palette_uv_mode_prob[pmi->palette_size[0] > 0])) {
      pmi->palette_size[1] =
          vpx_read_tree(r, vp10_palette_size_tree,
                        vp10_default_palette_uv_size_prob[bsize - BLOCK_8X8])
                        + 2;
      n = pmi->palette_size[1];
      for (i = 0; i < n; ++i) {
        pmi->palette_colors[PALETTE_MAX_SIZE + i] =
            vpx_read_literal(r, cm->bit_depth);
        pmi->palette_colors[2 * PALETTE_MAX_SIZE + i] =
            vpx_read_literal(r, cm->bit_depth);
      }
      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
464 465 466
  }
}

hui su's avatar
hui su committed
467 468 469 470 471 472
#if CONFIG_EXT_INTRA
static void read_ext_intra_mode_info(VP10_COMMON *const cm,
                                     MACROBLOCKD *const xd, vpx_reader *r) {
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  FRAME_COUNTS *counts = xd->counts;
hui su's avatar
hui su committed
473 474 475 476

#if !ALLOW_FILTER_INTRA_MODES
  return;
#endif
477 478
  if (mbmi->mode == DC_PRED &&
      mbmi->palette_mode_info.palette_size[0] == 0) {
hui su's avatar
hui su committed
479 480 481
    mbmi->ext_intra_mode_info.use_ext_intra_mode[0] =
        vpx_read(r, cm->fc->ext_intra_probs[0]);
    if (mbmi->ext_intra_mode_info.use_ext_intra_mode[0]) {
hui su's avatar
hui su committed
482 483
      mbmi->ext_intra_mode_info.ext_intra_mode[0] =
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
484 485 486 487
    }
    if (counts)
      ++counts->ext_intra[0][mbmi->ext_intra_mode_info.use_ext_intra_mode[0]];
  }
488 489
  if (mbmi->uv_mode == DC_PRED &&
      mbmi->palette_mode_info.palette_size[1] == 0) {
hui su's avatar
hui su committed
490 491 492
    mbmi->ext_intra_mode_info.use_ext_intra_mode[1] =
        vpx_read(r, cm->fc->ext_intra_probs[1]);
    if (mbmi->ext_intra_mode_info.use_ext_intra_mode[1]) {
hui su's avatar
hui su committed
493 494
      mbmi->ext_intra_mode_info.ext_intra_mode[1] =
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
495 496 497 498 499 500 501
    }
    if (counts)
      ++counts->ext_intra[1][mbmi->ext_intra_mode_info.use_ext_intra_mode[1]];
  }
}
#endif  // CONFIG_EXT_INTRA

Yaowu Xu's avatar
Yaowu Xu committed
502
static void read_intra_frame_mode_info(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
503 504 505 506 507 508 509 510 511 512 513 514 515
                                       MACROBLOCKD *const xd,
                                       int mi_row, int mi_col, vpx_reader *r) {
  MODE_INFO *const mi = xd->mi[0];
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const MODE_INFO *above_mi = xd->above_mi;
  const MODE_INFO *left_mi  = xd->left_mi;
  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 ?????
516 517
  const int x_mis = VPXMIN(cm->mi_cols - mi_col, bw);
  const int y_mis = VPXMIN(cm->mi_rows - mi_row, bh);
Jingning Han's avatar
Jingning Han committed
518

519
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
520 521 522 523 524 525 526 527 528
  mbmi->skip = read_skip(cm, xd, mbmi->segment_id, r);
  mbmi->tx_size = read_tx_size(cm, xd, 1, r);
  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 =
529
            read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
Jingning Han's avatar
Jingning Han committed
530 531 532 533
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode =
534
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
535
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
536
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
Jingning Han's avatar
Jingning Han committed
537 538 539
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode =
540
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
541
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
542
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
Jingning Han's avatar
Jingning Han committed
543 544 545
      break;
    default:
      mbmi->mode = read_intra_mode(r,
546
          get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
hui su's avatar
hui su committed
547
#if CONFIG_EXT_INTRA
548 549 550
      if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
        int p_angle;
        const int ctx = vp10_get_pred_context_intra_interp(xd);
hui su's avatar
hui su committed
551 552
        mbmi->angle_delta[0] =
            read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
553 554 555 556 557 558 559 560 561 562 563 564
        p_angle = mode_to_angle_map[mbmi->mode] +
            mbmi->angle_delta[0] * ANGLE_STEP;
        if (pick_intra_filter(p_angle)) {
          FRAME_COUNTS *counts = xd->counts;
          mbmi->intra_filter = vpx_read_tree(r, vp10_intra_filter_tree,
                                             cm->fc->intra_filter_probs[ctx]);
          if (counts)
            ++counts->intra_filter[ctx][mbmi->intra_filter];
        } else {
          mbmi->intra_filter = INTRA_FILTER_LINEAR;
        }
      }
hui su's avatar
hui su committed
565
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
566 567
  }

568
  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
569 570 571 572 573 574
#if CONFIG_EXT_INTRA
  if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED &&
      bsize >= BLOCK_8X8)
    mbmi->angle_delta[1] =
        read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
#endif
hui su's avatar
hui su committed
575

hui su's avatar
hui su committed
576 577
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
578
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
hui su's avatar
hui su committed
579 580
    read_palette_mode_info(cm, xd, r);

581
  if (!FIXED_TX_TYPE) {
582
#if CONFIG_EXT_TX
583 584
    if (get_ext_tx_types(mbmi->tx_size, mbmi->sb_type, 0) > 1 &&
        cm->base_qindex > 0 && !mbmi->skip &&
585 586
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
        ALLOW_INTRA_EXT_TX) {
Jingning Han's avatar
Jingning Han committed
587
      FRAME_COUNTS *counts = xd->counts;
588 589 590 591 592 593 594
      int eset = get_ext_tx_set(mbmi->tx_size, mbmi->sb_type, 0);
      if (eset > 0) {
        mbmi->tx_type = vpx_read_tree(
            r, vp10_ext_tx_intra_tree[eset],
            cm->fc->intra_ext_tx_prob[eset][mbmi->tx_size][mbmi->mode]);
        if (counts)
          ++counts->intra_ext_tx[eset][mbmi->tx_size][mbmi->mode]
595
                                                     [mbmi->tx_type];
596
      }
597
    } else {
hui su's avatar
hui su committed
598
      mbmi->tx_type = DCT_DCT;
599
    }
600
#else
601 602 603 604 605 606 607 608 609 610 611 612 613
    if (mbmi->tx_size < TX_32X32 &&
        cm->base_qindex > 0 && !mbmi->skip &&
        !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];
      mbmi->tx_type = vpx_read_tree(
          r, vp10_ext_tx_tree,
          cm->fc->intra_ext_tx_prob[mbmi->tx_size][tx_type_nom]);
      if (counts)
        ++counts->intra_ext_tx[mbmi->tx_size][tx_type_nom][mbmi->tx_type];
    } else {
      mbmi->tx_type = DCT_DCT;
    }
614
#endif  // CONFIG_EXT_TX
615
  }
hui su's avatar
hui su committed
616 617 618 619 620 621 622

#if CONFIG_EXT_INTRA
    mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
    mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
    if (bsize >= BLOCK_8X8)
      read_ext_intra_mode_info(cm, xd, r);
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
}

static int read_mv_component(vpx_reader *r,
                             const nmv_component *mvcomp, int usehp) {
  int mag, d, fr, hp;
  const int sign = vpx_read(r, mvcomp->sign);
  const int mv_class = vpx_read_tree(r, vp10_mv_class_tree, mvcomp->classes);
  const int class0 = mv_class == MV_CLASS_0;

  // Integer part
  if (class0) {
    d = vpx_read_tree(r, vp10_mv_class0_tree, mvcomp->class0);
    mag = 0;
  } else {
    int i;
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits

    d = 0;
    for (i = 0; i < n; ++i)
      d |= vpx_read(r, mvcomp->bits[i]) << i;
    mag = CLASS0_SIZE << (mv_class + 2);
  }

  // Fractional part
  fr = vpx_read_tree(r, vp10_mv_fp_tree, class0 ? mvcomp->class0_fp[d]
                                               : mvcomp->fp);

  // High precision part (if hp is not used, the default value of the hp is 1)
  hp = usehp ? vpx_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp)
             : 1;

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

static INLINE void read_mv(vpx_reader *r, MV *mv, const MV *ref,
                           const nmv_context *ctx,
                           nmv_context_counts *counts, int allow_hp) {
  const MV_JOINT_TYPE joint_type =
      (MV_JOINT_TYPE)vpx_read_tree(r, vp10_mv_joint_tree, ctx->joints);
  const int use_hp = allow_hp && vp10_use_mv_hp(ref);
  MV diff = {0, 0};

  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);

673
  vp10_inc_mv(&diff, counts, use_hp);
Jingning Han's avatar
Jingning Han committed
674 675 676 677 678

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

Yaowu Xu's avatar
Yaowu Xu committed
679
static REFERENCE_MODE read_block_reference_mode(VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695
                                                const MACROBLOCKD *xd,
                                                vpx_reader *r) {
  if (cm->reference_mode == REFERENCE_MODE_SELECT) {
    const int ctx = vp10_get_reference_mode_context(cm, xd);
    const REFERENCE_MODE mode =
        (REFERENCE_MODE)vpx_read(r, cm->fc->comp_inter_prob[ctx]);
    FRAME_COUNTS *counts = xd->counts;
    if (counts)
      ++counts->comp_inter[ctx][mode];
    return mode;  // SINGLE_REFERENCE or COMPOUND_REFERENCE
  } else {
    return cm->reference_mode;
  }
}

// Read the referncence frame
Yaowu Xu's avatar
Yaowu Xu committed
696
static void read_ref_frames(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
                            vpx_reader *r,
                            int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
  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) {
      const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
      const int ctx = vp10_get_pred_context_comp_ref_p(cm, xd);
712
      const int bit = vpx_read(r, fc->comp_ref_prob[ctx][0]);
Jingning Han's avatar
Jingning Han committed
713
      if (counts)
714
        ++counts->comp_ref[ctx][0][bit];
Jingning Han's avatar
Jingning Han committed
715
      ref_frame[idx] = cm->comp_fixed_ref;
716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739

#if CONFIG_EXT_REFS
      if (!bit) {
        const int ctx1 = vp10_get_pred_context_comp_ref_p1(cm, xd);
        const int bit1 = vpx_read(r, fc->comp_ref_prob[ctx1][1]);
        if (counts)
          ++counts->comp_ref[ctx1][1][bit1];
        ref_frame[!idx] = cm->comp_var_ref[bit1 ? 0 : 1];
      } else {
        const int ctx2 = vp10_get_pred_context_comp_ref_p2(cm, xd);
        const int bit2 = vpx_read(r, fc->comp_ref_prob[ctx2][2]);
        if (counts)
          ++counts->comp_ref[ctx2][2][bit2];
        if (!bit2) {
          const int ctx3 = vp10_get_pred_context_comp_ref_p3(cm, xd);
          const int bit3 = vpx_read(r, fc->comp_ref_prob[ctx3][3]);
          if (counts)
            ++counts->comp_ref[ctx3][3][bit3];
          ref_frame[!idx] = cm->comp_var_ref[bit3 ? 2 : 3];
        } else {
          ref_frame[!idx] = cm->comp_var_ref[4];
        }
      }
#else
Jingning Han's avatar
Jingning Han committed
740
      ref_frame[!idx] = cm->comp_var_ref[bit];
741
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
742
    } else if (mode == SINGLE_REFERENCE) {
743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
#if CONFIG_EXT_REFS
      const int ctx0 = vp10_get_pred_context_single_ref_p1(xd);
      const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]);
      if (counts)
        ++counts->single_ref[ctx0][0][bit0];
      if (bit0) {
        const int ctx1 = vp10_get_pred_context_single_ref_p2(xd);
        const int bit1 = vpx_read(r, fc->single_ref_prob[ctx1][1]);
        if (counts)
          ++counts->single_ref[ctx1][1][bit1];
        ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
      } else {
        const int ctx2 = vp10_get_pred_context_single_ref_p3(xd);
        const int bit2 = vpx_read(r, fc->single_ref_prob[ctx2][2]);
        if (counts)
          ++counts->single_ref[ctx2][2][bit2];
        if (bit2) {
          const int ctx4 = vp10_get_pred_context_single_ref_p5(xd);
          const int bit4 = vpx_read(r, fc->single_ref_prob[ctx4][4]);
          if (counts)
            ++counts->single_ref[ctx4][4][bit4];
          ref_frame[0] = bit4 ? LAST4_FRAME : LAST3_FRAME;
        } else {
          const int ctx3 = vp10_get_pred_context_single_ref_p4(xd);
          const int bit3 = vpx_read(r, fc->single_ref_prob[ctx3][3]);
          if (counts)
            ++counts->single_ref[ctx3][3][bit3];
          ref_frame[0] = bit3 ? LAST2_FRAME : LAST_FRAME;
        }
      }
#else
Jingning Han's avatar
Jingning Han committed
774 775 776 777 778 779 780 781 782 783 784 785 786
      const int ctx0 = vp10_get_pred_context_single_ref_p1(xd);
      const int bit0 = vpx_read(r, fc->single_ref_prob[ctx0][0]);
      if (counts)
        ++counts->single_ref[ctx0][0][bit0];
      if (bit0) {
        const int ctx1 = vp10_get_pred_context_single_ref_p2(xd);
        const int bit1 = vpx_read(r, fc->single_ref_prob[ctx1][1]);
        if (counts)
          ++counts->single_ref[ctx1][1][bit1];
        ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
      } else {
        ref_frame[0] = LAST_FRAME;
      }
787
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
788 789 790 791 792 793 794 795 796

      ref_frame[1] = NONE;
    } else {
      assert(0 && "Invalid prediction mode.");
    }
  }
}


797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
#if CONFIG_OBMC
static int read_is_obmc_block(VP10_COMMON *const cm, MACROBLOCKD *const xd,
                              vpx_reader *r) {
  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
  FRAME_COUNTS *counts = xd->counts;
  int is_obmc;

  if (is_obmc_allowed(&xd->mi[0]->mbmi)) {
    is_obmc = vpx_read(r, cm->fc->obmc_prob[bsize]);
    if (counts)
      ++counts->obmc[bsize][is_obmc];
    return is_obmc;
  } else {
    return 0;
  }
}
#endif  // CONFIG_OBMC

Jingning Han's avatar
Jingning Han committed
815
static INLINE INTERP_FILTER read_switchable_interp_filter(
Yaowu Xu's avatar
Yaowu Xu committed
816
    VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
817 818 819
    vpx_reader *r) {
  const int ctx = vp10_get_pred_context_switchable_interp(xd);
  FRAME_COUNTS *counts = xd->counts;
820 821
  INTERP_FILTER type;
#if CONFIG_EXT_INTERP
822
  if (!vp10_is_interp_needed(xd)) return EIGHTTAP_REGULAR;
823 824 825
#endif
  type = (INTERP_FILTER)vpx_read_tree(r, vp10_switchable_interp_tree,
                                      cm->fc->switchable_interp_prob[ctx]);
Jingning Han's avatar
Jingning Han committed
826 827 828 829 830
  if (counts)
    ++counts->switchable_interp[ctx][type];
  return type;
}

Yaowu Xu's avatar
Yaowu Xu committed
831
static void read_intra_block_mode_info(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860
                                       MACROBLOCKD *const xd, MODE_INFO *mi,
                                       vpx_reader *r) {
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
  int i;

  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 = read_intra_mode_y(cm, xd, r, 0);
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode = read_intra_mode_y(cm, xd,
                                                                  r, 0);
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
          read_intra_mode_y(cm, xd, r, 0);
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode = read_intra_mode_y(cm, xd,
                                                                  r, 0);
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
          read_intra_mode_y(cm, xd, r, 0);
      break;
    default:
      mbmi->mode = read_intra_mode_y(cm, xd, r, size_group_lookup[bsize]);
hui su's avatar
hui su committed
861 862
#if CONFIG_EXT_INTRA
      mbmi->angle_delta[0] = 0;
863 864
      if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
        int p_angle;
hui su's avatar
hui su committed
865 866
        mbmi->angle_delta[0] =
            read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
867 868 869 870 871 872 873 874 875 876 877 878 879
        p_angle =
            mode_to_angle_map[mbmi->mode] + mbmi->angle_delta[0] * ANGLE_STEP;
        if (pick_intra_filter(p_angle)) {
          FRAME_COUNTS *counts = xd->counts;
          const int ctx = vp10_get_pred_context_intra_interp(xd);
          mbmi->intra_filter = vpx_read_tree(r, vp10_intra_filter_tree,
                                             cm->fc->intra_filter_probs[ctx]);
          if (counts)
            ++counts->intra_filter[ctx][mbmi->intra_filter];
        } else {
          mbmi->intra_filter = INTRA_FILTER_LINEAR;
        }
      }
hui su's avatar
hui su committed
880
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
881 882 883
  }

  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
884 885 886 887 888 889
#if CONFIG_EXT_INTRA
  if (mbmi->uv_mode != DC_PRED && mbmi->uv_mode != TM_PRED &&
      bsize >= BLOCK_8X8)
    mbmi->angle_delta[1] =
        read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
#endif  // CONFIG_EXT_INTRA
hui su's avatar
hui su committed
890 891
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
892 893
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools)
    read_palette_mode_info(cm, xd, r);
hui su's avatar
hui su committed
894 895 896 897 898 899
#if CONFIG_EXT_INTRA
  mbmi->ext_intra_mode_info.use_ext_intra_mode[0] = 0;
  mbmi->ext_intra_mode_info.use_ext_intra_mode[1] = 0;
  if (bsize >= BLOCK_8X8)
    read_ext_intra_mode_info(cm, xd, r);
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
900 901 902 903 904 905 906
}

static INLINE int is_mv_valid(const MV *mv) {
  return mv->row > MV_LOW && mv->row < MV_UPP &&
         mv->col > MV_LOW && mv->col < MV_UPP;
}

Yaowu Xu's avatar
Yaowu Xu committed
907
static INLINE int assign_mv(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
908
                            PREDICTION_MODE mode,
Jingning Han's avatar
Jingning Han committed
909 910 911
#if CONFIG_REF_MV
                            int block,
#endif
Jingning Han's avatar
Jingning Han committed
912 913 914 915 916
                            int_mv mv[2], int_mv ref_mv[2],
                            int_mv nearest_mv[2], int_mv near_mv[2],
                            int is_compound, int allow_hp, vpx_reader *r) {
  int i;
  int ret = 1;
Jingning Han's avatar
Jingning Han committed
917 918 919 920 921 922
#if CONFIG_REF_MV
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
  BLOCK_SIZE bsize = mbmi->sb_type;
  int_mv *pred_mv = (bsize >= BLOCK_8X8) ?
      mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv;
#endif
Jingning Han's avatar
Jingning Han committed
923 924

  switch (mode) {
Yue Chen's avatar
Yue Chen committed
925 926 927
#if CONFIG_EXT_INTER
    case NEWFROMNEARMV:
#endif  // CONFIG_EXT_INTER
Jingning Han's avatar
Jingning Han committed
928 929
    case NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
930
#if !CONFIG_REF_MV
Jingning Han's avatar
Jingning Han committed
931
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
932
#endif
Jingning Han's avatar
Jingning Han committed
933
      for (i = 0; i < 1 + is_compound; ++i) {
934 935 936 937 938 939 940 941
#if CONFIG_REF_MV
        int nmv_ctx = vp10_nmv_ctx(xd->ref_mv_count[mbmi->ref_frame[i]],
                                   xd->ref_mv_stack[mbmi->ref_frame[i]]);
        nmv_context_counts *const mv_counts =
            counts ? &counts->mv[nmv_ctx] : NULL;
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc[nmv_ctx],
                mv_counts, allow_hp);
#else
Jingning Han's avatar
Jingning Han committed
942 943
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
                allow_hp);
944
#endif
Jingning Han's avatar
Jingning Han committed
945
        ret = ret && is_mv_valid(&mv[i].as_mv);
Jingning Han's avatar
Jingning Han committed
946 947 948 949

#if CONFIG_REF_MV
        pred_mv[i].as_int = ref_mv[i].as_int;
#endif
Jingning Han's avatar
Jingning Han committed
950 951 952 953 954 955 956
      }
      break;
    }
    case NEARESTMV: {
      mv[0].as_int = nearest_mv[0].as_int;
      if (is_compound)
        mv[1].as_int = nearest_mv[1].as_int;
Jingning Han's avatar
Jingning Han committed
957 958 959 960 961 962

#if CONFIG_REF_MV
      pred_mv[0].as_int = nearest_mv[0].as_int;
      if (is_compound)
        pred_mv[1].as_int = nearest_mv[1].as_int;
#endif
Jingning Han's avatar
Jingning Han committed
963 964 965 966 967 968
      break;
    }
    case NEARMV: {
      mv[0].as_int = near_mv[0].as_int;
      if (is_compound)
        mv[1].as_int = near_mv[1].as_int;
Jingning Han's avatar
Jingning Han committed
969 970 971 972 973 974

#if CONFIG_REF_MV
      pred_mv[0].as_int = near_mv[0].as_int;
      if (is_compound)
        pred_mv[1].as_int = near_mv[1].as_int;
#endif
Jingning Han's avatar
Jingning Han committed
975 976 977 978 979 980
      break;
    }
    case ZEROMV: {
      mv[0].as_int = 0;
      if (is_compound)
        mv[1].as_int = 0;
Jingning Han's avatar
Jingning Han committed
981 982 983 984 985 986

#if CONFIG_REF_MV
      pred_mv[0].as_int = 0;
      if (is_compound)
        pred_mv[1].as_int = 0;
#endif
Jingning Han's avatar
Jingning Han committed
987 988
      break;
    }
989 990 991
#if CONFIG_EXT_INTER
    case NEW_NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
992
#if !CONFIG_REF_MV
993
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
994
#endif
995 996
      assert(is_compound);
      for (i = 0; i < 2; ++i) {
997 998 999 1000 1001 1002 1003 1004 1005
#if CONFIG_REF_MV
        int nmv_ctx = vp10_nmv_ctx(xd->ref_mv_count[mbmi->ref_frame[i]],
                                   xd->ref_mv_stack[mbmi->ref_frame[i]]);
        nmv_context_counts *const mv_counts =
            counts ? &counts->mv[nmv_ctx] : NULL;
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv,
                &cm->fc->nmvc[nmv_ctx], mv_counts,
                allow_hp);
#else
1006 1007
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
                allow_hp);
1008
#endif
1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
        ret = ret && is_mv_valid(&mv[i].as_mv);
      }
      break;
    }
    case NEAREST_NEARESTMV: {
      assert(is_compound);
      mv[0].as_int = nearest_mv[0].as_int;
      mv[1].as_int = nearest_mv[1].as_int;
      break;
    }
    case NEAREST_NEARMV: {
      assert(is_compound);
      mv[0].as_int = nearest_mv[0].as_int;
      mv[1].as_int = near_mv[1].as_int;
      break;
    }
    case NEAR_NEARESTMV: {
      assert(is_compound);
      mv[0].as_int = near_mv[0].as_int;
      mv[1].as_int = nearest_mv[1].as_int;
      break;
    }
    case NEW_NEARESTMV: {
      FRAME_COUNTS *counts = xd->counts;
1033 1034 1035 1036 1037 1038 1039 1040 1041
#if CONFIG_REF_MV
      int nmv_ctx = vp10_nmv_ctx(xd->ref_mv_count[mbmi->ref_frame[0]],
                                 xd->ref_mv_stack[mbmi->ref_frame[0]]);
      nmv_context_counts *const mv_counts =
          counts ? &counts->mv[nmv_ctx] : NULL;
      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv,
              &cm->fc->nmvc[nmv_ctx], mv_counts,
              allow_hp);
#else
1042 1043 1044
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
              allow_hp);
1045 1046
#endif
      assert(is_compound);
1047 1048 1049 1050 1051 1052
      ret = ret && is_mv_valid(&mv[0].as_mv);
      mv[1].as_int = nearest_mv[1].as_int;
      break;
    }
    case NEAREST_NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
#if CONFIG_REF_MV
      int nmv_ctx = vp10_nmv_ctx(xd->ref_mv_count[mbmi->ref_frame[1]],
                                 xd->ref_mv_stack[mbmi->ref_frame[1]]);
      nmv_context_counts *const mv_counts =
          counts ? &counts->mv[nmv_ctx] : NULL;
      mv[0].as_int = nearest_mv[0].as_int;
      read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv,
              &cm->fc->nmvc[nmv_ctx], mv_counts,
              allow_hp);
#else
1063 1064 1065 1066
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      mv[0].as_int = nearest_mv[0].as_int;
      read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv, &cm->fc->nmvc, mv_counts,
              allow_hp);
1067 1068
#endif
      assert(is_compound);
1069 1070 1071 1072 1073
      ret = ret && is_mv_valid(&mv[1].as_mv);
      break;
    }
    case NEAR_NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
#if CONFIG_REF_MV
      int nmv_ctx = vp10_nmv_ctx(xd->ref_mv_count[mbmi->ref_frame[1]],
                                 xd->ref_mv_stack[mbmi->ref_frame[1]]);
      nmv_context_counts *const mv_counts =
          counts ? &counts->mv[nmv_ctx] : NULL;
      mv[0].as_int = near_mv[0].as_int;
      read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv,
              &cm->fc->nmvc[nmv_ctx], mv_counts,
              allow_hp);
#else
1084 1085 1086 1087
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      mv[0].as_int = near_mv[0].as_int;
      read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv, &cm->fc->nmvc, mv_counts,
              allow_hp);
1088 1089 1090
#endif
      assert(is_compound);

1091 1092 1093 1094 1095
      ret = ret && is_mv_valid(&mv[1].as_mv);
      break;
    }
    case NEW_NEARMV: {
      FRAME_COUNTS *counts = xd->counts;
1096 1097 1098 1099 1100 1101 1102 1103 1104
#if CONFIG_REF_MV
      int nmv_ctx = vp10_nmv_ctx(xd->ref_mv_count[mbmi->ref_frame[0]],
                                 xd->ref_mv_stack[mbmi->ref_frame[0]]);
      nmv_context_counts *const mv_counts =
          counts ? &counts->mv[nmv_ctx] : NULL;
      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv,
              &cm->fc->nmvc[nmv_ctx], mv_counts,
              allow_hp);
#else
1105 1106 1107
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
              allow_hp);
1108 1109
#endif
      assert(is_compound);
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
      ret = ret && is_mv_valid(&mv[0].as_mv);
      mv[1].as_int = near_mv[1].as_int;
      break;
    }
    case ZERO_ZEROMV: {
      assert(is_compound);
      mv[0].as_int = 0;
      mv[1].as_int = 0;
      break;
    }
#endif  // CONFIG_EXT_INTER
Jingning Han's avatar
Jingning Han committed
1121 1122 1123 1124 1125 1126 1127
    default: {
      return 0;
    }
  }
  return ret;
}

Yaowu Xu's avatar
Yaowu Xu committed
1128
static int read_is_inter_block(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142
                               int segment_id, vpx_reader *r) {
  if (segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
    return get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) != INTRA_FRAME;
  } else {
    const int ctx = vp10_get_intra_inter_context(xd);
    const int is_inter = vpx_read(r, cm->fc->intra_inter_prob[ctx]);
    FRAME_COUNTS *counts = xd->counts;
    if (counts)
      ++counts->intra_inter[ctx][is_inter];
    return is_inter;
  }
}

static void fpm_sync(void *const data, int mi_row) {
Yaowu Xu's avatar
Yaowu Xu committed
1143
  VP10Decoder *const pbi = (VP10Decoder *)data;
Jingning Han's avatar
Jingning Han committed
1144 1145 1146 1147
  vp10_frameworker_wait(pbi->frame_worker_owner, pbi->common.prev_frame,
                       mi_row << MI_BLOCK_SIZE_LOG2);
}

Yaowu Xu's avatar
Yaowu Xu committed
1148
static void read_inter_block_mode_info(VP10Decoder *const pbi,
Jingning Han's avatar
Jingning Han committed
1149 1150
                                       MACROBLOCKD *const xd,
                                       MODE_INFO *const mi,
1151
#if (CONFIG_OBMC || CONFIG_EXT_INTER) && CONFIG_SUPERTX
1152 1153 1154
                                       int mi_row, int mi_col, vpx_reader *r,
                                       int supertx_enabled) {
#else
Jingning Han's avatar
Jingning Han committed
1155
                                       int mi_row, int mi_col, vpx_reader *r) {
1156
#endif  // CONFIG_OBMC && CONFIG_SUPERTX
Yaowu Xu's avatar
Yaowu Xu committed
1157
  VP10_COMMON *const cm = &pbi->common;
Jingning Han's avatar
Jingning Han committed
1158 1159 1160 1161
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const BLOCK_SIZE bsize = mbmi->sb_type;
  const int allow_hp = cm->allow_high_precision_mv;
  int_mv nearestmv[2], nearmv[2];
1162
  int_mv ref_mvs[MODE_CTX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
Yue Chen's avatar
Yue Chen committed
1163 1164 1165
#if CONFIG_EXT_INTER
  int mv_idx;
#endif  // CONFIG_EXT_INTER
Jingning Han's avatar
Jingning Han committed
1166
  int ref, is_compound;
1167
  int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
1168 1169 1170
#if CONFIG_REF_MV && CONFIG_EXT_INTER
  int16_t compound_inter_mode_ctx[MODE_CTX_REF_FRAMES];
#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
1171
  int16_t mode_ctx = 0;
1172
  MV_REFERENCE_FRAME ref_frame;
Jingning Han's avatar
Jingning Han committed
1173

1174 1175 1176
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;

Jingning Han's avatar
Jingning Han committed
1177 1178 1179 1180
  read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
  is_compound = has_second_ref(mbmi);

  for (ref = 0; ref < 1 + is_compound; ++ref) {
1181
    MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
Jingning Han's avatar
Jingning Han committed
1182 1183 1184 1185 1186 1187 1188 1189
    RefBuffer *ref_buf = &cm->frame_refs[frame - LAST_FRAME];

    xd->block_refs[ref] = ref_buf;
    if ((!vp10_is_valid_scale(&ref_buf->sf)))
      vpx_internal_error(xd->error_info, VPX_CODEC_UNSUP_BITSTREAM,
                         "Reference frame has invalid dimensions");
    vp10_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
                         &ref_buf->sf);
1190 1191
  }

1192
  for (ref_frame = LAST_FRAME; ref_frame < MODE_CTX_REF_FRAMES; ++ref_frame) {
1193
    vp10_find_mv_refs(cm, xd, mi, ref_frame,
1194
#if CONFIG_REF_MV
1195 1196
                      &xd->ref_mv_count[ref_frame],
                      xd->ref_mv_stack[ref_frame],
1197 1198 1199
#if CONFIG_EXT_INTER
                      compound_inter_mode_ctx,
#endif  // CONFIG_EXT_INTER
1200
#endif