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

11
12
#include <assert.h>

13
14
#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_entropy.h"
15
#include "vp9/common/vp9_entropymode.h"
16
#include "vp9/common/vp9_entropymv.h"
17
#include "vp9/common/vp9_findnearmv.h"
18
#include "vp9/common/vp9_mvref_common.h"
19
#include "vp9/common/vp9_pred_common.h"
20
21
22
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_seg_common.h"

23
#include "vp9/decoder/vp9_decodemv.h"
24
#include "vp9/decoder/vp9_decodframe.h"
25
#include "vp9/decoder/vp9_onyxd_int.h"
26
#include "vp9/decoder/vp9_dsubexp.h"
27
28
#include "vp9/decoder/vp9_treereader.h"

John Koleszar's avatar
John Koleszar committed
29
// #define DEBUG_DEC_MV
30
31
32
#ifdef DEBUG_DEC_MV
int dec_mvcount = 0;
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
33

34
35
36
37
// #define DEC_DEBUG
#ifdef DEC_DEBUG
extern int dec_debug;
#endif
38

39
static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
40
41
42
43
44
  return (MB_PREDICTION_MODE)treed_read(r, vp9_intra_mode_tree, p);
}

static MB_PREDICTION_MODE read_inter_mode(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(r, vp9_sb_mv_ref_tree, p);
45
46
}

47
48
static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
  return treed_read(r, vp9_segment_tree, seg->tree_probs);
Scott LaVarnway's avatar
Scott LaVarnway committed
49
}
50

51
52
static TX_SIZE read_selected_txfm_size(VP9_COMMON *cm, MACROBLOCKD *xd,
                                       BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
53
54
  const int context = vp9_get_pred_context_tx_size(cm, xd);
  const vp9_prob *tx_probs = vp9_get_pred_probs_tx_size(cm, xd);
55
56
57
58
59
60
61
62
  TX_SIZE txfm_size = vp9_read(r, tx_probs[0]);
  if (txfm_size != TX_4X4 && bsize >= BLOCK_SIZE_MB16X16) {
    txfm_size += vp9_read(r, tx_probs[1]);
    if (txfm_size != TX_8X8 && bsize >= BLOCK_SIZE_SB32X32)
      txfm_size += vp9_read(r, tx_probs[2]);
  }

  if (bsize >= BLOCK_SIZE_SB32X32)
63
    cm->fc.tx_counts.p32x32[context][txfm_size]++;
64
  else if (bsize >= BLOCK_SIZE_MB16X16)
65
    cm->fc.tx_counts.p16x16[context][txfm_size]++;
66
  else
67
    cm->fc.tx_counts.p8x8[context][txfm_size]++;
68
69
70
71

  return txfm_size;
}

72
73
74
static TX_SIZE read_txfm_size(VP9D_COMP *pbi, TXFM_MODE txfm_mode,
                              BLOCK_SIZE_TYPE bsize, int select_cond,
                              vp9_reader *r) {
75
76
77
78
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

  if (txfm_mode == TX_MODE_SELECT && bsize >= BLOCK_SIZE_SB8X8 && select_cond)
79
    return read_selected_txfm_size(cm, xd, bsize, r);
80
81
82
83
84
85
86
87
88
89
  else if (txfm_mode >= ALLOW_32X32 && bsize >= BLOCK_SIZE_SB32X32)
    return TX_32X32;
  else if (txfm_mode >= ALLOW_16X16 && bsize >= BLOCK_SIZE_MB16X16)
    return TX_16X16;
  else if (txfm_mode >= ALLOW_8X8 && bsize >= BLOCK_SIZE_SB8X8)
    return TX_8X8;
  else
    return TX_4X4;
}

90
static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize,
91
                           int mi_row, int mi_col, int segment_id) {
92
93
94
  const int mi_offset = mi_row * cm->mi_cols + mi_col;
  const int bw = 1 << mi_width_log2(bsize);
  const int bh = 1 << mi_height_log2(bsize);
95
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
96
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
97
98
  int x, y;

99
100
101
102
103
104
105
106
107
108
  assert(segment_id >= 0 && segment_id < MAX_MB_SEGMENTS);

  for (y = 0; y < ymis; y++)
    for (x = 0; x < xmis; x++)
      cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}

static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
                                 vp9_reader *r) {
  MACROBLOCKD *const xd = &pbi->mb;
109
  struct segmentation *const seg = &xd->seg;
110
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
111
  int segment_id;
112

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

  if (!seg->update_map)
117
    return 0;
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

  segment_id = read_segment_id(r, seg);
  set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id);
  return segment_id;
}

static int read_inter_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
                                 vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
  struct segmentation *const seg = &xd->seg;
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
  int pred_segment_id, segment_id;

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

  pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
                                       bsize, mi_row, mi_col);
  if (!seg->update_map)
    return pred_segment_id;

  if (seg->temporal_update) {
    const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(xd);
    const int pred_flag = vp9_read(r, pred_prob);
143
    vp9_set_pred_flag_seg_id(cm, bsize, mi_row, mi_col, pred_flag);
144
145
146
147
    segment_id = pred_flag ? pred_segment_id
                           : read_segment_id(r, seg);
  } else {
    segment_id = read_segment_id(r, seg);
148
  }
149
150
  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
  return segment_id;
151
152
}

153
static uint8_t read_skip_coeff(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
154
  VP9_COMMON *const cm = &pbi->common;
155
  MACROBLOCKD *const xd = &pbi->mb;
156
  int skip_coeff = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP);
157
  if (!skip_coeff) {
158
    const int ctx = vp9_get_pred_context_mbskip(xd);
159
    skip_coeff = vp9_read(r, vp9_get_pred_prob_mbskip(cm, xd));
160
    cm->fc.mbskip_count[ctx][skip_coeff]++;
Deb Mukherjee's avatar
Deb Mukherjee committed
161
  }
162
163
  return skip_coeff;
}
John Koleszar's avatar
John Koleszar committed
164

165
166
167
168
169
170
171
static void read_intra_mode_info(VP9D_COMP *pbi, MODE_INFO *m,
                                 int mi_row, int mi_col, vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
  MB_MODE_INFO *const mbmi = &m->mbmi;
  const BLOCK_SIZE_TYPE bsize = mbmi->sb_type;
  const int mis = cm->mode_info_stride;
172

173
174
  mbmi->segment_id = read_intra_segment_id(pbi, mi_row, mi_col, r);
  mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
175
  mbmi->txfm_size = read_txfm_size(pbi, cm->txfm_mode, bsize, 1, r);
176
177
178
  mbmi->ref_frame[0] = INTRA_FRAME;

  if (bsize >= BLOCK_SIZE_SB8X8) {
179
180
181
    const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
    const MB_PREDICTION_MODE L = xd->left_available ?
                                  left_block_mode(m, 0) : DC_PRED;
182
    mbmi->mode = read_intra_mode(r, cm->kf_y_mode_prob[A][L]);
183
  } else {
184
185
186
    // Only 4x4, 4x8, 8x4 blocks
    const int bw = 1 << b_width_log2(bsize);
    const int bh = 1 << b_height_log2(bsize);
187
    int idx, idy;
188
189
190

    for (idy = 0; idy < 2; idy += bh) {
      for (idx = 0; idx < 2; idx += bw) {
191
        const int ib = idy * 2 + idx;
192
193
194
        const MB_PREDICTION_MODE A = above_block_mode(m, ib, mis);
        const MB_PREDICTION_MODE L = (xd->left_available || idx) ?
                                      left_block_mode(m, ib) : DC_PRED;
195
196
        const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
                                              cm->kf_y_mode_prob[A][L]);
197
        m->bmi[ib].as_mode = b_mode;
198
        if (bh == 2)
199
          m->bmi[ib + 2].as_mode = b_mode;
200
        if (bw == 2)
201
          m->bmi[ib + 1].as_mode = b_mode;
202
203
      }
    }
204

205
    mbmi->mode = m->bmi[3].as_mode;
John Koleszar's avatar
John Koleszar committed
206
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
207

208
  mbmi->uv_mode = read_intra_mode(r, cm->kf_uv_mode_prob[mbmi->mode]);
Scott LaVarnway's avatar
Scott LaVarnway committed
209
}
John Koleszar's avatar
John Koleszar committed
210

211
212
static int read_mv_component(vp9_reader *r,
                             const nmv_component *mvcomp, int usehp) {
213

214
  int mag, d, fr, hp;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
215
216
  const int sign = vp9_read(r, mvcomp->sign);
  const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
217
  const int class0 = mv_class == MV_CLASS_0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
218

219
  // Integer part
220
  if (class0) {
221
    d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
222
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
223
    int i;
224
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits
Dmitry Kovalev's avatar
Dmitry Kovalev committed
225

226
    d = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
227
228
    for (i = 0; i < n; ++i)
      d |= vp9_read(r, mvcomp->bits[i]) << i;
229
230
  }

231
232
  // Fractional part
  fr = treed_read(r, vp9_mv_fp_tree,
233
                  class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
234
235


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

240
  // Result
241
242
  mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
  return sign ? -mag : mag;
243
244
}

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
static INLINE void read_mv(vp9_reader *r, MV *mv, const MV *ref,
                           const nmv_context *ctx,
                           nmv_context_counts *counts, int usehp) {
  const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
  MV diff = {0, 0};

  usehp = usehp && vp9_use_mv_hp(ref);
  if (mv_joint_vertical(j))
    diff.row = read_mv_component(r, &ctx->comps[0], usehp);

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

  vp9_inc_mv(&diff, ref, counts, usehp);

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

264
static void update_mv(vp9_reader *r, vp9_prob *p, vp9_prob upd_p) {
265
  if (vp9_read(r, upd_p)) {
266
#ifdef LOW_PRECISION_MV_UPDATE
267
    *p = (vp9_read_literal(r, 7) << 1) | 1;
268
#else
269
    *p = vp9_read_literal(r, 8);
270
271
272
273
#endif
  }
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
274
static void read_mv_probs(vp9_reader *r, nmv_context *mvc, int usehp) {
275
  int i, j, k;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276
277

  for (j = 0; j < MV_JOINTS - 1; ++j)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
278
    update_mv(r, &mvc->joints[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
279

280
  for (i = 0; i < 2; ++i) {
281
282
283
    nmv_component *const comp = &mvc->comps[i];

    update_mv(r, &comp->sign, VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
284
    for (j = 0; j < MV_CLASSES - 1; ++j)
285
      update_mv(r, &comp->classes[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
286
287

    for (j = 0; j < CLASS0_SIZE - 1; ++j)
288
      update_mv(r, &comp->class0[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
289
290

    for (j = 0; j < MV_OFFSET_BITS; ++j)
291
      update_mv(r, &comp->bits[j], VP9_NMV_UPDATE_PROB);
292
293
294
  }

  for (i = 0; i < 2; ++i) {
295
296
    nmv_component *const comp = &mvc->comps[i];

297
    for (j = 0; j < CLASS0_SIZE; ++j)
298
      for (k = 0; k < 3; ++k)
299
        update_mv(r, &comp->class0_fp[j][k], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
300
301

    for (j = 0; j < 3; ++j)
302
      update_mv(r, &comp->fp[j], VP9_NMV_UPDATE_PROB);
303
304
305
306
  }

  if (usehp) {
    for (i = 0; i < 2; ++i) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
307
308
      update_mv(r, &mvc->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
      update_mv(r, &mvc->comps[i].hp, VP9_NMV_UPDATE_PROB);
309
310
311
312
    }
  }
}

313
// Read the referncence frame
Ronald S. Bultje's avatar
Ronald S. Bultje committed
314
315
static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
                           int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
316
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
317
  MACROBLOCKD *const xd = &pbi->mb;
318
  FRAME_CONTEXT *const fc = &cm->fc;
319

320
321
  if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
    ref_frame[0] = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME);
322
323
    ref_frame[1] = NONE;
  } else {
324
    const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
325
    int is_comp;
John Koleszar's avatar
John Koleszar committed
326

Ronald S. Bultje's avatar
Ronald S. Bultje committed
327
    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
328
329
      is_comp = vp9_read(r, fc->comp_inter_prob[comp_ctx]);
      fc->comp_inter_count[comp_ctx][is_comp]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
330
331
332
    } else {
      is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
    }
John Koleszar's avatar
John Koleszar committed
333

Ronald S. Bultje's avatar
Ronald S. Bultje committed
334
335
    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
    if (is_comp) {
336
      const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
337
      const int ref_ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
338
339
340
      const int b = vp9_read(r, fc->comp_ref_prob[ref_ctx]);
      fc->comp_ref_count[ref_ctx][b]++;
      ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
341
      ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
342
    } else {
343
      const int ref1_ctx = vp9_get_pred_context_single_ref_p1(cm, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
344
      ref_frame[1] = NONE;
345
      if (vp9_read(r, fc->single_ref_prob[ref1_ctx][0])) {
346
        const int ref2_ctx = vp9_get_pred_context_single_ref_p2(cm, xd);
347
348
349
350
        const int b = vp9_read(r, fc->single_ref_prob[ref2_ctx][1]);
        ref_frame[0] = b ? ALTREF_FRAME : GOLDEN_FRAME;
        fc->single_ref_count[ref1_ctx][0][1]++;
        fc->single_ref_count[ref2_ctx][1][b]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
351
352
      } else {
        ref_frame[0] = LAST_FRAME;
353
        fc->single_ref_count[ref1_ctx][0][0]++;
John Koleszar's avatar
John Koleszar committed
354
      }
355
    }
John Koleszar's avatar
John Koleszar committed
356
  }
357
}
John Koleszar's avatar
John Koleszar committed
358

359
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
360
  int i, j;
361
362
363
  for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j)
    for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i)
      if (vp9_read(r, VP9_MODE_UPDATE_PROB))
364
        vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
365
366
}

367
static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
368
369
  int i, j;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
370
371
    for (j = 0; j < VP9_INTER_MODES - 1; ++j)
      if (vp9_read(r, VP9_MODE_UPDATE_PROB))
372
        vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
373
}
John Koleszar's avatar
John Koleszar committed
374

375
376
377
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
  COMPPREDMODE_TYPE mode = vp9_read_bit(r);
  if (mode)
378
    mode += vp9_read_bit(r);
379
380
381
  return mode;
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
382
383
384
385
386
387
388
389
390
391
static INLINE void assign_and_clamp_mv(int_mv *dst, const int_mv *src,
                                       int mb_to_left_edge,
                                       int mb_to_right_edge,
                                       int mb_to_top_edge,
                                       int mb_to_bottom_edge) {
  dst->as_int = src->as_int;
  clamp_mv(dst, mb_to_left_edge, mb_to_right_edge, mb_to_top_edge,
           mb_to_bottom_edge);
}

392
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
393
    VP9D_COMP *pbi, vp9_reader *r) {
394
395
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
396
  const vp9_prob *probs = vp9_get_pred_probs_switchable_interp(cm, xd);
397
  const int index = treed_read(r, vp9_switchable_interp_tree, probs);
398
  const int ctx = vp9_get_pred_context_switchable_interp(cm, xd);
399
  ++cm->fc.switchable_interp_count[ctx][index];
400
401
402
  return vp9_switchable_interp[index];
}

403
static void read_intra_block_modes(VP9D_COMP *pbi, MODE_INFO *mi,
404
                                   vp9_reader *r) {
405
  VP9_COMMON *const cm = &pbi->common;
406
  MB_MODE_INFO *const mbmi = &mi->mbmi;
407
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
408
  const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
409
410

  if (bsize >= BLOCK_SIZE_SB8X8) {
411
412
413
    const int size_group = MIN(3, MIN(bwl, bhl));
    mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[size_group]);
    cm->fc.y_mode_counts[size_group][mbmi->mode]++;
414
  } else {
415
416
     // Only 4x4, 4x8, 8x4 blocks
     const int bw = 1 << bwl, bh = 1 << bhl;
417
     int idx, idy;
418

419
420
     for (idy = 0; idy < 2; idy += bh) {
       for (idx = 0; idx < 2; idx += bw) {
421
422
         const int ib = idy * 2 + idx;
         const int b_mode = read_intra_mode(r, cm->fc.y_mode_prob[0]);
423
         mi->bmi[ib].as_mode = b_mode;
424
425
426
         cm->fc.y_mode_counts[0][b_mode]++;

         if (bh == 2)
427
           mi->bmi[ib + 2].as_mode = b_mode;
428
         if (bw == 2)
429
           mi->bmi[ib + 1].as_mode = b_mode;
430
431
      }
    }
432
    mbmi->mode = mi->bmi[3].as_mode;
433
434
435
436
437
438
439
440
441
442
443
444
  }

  mbmi->uv_mode = read_intra_mode(r, cm->fc.uv_mode_prob[mbmi->mode]);
  cm->fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
}

static MV_REFERENCE_FRAME read_reference_frame(VP9D_COMP *pbi, int segment_id,
                                               vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

  MV_REFERENCE_FRAME ref;
445
  if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
446
    const int ctx = vp9_get_pred_context_intra_inter(cm, xd);
447
    ref = (MV_REFERENCE_FRAME)
448
              vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
449
450
    cm->fc.intra_inter_count[ctx][ref != INTRA_FRAME]++;
  } else {
451
452
    ref = (MV_REFERENCE_FRAME) vp9_get_segdata(&xd->seg, segment_id,
                                   SEG_LVL_REF_FRAME) != INTRA_FRAME;
453
454
455
456
  }
  return ref;
}

457
458
static void read_inter_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
                                 int mi_row, int mi_col, vp9_reader *r) {
459
  VP9_COMMON *const cm = &pbi->common;
460
  MACROBLOCKD *const xd = &pbi->mb;
461
  nmv_context *const nmvc = &cm->fc.nmvc;
462
  MB_MODE_INFO *const mbmi = &mi->mbmi;
John Koleszar's avatar
John Koleszar committed
463

464
465
  int_mv *const mv0 = &mbmi->mv[0];
  int_mv *const mv1 = &mbmi->mv[1];
466
467
468
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
  const int bw = 1 << b_width_log2(bsize);
  const int bh = 1 << b_height_log2(bsize);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
469

470
  int idx, idy;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
471

472
  mbmi->segment_id = read_inter_segment_id(pbi, mi_row, mi_col, r);
473
  mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
474
  mbmi->ref_frame[0] = read_reference_frame(pbi, mbmi->segment_id, r);
475
476
477
  mbmi->ref_frame[1] = NONE;
  mbmi->txfm_size = read_txfm_size(pbi, cm->txfm_mode, bsize,
     (!mbmi->mb_skip_coeff || mbmi->ref_frame[0] == INTRA_FRAME), r);
478

Ronald S. Bultje's avatar
Ronald S. Bultje committed
479
  if (mbmi->ref_frame[0] != INTRA_FRAME) {
John Koleszar's avatar
John Koleszar committed
480
481
    int_mv nearest, nearby, best_mv;
    int_mv nearest_second, nearby_second, best_mv_second;
482
    vp9_prob *mv_ref_p;
483
    MV_REFERENCE_FRAME ref0, ref1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
484
485

    read_ref_frame(pbi, r, mbmi->segment_id, mbmi->ref_frame);
486
487
    ref0 = mbmi->ref_frame[0];
    ref1 = mbmi->ref_frame[1];
488

489
#ifdef DEC_DEBUG
490
491
492
    if (dec_debug)
      printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
             xd->mode_info_context->mbmi.mv[0].as_mv.col);
493
#endif
494
495
    vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
                     ref0, mbmi->ref_mvs[ref0], cm->ref_frame_sign_bias);
496

497
    mv_ref_p = cm->fc.inter_mode_probs[mbmi->mb_mode_context[ref0]];
498

499
    if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
500
501
502
503
504
505
506
507
508
509
510
511
      mbmi->mode = ZEROMV;
    } else if (bsize >= BLOCK_SIZE_SB8X8) {
      mbmi->mode = read_inter_mode(r, mv_ref_p);
      vp9_accum_mv_refs(cm, mbmi->mode, mbmi->mb_mode_context[ref0]);
    }
    mbmi->uv_mode = DC_PRED;

    // nearest, nearby
    if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
      vp9_find_best_ref_mvs(xd, mbmi->ref_mvs[ref0], &nearest, &nearby);
      best_mv.as_int = mbmi->ref_mvs[ref0][0].as_int;
    }
512

513
#ifdef DEC_DEBUG
514
515
516
517
    if (dec_debug)
      printf("[D %d %d] %d %d %d %d\n", ref_frame,
             mbmi->mb_mode_context[ref_frame],
             mv_ref_p[0], mv_ref_p[1], mv_ref_p[2], mv_ref_p[3]);
518
#endif
John Koleszar's avatar
John Koleszar committed
519

520
521
522
    mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
                              ? read_switchable_filter_type(pbi, r)
                              : cm->mcomp_filter_type;
523

524
    if (ref1 > INTRA_FRAME) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
525
      vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
526
                       ref1, mbmi->ref_mvs[ref1], cm->ref_frame_sign_bias);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
527
528

      if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
529
530
531
        vp9_find_best_ref_mvs(xd, mbmi->ref_mvs[ref1],
                              &nearest_second, &nearby_second);
        best_mv_second.as_int = mbmi->ref_mvs[ref1][0].as_int;
532
      }
John Koleszar's avatar
John Koleszar committed
533
    }
534

535

Ronald S. Bultje's avatar
Ronald S. Bultje committed
536
537
538
539
    if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
      for (idy = 0; idy < 2; idy += bh) {
        for (idx = 0; idx < 2; idx += bw) {
          int_mv blockmv, secondmv;
540
          const int j = idy * 2 + idx;
541
          const int blockmode = read_inter_mode(r, mv_ref_p);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
542

543
          vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref0]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
544
545
          if (blockmode == NEARESTMV || blockmode == NEARMV) {
            vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0);
546
            if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
547
548
549
              vp9_append_sub8x8_mvs_for_idx(cm, xd,  &nearest_second,
                                            &nearby_second, j, 1);
          }
550

Ronald S. Bultje's avatar
Ronald S. Bultje committed
551
552
          switch (blockmode) {
            case NEWMV:
553
554
              read_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
                      &cm->fc.NMVcount, xd->allow_high_precision_mv);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
555

556
              if (ref1 > 0)
557
558
                read_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
                        &cm->fc.NMVcount, xd->allow_high_precision_mv);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
559
560
561
              break;
            case NEARESTMV:
              blockmv.as_int = nearest.as_int;
562
              if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
563
564
565
566
                secondmv.as_int = nearest_second.as_int;
              break;
            case NEARMV:
              blockmv.as_int = nearby.as_int;
567
              if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
568
569
570
571
                secondmv.as_int = nearby_second.as_int;
              break;
            case ZEROMV:
              blockmv.as_int = 0;
572
              if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
573
574
575
                secondmv.as_int = 0;
              break;
            default:
576
              assert(!"Invalid inter mode value");
John Koleszar's avatar
John Koleszar committed
577
          }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
578
          mi->bmi[j].as_mv[0].as_int = blockmv.as_int;
579
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
580
581
            mi->bmi[j].as_mv[1].as_int = secondmv.as_int;

582
          if (bh == 2)
583
            mi->bmi[j + 2] = mi->bmi[j];
584
          if (bw == 2)
585
            mi->bmi[j + 1] = mi->bmi[j];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
586
          mi->mbmi.mode = blockmode;
587
        }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
588
      }
John Koleszar's avatar
John Koleszar committed
589

Ronald S. Bultje's avatar
Ronald S. Bultje committed
590
591
592
      mv0->as_int = mi->bmi[3].as_mv[0].as_int;
      mv1->as_int = mi->bmi[3].as_mv[1].as_int;
    } else {
593
594
595
596
597
      const int mb_to_top_edge = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
      const int mb_to_bottom_edge = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
      const int mb_to_left_edge = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
      const int mb_to_right_edge = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;

Ronald S. Bultje's avatar
Ronald S. Bultje committed
598
599
600
601
602
603
604
      switch (mbmi->mode) {
        case NEARMV:
          // Clip "next_nearest" so that it does not extend to far out of image
          assign_and_clamp_mv(mv0, &nearby, mb_to_left_edge,
                                            mb_to_right_edge,
                                            mb_to_top_edge,
                                            mb_to_bottom_edge);
605
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
606
607
608
609
610
611
612
613
614
615
616
617
            assign_and_clamp_mv(mv1, &nearby_second, mb_to_left_edge,
                                                     mb_to_right_edge,
                                                     mb_to_top_edge,
                                                     mb_to_bottom_edge);
          break;

        case NEARESTMV:
          // Clip "next_nearest" so that it does not extend to far out of image
          assign_and_clamp_mv(mv0, &nearest, mb_to_left_edge,
                                             mb_to_right_edge,
                                             mb_to_top_edge,
                                             mb_to_bottom_edge);
618
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
619
620
621
622
623
624
625
626
            assign_and_clamp_mv(mv1, &nearest_second, mb_to_left_edge,
                                                      mb_to_right_edge,
                                                      mb_to_top_edge,
                                                      mb_to_bottom_edge);
          break;

        case ZEROMV:
          mv0->as_int = 0;
627
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
628
629
630
631
            mv1->as_int = 0;
          break;

        case NEWMV:
632
633
          read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
                  xd->allow_high_precision_mv);
634
          if (ref1 > 0)
635
636
            read_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
                    &cm->fc.NMVcount, xd->allow_high_precision_mv);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
637
638
          break;
        default:
639
          assert(!"Invalid inter mode value");
Ronald S. Bultje's avatar
Ronald S. Bultje committed
640
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
641
    }
John Koleszar's avatar
John Koleszar committed
642
  } else {
643
    mv0->as_int = 0;  // required for left and above block mv
644
    read_intra_block_modes(pbi, mi, r);
John Koleszar's avatar
John Koleszar committed
645
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
646
}
John Koleszar's avatar
John Koleszar committed
647

648
649
void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
650
  int k;
651

652
  // TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
Deb Mukherjee's avatar
Deb Mukherjee committed
653
  // vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
654
655
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
    if (vp9_read(r, VP9_MODE_UPDATE_PROB))
656
      vp9_diff_update_prob(r, &cm->fc.mbskip_probs[k]);
657

658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
  if (cm->frame_type != KEY_FRAME && !cm->intra_only) {
    nmv_context *const nmvc = &pbi->common.fc.nmvc;
    MACROBLOCKD *const xd = &pbi->mb;
    int i, j;

    read_inter_mode_probs(&cm->fc, r);

    if (cm->mcomp_filter_type == SWITCHABLE)
      read_switchable_interp_probs(&cm->fc, r);

    for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
      if (vp9_read(r, VP9_MODE_UPDATE_PROB))
        vp9_diff_update_prob(r, &cm->fc.intra_inter_prob[i]);

    if (cm->allow_comp_inter_inter) {
      cm->comp_pred_mode = read_comp_pred_mode(r);
      if (cm->comp_pred_mode == HYBRID_PREDICTION)
        for (i = 0; i < COMP_INTER_CONTEXTS; i++)
          if (vp9_read(r, VP9_MODE_UPDATE_PROB))
            vp9_diff_update_prob(r, &cm->fc.comp_inter_prob[i]);
    } else {
      cm->comp_pred_mode = SINGLE_PREDICTION_ONLY;
    }

    if (cm->comp_pred_mode != COMP_PREDICTION_ONLY)
      for (i = 0; i < REF_CONTEXTS; i++) {
        if (vp9_read(r, VP9_MODE_UPDATE_PROB))
          vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][0]);

        if (vp9_read(r, VP9_MODE_UPDATE_PROB))
          vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][1]);
      }

    if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
      for (i = 0; i < REF_CONTEXTS; i++)
        if (vp9_read(r, VP9_MODE_UPDATE_PROB))
          vp9_diff_update_prob(r, &cm->fc.comp_ref_prob[i]);

    // VP9_INTRA_MODES
    for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
      for (i = 0; i < VP9_INTRA_MODES - 1; ++i)
        if (vp9_read(r, VP9_MODE_UPDATE_PROB))
          vp9_diff_update_prob(r, &cm->fc.y_mode_prob[j][i]);

    for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j)
      for (i = 0; i < PARTITION_TYPES - 1; ++i)
        if (vp9_read(r, VP9_MODE_UPDATE_PROB))
          vp9_diff_update_prob(r, &cm->fc.partition_prob[INTER_FRAME][j][i]);

    read_mv_probs(r, nmvc, xd->allow_high_precision_mv);
  }
709
}
710

711
void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r) {
712
  VP9_COMMON *const cm = &pbi->common;
713
  MACROBLOCKD *const xd = &pbi->mb;
714
  MODE_INFO *mi = xd->mode_info_context;
715
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
Jim Bankoski's avatar
Jim Bankoski committed
716
717
718
719
720
  const int bw = 1 << mi_width_log2(bsize);
  const int bh = 1 << mi_height_log2(bsize);
  const int y_mis = MIN(bh, cm->mi_rows - mi_row);
  const int x_mis = MIN(bw, cm->mi_cols - mi_col);
  int x, y;
721

722
723
724
725
  if (cm->frame_type == KEY_FRAME || cm->intra_only)
    read_intra_mode_info(pbi, mi, mi_row, mi_col, r);
  else
    read_inter_mode_info(pbi, mi, mi_row, mi_col, r);
726

Jim Bankoski's avatar
Jim Bankoski committed
727
728
729
  for (y = 0; y < y_mis; y++)
    for (x = !y; x < x_mis; x++)
      mi[y * cm->mode_info_stride + x] = *mi;
730
}