decodemv.c 50.1 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
276
277
278
279
280
281
282
283
284
285
286
287
288
                                     TX_SIZE max_tx_size, vpx_reader *r) {
  FRAME_COUNTS *counts = xd->counts;
  const int ctx = get_tx_size_context(xd);
  const vpx_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc->tx_probs);
  int tx_size = vpx_read(r, tx_probs[0]);
  if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
    tx_size += vpx_read(r, tx_probs[1]);
    if (tx_size != TX_8X8 && max_tx_size >= TX_32X32)
      tx_size += vpx_read(r, tx_probs[2]);
  }

  if (counts)
    ++get_tx_counts(max_tx_size, ctx, &counts->tx)[tx_size];
  return (TX_SIZE)tx_size;
}

Yaowu Xu's avatar
Yaowu Xu committed
289
static TX_SIZE read_tx_size(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
290
291
292
293
                            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];
294
295
  if (xd->lossless[xd->mi[0]->mbmi.segment_id])
    return TX_4X4;
Jingning Han's avatar
Jingning Han committed
296
297
298
  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
    return read_selected_tx_size(cm, xd, max_tx_size, r);
  else
299
    return VPXMIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]);
Jingning Han's avatar
Jingning Han committed
300
301
}

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

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

Yaowu Xu's avatar
Yaowu Xu committed
315
static void set_segment_id(VP10_COMMON *cm, int mi_offset,
Jingning Han's avatar
Jingning Han committed
316
317
318
319
320
321
322
323
324
325
                           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;
}

326
327
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
328
329
                                 vpx_reader *r) {
  struct segmentation *const seg = &cm->seg;
330
331
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
332
333
334
335
336
  int segment_id;

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

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

339
340
341
  segment_id = read_segment_id(r, segp);
  if (counts)
    ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
342
343
344
345
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

346
347
348
349
350
351
352
353
354
355
356
357
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
358
static int read_inter_segment_id(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
359
360
                                 int mi_row, int mi_col, vpx_reader *r) {
  struct segmentation *const seg = &cm->seg;
361
362
  FRAME_COUNTS *counts = xd->counts;
  struct segmentation_probs *const segp = &cm->fc->seg;
Jingning Han's avatar
Jingning Han committed
363
364
365
366
367
368
369
  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 ?????
370
371
  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
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386

  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) {
387
388
    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
389
    mbmi->seg_id_predicted = vpx_read(r, pred_prob);
390
391
392
393
394
395
396
397
398
    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
399
  } else {
400
401
402
    segment_id = read_segment_id(r, segp);
    if (counts)
      ++counts->seg.tree_total[segment_id];
Jingning Han's avatar
Jingning Han committed
403
404
405
406
407
  }
  set_segment_id(cm, mi_offset, x_mis, y_mis, segment_id);
  return segment_id;
}

Yaowu Xu's avatar
Yaowu Xu committed
408
static int read_skip(VP10_COMMON *cm, const MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
409
410
411
412
413
414
415
416
417
418
419
420
421
                     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
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
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;
  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, palette_ctx = 0;

  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])) {
    int n;
    PALETTE_MODE_INFO *pmi = &mbmi->palette_mode_info;

    pmi->palette_size[0] =
        vpx_read_tree(r, vp10_palette_size_tree,
                      vp10_default_palette_y_size_prob[bsize - BLOCK_8X8]) + 2;
    n = pmi->palette_size[0];

    for (i = 0; i < n; ++i)
      pmi->palette_colors[i] = vpx_read_literal(r, cm->bit_depth);

    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
454
455
456
457
458
459
#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
460
461
462
463

#if !ALLOW_FILTER_INTRA_MODES
  return;
#endif
hui su's avatar
hui su committed
464
465
466
467
  if (mbmi->mode == DC_PRED) {
    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
468
469
      mbmi->ext_intra_mode_info.ext_intra_mode[0] =
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
470
471
472
473
474
475
476
477
    }
    if (counts)
      ++counts->ext_intra[0][mbmi->ext_intra_mode_info.use_ext_intra_mode[0]];
  }
  if (mbmi->uv_mode == DC_PRED) {
    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
478
479
      mbmi->ext_intra_mode_info.ext_intra_mode[1] =
          read_uniform(r, FILTER_INTRA_MODES);
hui su's avatar
hui su committed
480
481
482
483
484
485
486
    }
    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
487
static void read_intra_frame_mode_info(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
488
489
490
491
492
493
494
495
496
497
498
499
500
                                       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 ?????
501
502
  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
503

504
  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_offset, x_mis, y_mis, r);
Jingning Han's avatar
Jingning Han committed
505
506
507
508
509
510
511
512
513
  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 =
514
            read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, i));
Jingning Han's avatar
Jingning Han committed
515
516
517
518
      mbmi->mode = mi->bmi[3].as_mode;
      break;
    case BLOCK_4X8:
      mi->bmi[0].as_mode = mi->bmi[2].as_mode =
519
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
520
      mi->bmi[1].as_mode = mi->bmi[3].as_mode = mbmi->mode =
521
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 1));
Jingning Han's avatar
Jingning Han committed
522
523
524
      break;
    case BLOCK_8X4:
      mi->bmi[0].as_mode = mi->bmi[1].as_mode =
525
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
Jingning Han's avatar
Jingning Han committed
526
      mi->bmi[2].as_mode = mi->bmi[3].as_mode = mbmi->mode =
527
          read_intra_mode(r, get_y_mode_probs(cm, mi, above_mi, left_mi, 2));
Jingning Han's avatar
Jingning Han committed
528
529
530
      break;
    default:
      mbmi->mode = read_intra_mode(r,
531
          get_y_mode_probs(cm, mi, above_mi, left_mi, 0));
hui su's avatar
hui su committed
532
#if CONFIG_EXT_INTRA
533
534
535
      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
536
537
        mbmi->angle_delta[0] =
            read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
538
539
540
541
542
543
544
545
546
547
548
549
        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
550
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
551
552
  }

553
  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
554
555
556
557
558
559
#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
560

hui su's avatar
hui su committed
561
562
563
564
565
566
  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
  if (bsize >= BLOCK_8X8 && cm->allow_screen_content_tools &&
      mbmi->mode == DC_PRED)
    read_palette_mode_info(cm, xd, r);

567
#if CONFIG_EXT_TX
568
569
    if (get_ext_tx_types(mbmi->tx_size, mbmi->sb_type, 0) > 1 &&
        cm->base_qindex > 0 && !mbmi->skip &&
570
571
        !segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&
        ALLOW_INTRA_EXT_TX) {
Jingning Han's avatar
Jingning Han committed
572
      FRAME_COUNTS *counts = xd->counts;
573
574
575
576
577
578
579
580
581
      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]
                                [mbmi->tx_type];
      }
582
    } else {
hui su's avatar
hui su committed
583
      mbmi->tx_type = DCT_DCT;
584
    }
585
#else
586
587
588
589
590
591
592
593
594
595
596
597
598
  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;
  }
599
#endif  // CONFIG_EXT_TX
hui su's avatar
hui su committed
600
601
602
603
604
605
606

#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
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
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
}

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

657
  vp10_inc_mv(&diff, counts, use_hp);
Jingning Han's avatar
Jingning Han committed
658
659
660
661
662

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

Yaowu Xu's avatar
Yaowu Xu committed
663
static REFERENCE_MODE read_block_reference_mode(VP10_COMMON *cm,
Jingning Han's avatar
Jingning Han committed
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
                                                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
680
static void read_ref_frames(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
                            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);
696
      const int bit = vpx_read(r, fc->comp_ref_prob[ctx][0]);
Jingning Han's avatar
Jingning Han committed
697
      if (counts)
698
        ++counts->comp_ref[ctx][0][bit];
Jingning Han's avatar
Jingning Han committed
699
      ref_frame[idx] = cm->comp_fixed_ref;
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723

#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
724
      ref_frame[!idx] = cm->comp_var_ref[bit];
725
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
726
    } else if (mode == SINGLE_REFERENCE) {
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
752
753
754
755
756
757
#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
758
759
760
761
762
763
764
765
766
767
768
769
770
      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;
      }
771
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
772
773
774
775
776
777
778
779
780
781

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


static INLINE INTERP_FILTER read_switchable_interp_filter(
Yaowu Xu's avatar
Yaowu Xu committed
782
    VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
783
784
785
    vpx_reader *r) {
  const int ctx = vp10_get_pred_context_switchable_interp(xd);
  FRAME_COUNTS *counts = xd->counts;
786
787
788
789
790
791
  INTERP_FILTER type;
#if CONFIG_EXT_INTERP
  if (!vp10_is_interp_needed(xd)) return EIGHTTAP;
#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
792
793
794
795
796
  if (counts)
    ++counts->switchable_interp[ctx][type];
  return type;
}

Yaowu Xu's avatar
Yaowu Xu committed
797
static void read_intra_block_mode_info(VP10_COMMON *const cm,
Jingning Han's avatar
Jingning Han committed
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
                                       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
827
828
#if CONFIG_EXT_INTRA
      mbmi->angle_delta[0] = 0;
829
830
      if (mbmi->mode != DC_PRED && mbmi->mode != TM_PRED) {
        int p_angle;
hui su's avatar
hui su committed
831
832
        mbmi->angle_delta[0] =
            read_uniform(r, 2 * MAX_ANGLE_DELTAS + 1) - MAX_ANGLE_DELTAS;
833
834
835
836
837
838
839
840
841
842
843
844
845
        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
846
#endif  // CONFIG_EXT_INTRA
Jingning Han's avatar
Jingning Han committed
847
848
849
  }

  mbmi->uv_mode = read_intra_mode_uv(cm, xd, r, mbmi->mode);
hui su's avatar
hui su committed
850
851
852
853
854
855
#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
856
857
858

  mbmi->palette_mode_info.palette_size[0] = 0;
  mbmi->palette_mode_info.palette_size[1] = 0;
hui su's avatar
hui su committed
859
860
861
862
863
864
#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
865
866
867
868
869
870
871
}

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
872
static INLINE int assign_mv(VP10_COMMON *cm, MACROBLOCKD *xd,
Jingning Han's avatar
Jingning Han committed
873
874
875
876
877
878
879
880
                            PREDICTION_MODE mode,
                            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;

  switch (mode) {
Yue Chen's avatar
Yue Chen committed
881
882
883
#if CONFIG_EXT_INTER
    case NEWFROMNEARMV:
#endif  // CONFIG_EXT_INTER
Jingning Han's avatar
Jingning Han committed
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
    case NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      for (i = 0; i < 1 + is_compound; ++i) {
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
                allow_hp);
        ret = ret && is_mv_valid(&mv[i].as_mv);
      }
      break;
    }
    case NEARESTMV: {
      mv[0].as_int = nearest_mv[0].as_int;
      if (is_compound)
        mv[1].as_int = nearest_mv[1].as_int;
      break;
    }
    case NEARMV: {
      mv[0].as_int = near_mv[0].as_int;
      if (is_compound)
        mv[1].as_int = near_mv[1].as_int;
      break;
    }
    case ZEROMV: {
      mv[0].as_int = 0;
      if (is_compound)
        mv[1].as_int = 0;
      break;
    }
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
#if CONFIG_EXT_INTER
    case NEW_NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      assert(is_compound);
      for (i = 0; i < 2; ++i) {
        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
                allow_hp);
        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;
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      assert(is_compound);
      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
              allow_hp);
      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;
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      assert(is_compound);
      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);
      ret = ret && is_mv_valid(&mv[1].as_mv);
      break;
    }
    case NEAR_NEWMV: {
      FRAME_COUNTS *counts = xd->counts;
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      assert(is_compound);
      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);
      ret = ret && is_mv_valid(&mv[1].as_mv);
      break;
    }
    case NEW_NEARMV: {
      FRAME_COUNTS *counts = xd->counts;
      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
      assert(is_compound);
      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
              allow_hp);
      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
989
990
991
992
993
994
995
    default: {
      return 0;
    }
  }
  return ret;
}

Yaowu Xu's avatar
Yaowu Xu committed
996
static int read_is_inter_block(VP10_COMMON *const cm, MACROBLOCKD *const xd,
Jingning Han's avatar
Jingning Han committed
997
998
999
1000
                               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 {
For faster browsing, not all history is shown. View entire blame