vp9_decodemv.c 25 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"

29
static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
30 31 32 33
  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) {
34
  return (MB_PREDICTION_MODE)treed_read(r, vp9_inter_mode_tree, p);
35 36
}

37 38
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
39
}
40

41 42
static TX_SIZE read_selected_txfm_size(VP9_COMMON *cm, MACROBLOCKD *xd,
                                       BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
43 44
  const int context = vp9_get_pred_context_tx_size(xd);
  const vp9_prob *tx_probs = vp9_get_pred_probs_tx_size(xd, &cm->fc.tx_probs);
45 46 47 48 49 50 51 52
  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)
53
    cm->fc.tx_counts.p32x32[context][txfm_size]++;
54
  else if (bsize >= BLOCK_SIZE_MB16X16)
55
    cm->fc.tx_counts.p16x16[context][txfm_size]++;
56
  else
57
    cm->fc.tx_counts.p8x8[context][txfm_size]++;
58 59 60 61

  return txfm_size;
}

62
static TX_SIZE read_txfm_size(VP9D_COMP *pbi, TX_MODE tx_mode,
63 64
                              BLOCK_SIZE_TYPE bsize, int select_cond,
                              vp9_reader *r) {
65 66 67
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

68
  if (tx_mode == TX_MODE_SELECT && bsize >= BLOCK_SIZE_SB8X8 && select_cond)
69
    return read_selected_txfm_size(cm, xd, bsize, r);
70
  else if (tx_mode >= ALLOW_32X32 && bsize >= BLOCK_SIZE_SB32X32)
71
    return TX_32X32;
72
  else if (tx_mode >= ALLOW_16X16 && bsize >= BLOCK_SIZE_MB16X16)
73
    return TX_16X16;
74
  else if (tx_mode >= ALLOW_8X8 && bsize >= BLOCK_SIZE_SB8X8)
75 76 77 78 79
    return TX_8X8;
  else
    return TX_4X4;
}

80
static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE_TYPE bsize,
81
                           int mi_row, int mi_col, int segment_id) {
82 83 84
  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);
85
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
86
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
87 88
  int x, y;

89 90 91 92 93 94 95 96 97 98
  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;
99
  struct segmentation *const seg = &xd->seg;
100
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
101
  int segment_id;
102

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

  if (!seg->update_map)
107
    return 0;
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132

  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);
133
    vp9_set_pred_flag_seg_id(cm, bsize, mi_row, mi_col, pred_flag);
134 135 136 137
    segment_id = pred_flag ? pred_segment_id
                           : read_segment_id(r, seg);
  } else {
    segment_id = read_segment_id(r, seg);
138
  }
139 140
  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
  return segment_id;
141 142
}

143
static uint8_t read_skip_coeff(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
144
  VP9_COMMON *const cm = &pbi->common;
145
  MACROBLOCKD *const xd = &pbi->mb;
146
  int skip_coeff = vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_SKIP);
147
  if (!skip_coeff) {
148
    const int ctx = vp9_get_pred_context_mbskip(xd);
149
    skip_coeff = vp9_read(r, vp9_get_pred_prob_mbskip(cm, xd));
150
    cm->fc.mbskip_count[ctx][skip_coeff]++;
Deb Mukherjee's avatar
Deb Mukherjee committed
151
  }
152 153
  return skip_coeff;
}
John Koleszar's avatar
John Koleszar committed
154

155 156 157 158 159 160 161
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;
162

163 164
  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);
165
  mbmi->txfm_size = read_txfm_size(pbi, cm->tx_mode, bsize, 1, r);
166 167 168
  mbmi->ref_frame[0] = INTRA_FRAME;

  if (bsize >= BLOCK_SIZE_SB8X8) {
169 170 171
    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;
172
    mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
173
  } else {
174 175 176
    // Only 4x4, 4x8, 8x4 blocks
    const int bw = 1 << b_width_log2(bsize);
    const int bh = 1 << b_height_log2(bsize);
177
    int idx, idy;
178 179 180

    for (idy = 0; idy < 2; idy += bh) {
      for (idx = 0; idx < 2; idx += bw) {
181
        const int ib = idy * 2 + idx;
182 183 184
        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;
185
        const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
186
                                              vp9_kf_y_mode_prob[A][L]);
187
        m->bmi[ib].as_mode = b_mode;
188
        if (bh == 2)
189
          m->bmi[ib + 2].as_mode = b_mode;
190
        if (bw == 2)
191
          m->bmi[ib + 1].as_mode = b_mode;
192 193
      }
    }
194

195
    mbmi->mode = m->bmi[3].as_mode;
John Koleszar's avatar
John Koleszar committed
196
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
197

198
  mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
Scott LaVarnway's avatar
Scott LaVarnway committed
199
}
John Koleszar's avatar
John Koleszar committed
200

201 202
static int read_mv_component(vp9_reader *r,
                             const nmv_component *mvcomp, int usehp) {
203

204
  int mag, d, fr, hp;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
205 206
  const int sign = vp9_read(r, mvcomp->sign);
  const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
207
  const int class0 = mv_class == MV_CLASS_0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
208

209
  // Integer part
210
  if (class0) {
211
    d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
212
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
213
    int i;
214
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits
Dmitry Kovalev's avatar
Dmitry Kovalev committed
215

216
    d = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
217 218
    for (i = 0; i < n; ++i)
      d |= vp9_read(r, mvcomp->bits[i]) << i;
219 220
  }

221 222
  // Fractional part
  fr = treed_read(r, vp9_mv_fp_tree,
223
                  class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
224 225


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

230
  // Result
231 232
  mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
  return sign ? -mag : mag;
233 234
}

235 236 237 238 239 240 241 242 243 244 245 246 247
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);

248
  vp9_inc_mv(&diff, counts);
249 250 251 252 253

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

254
static void update_mv(vp9_reader *r, vp9_prob *p, vp9_prob upd_p) {
255
  if (vp9_read(r, upd_p)) {
256
#ifdef LOW_PRECISION_MV_UPDATE
257
    *p = (vp9_read_literal(r, 7) << 1) | 1;
258
#else
259
    *p = vp9_read_literal(r, 8);
260 261 262 263
#endif
  }
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
264
static void read_mv_probs(vp9_reader *r, nmv_context *mvc, int usehp) {
265
  int i, j, k;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
266 267

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

270
  for (i = 0; i < 2; ++i) {
271 272 273
    nmv_component *const comp = &mvc->comps[i];

    update_mv(r, &comp->sign, VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
274
    for (j = 0; j < MV_CLASSES - 1; ++j)
275
      update_mv(r, &comp->classes[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276 277

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

    for (j = 0; j < MV_OFFSET_BITS; ++j)
281
      update_mv(r, &comp->bits[j], VP9_NMV_UPDATE_PROB);
282 283 284
  }

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

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

    for (j = 0; j < 3; ++j)
292
      update_mv(r, &comp->fp[j], VP9_NMV_UPDATE_PROB);
293 294 295 296
  }

  if (usehp) {
    for (i = 0; i < 2; ++i) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
297 298
      update_mv(r, &mvc->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
      update_mv(r, &mvc->comps[i].hp, VP9_NMV_UPDATE_PROB);
299 300 301 302
    }
  }
}

303
// Read the referncence frame
Ronald S. Bultje's avatar
Ronald S. Bultje committed
304 305
static void read_ref_frame(VP9D_COMP *pbi, vp9_reader *r,
                           int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
306
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
307
  MACROBLOCKD *const xd = &pbi->mb;
308
  FRAME_CONTEXT *const fc = &cm->fc;
309

310 311
  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);
312 313
    ref_frame[1] = NONE;
  } else {
314
    const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
315
    int is_comp;
John Koleszar's avatar
John Koleszar committed
316

Ronald S. Bultje's avatar
Ronald S. Bultje committed
317
    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
318 319
      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
320 321 322
    } else {
      is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
    }
John Koleszar's avatar
John Koleszar committed
323

Ronald S. Bultje's avatar
Ronald S. Bultje committed
324 325
    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
    if (is_comp) {
326
      const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
327
      const int ref_ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
328 329 330
      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
331
      ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
332
    } else {
333
      const int ref1_ctx = vp9_get_pred_context_single_ref_p1(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
334
      ref_frame[1] = NONE;
335
      if (vp9_read(r, fc->single_ref_prob[ref1_ctx][0])) {
336
        const int ref2_ctx = vp9_get_pred_context_single_ref_p2(xd);
337 338 339 340
        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
341 342
      } else {
        ref_frame[0] = LAST_FRAME;
343
        fc->single_ref_count[ref1_ctx][0][0]++;
John Koleszar's avatar
John Koleszar committed
344
      }
345
    }
John Koleszar's avatar
John Koleszar committed
346
  }
347
}
John Koleszar's avatar
John Koleszar committed
348

349
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
350
  int i, j;
351 352 353
  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))
354
        vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
355 356
}

357
static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
358 359
  int i, j;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
360 361
    for (j = 0; j < VP9_INTER_MODES - 1; ++j)
      if (vp9_read(r, VP9_MODE_UPDATE_PROB))
362
        vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
363
}
John Koleszar's avatar
John Koleszar committed
364

365 366 367
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
  COMPPREDMODE_TYPE mode = vp9_read_bit(r);
  if (mode)
368
    mode += vp9_read_bit(r);
369 370 371
  return mode;
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
372 373 374 375 376 377 378 379 380 381
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);
}

382
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
383
    VP9D_COMP *pbi, vp9_reader *r) {
384 385
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
386
  const vp9_prob *probs = vp9_get_pred_probs_switchable_interp(cm, xd);
387
  const int index = treed_read(r, vp9_switchable_interp_tree, probs);
388
  const int ctx = vp9_get_pred_context_switchable_interp(xd);
389
  ++cm->fc.switchable_interp_count[ctx][index];
390 391 392
  return vp9_switchable_interp[index];
}

393
static void read_intra_block_modes(VP9D_COMP *pbi, MODE_INFO *mi,
394
                                   vp9_reader *r) {
395
  VP9_COMMON *const cm = &pbi->common;
396
  MB_MODE_INFO *const mbmi = &mi->mbmi;
397
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
398
  const int bwl = b_width_log2(bsize), bhl = b_height_log2(bsize);
399 400

  if (bsize >= BLOCK_SIZE_SB8X8) {
401 402 403
    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]++;
404
  } else {
405 406
     // Only 4x4, 4x8, 8x4 blocks
     const int bw = 1 << bwl, bh = 1 << bhl;
407
     int idx, idy;
408

409 410
     for (idy = 0; idy < 2; idy += bh) {
       for (idx = 0; idx < 2; idx += bw) {
411 412
         const int ib = idy * 2 + idx;
         const int b_mode = read_intra_mode(r, cm->fc.y_mode_prob[0]);
413
         mi->bmi[ib].as_mode = b_mode;
414 415 416
         cm->fc.y_mode_counts[0][b_mode]++;

         if (bh == 2)
417
           mi->bmi[ib + 2].as_mode = b_mode;
418
         if (bw == 2)
419
           mi->bmi[ib + 1].as_mode = b_mode;
420 421
      }
    }
422
    mbmi->mode = mi->bmi[3].as_mode;
423 424 425 426 427 428 429 430 431 432 433 434
  }

  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;
435
  if (!vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
436
    const int ctx = vp9_get_pred_context_intra_inter(xd);
437
    ref = (MV_REFERENCE_FRAME)
438
              vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
439 440
    cm->fc.intra_inter_count[ctx][ref != INTRA_FRAME]++;
  } else {
441 442
    ref = (MV_REFERENCE_FRAME) vp9_get_segdata(&xd->seg, segment_id,
                                   SEG_LVL_REF_FRAME) != INTRA_FRAME;
443 444 445 446
  }
  return ref;
}

447 448
static void read_inter_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
                                 int mi_row, int mi_col, vp9_reader *r) {
449
  VP9_COMMON *const cm = &pbi->common;
450
  MACROBLOCKD *const xd = &pbi->mb;
451
  nmv_context *const nmvc = &cm->fc.nmvc;
452
  MB_MODE_INFO *const mbmi = &mi->mbmi;
John Koleszar's avatar
John Koleszar committed
453

454 455
  int_mv *const mv0 = &mbmi->mv[0];
  int_mv *const mv1 = &mbmi->mv[1];
456 457 458
  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
459

460
  int idx, idy;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
461

462
  mbmi->segment_id = read_inter_segment_id(pbi, mi_row, mi_col, r);
463
  mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
464
  mbmi->ref_frame[0] = read_reference_frame(pbi, mbmi->segment_id, r);
465
  mbmi->ref_frame[1] = NONE;
466
  mbmi->txfm_size = read_txfm_size(pbi, cm->tx_mode, bsize,
467
     (!mbmi->mb_skip_coeff || mbmi->ref_frame[0] == INTRA_FRAME), r);
468

Ronald S. Bultje's avatar
Ronald S. Bultje committed
469
  if (mbmi->ref_frame[0] != INTRA_FRAME) {
John Koleszar's avatar
John Koleszar committed
470 471
    int_mv nearest, nearby, best_mv;
    int_mv nearest_second, nearby_second, best_mv_second;
472
    vp9_prob *mv_ref_p;
473
    MV_REFERENCE_FRAME ref0, ref1;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
474 475

    read_ref_frame(pbi, r, mbmi->segment_id, mbmi->ref_frame);
476 477
    ref0 = mbmi->ref_frame[0];
    ref1 = mbmi->ref_frame[1];
478

479 480
    vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
                     ref0, mbmi->ref_mvs[ref0], cm->ref_frame_sign_bias);
481

482
    mv_ref_p = cm->fc.inter_mode_probs[mbmi->mb_mode_context[ref0]];
483

484
    if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
485 486 487 488 489 490 491 492 493 494 495 496
      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;
    }
497

498 499 500
    mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
                              ? read_switchable_filter_type(pbi, r)
                              : cm->mcomp_filter_type;
501

502
    if (ref1 > INTRA_FRAME) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
503
      vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
504
                       ref1, mbmi->ref_mvs[ref1], cm->ref_frame_sign_bias);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
505 506

      if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
507 508 509
        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;
510
      }
John Koleszar's avatar
John Koleszar committed
511
    }
512

513

Ronald S. Bultje's avatar
Ronald S. Bultje committed
514 515 516 517
    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;
518
          const int j = idy * 2 + idx;
519
          const int blockmode = read_inter_mode(r, mv_ref_p);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
520

521
          vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref0]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
522 523
          if (blockmode == NEARESTMV || blockmode == NEARMV) {
            vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0);
524
            if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
525 526 527
              vp9_append_sub8x8_mvs_for_idx(cm, xd,  &nearest_second,
                                            &nearby_second, j, 1);
          }
528

Ronald S. Bultje's avatar
Ronald S. Bultje committed
529 530
          switch (blockmode) {
            case NEWMV:
531 532
              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
533

534
              if (ref1 > 0)
535 536
                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
537 538 539
              break;
            case NEARESTMV:
              blockmv.as_int = nearest.as_int;
540
              if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
541 542 543 544
                secondmv.as_int = nearest_second.as_int;
              break;
            case NEARMV:
              blockmv.as_int = nearby.as_int;
545
              if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
546 547 548 549
                secondmv.as_int = nearby_second.as_int;
              break;
            case ZEROMV:
              blockmv.as_int = 0;
550
              if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
551 552 553
                secondmv.as_int = 0;
              break;
            default:
554
              assert(!"Invalid inter mode value");
John Koleszar's avatar
John Koleszar committed
555
          }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
556
          mi->bmi[j].as_mv[0].as_int = blockmv.as_int;
557
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
558 559
            mi->bmi[j].as_mv[1].as_int = secondmv.as_int;

560
          if (bh == 2)
561
            mi->bmi[j + 2] = mi->bmi[j];
562
          if (bw == 2)
563
            mi->bmi[j + 1] = mi->bmi[j];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
564
          mi->mbmi.mode = blockmode;
565
        }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
566
      }
John Koleszar's avatar
John Koleszar committed
567

Ronald S. Bultje's avatar
Ronald S. Bultje committed
568 569 570
      mv0->as_int = mi->bmi[3].as_mv[0].as_int;
      mv1->as_int = mi->bmi[3].as_mv[1].as_int;
    } else {
571 572 573 574 575
      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
576 577 578 579 580 581 582
      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);
583
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
584 585 586 587 588 589 590 591 592 593 594 595
            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);
596
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
597 598 599 600 601 602 603 604
            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;
605
          if (ref1 > 0)
Ronald S. Bultje's avatar
Ronald S. Bultje committed
606 607 608 609
            mv1->as_int = 0;
          break;

        case NEWMV:
610 611
          read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->fc.NMVcount,
                  xd->allow_high_precision_mv);
612
          if (ref1 > 0)
613 614
            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
615 616
          break;
        default:
617
          assert(!"Invalid inter mode value");
Ronald S. Bultje's avatar
Ronald S. Bultje committed
618
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
619
    }
John Koleszar's avatar
John Koleszar committed
620
  } else {
621
    mv0->as_int = 0;  // required for left and above block mv
622
    read_intra_block_modes(pbi, mi, r);
John Koleszar's avatar
John Koleszar committed
623
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
624
}
John Koleszar's avatar
John Koleszar committed
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
static void read_comp_pred(VP9_COMMON *cm, vp9_reader *r) {
  int i;

  cm->comp_pred_mode = cm->allow_comp_inter_inter ? read_comp_pred_mode(r)
                                                  : SINGLE_PREDICTION_ONLY;

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

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

651 652
void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
653
  int k;
654

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

661 662 663 664 665 666 667 668 669 670 671 672 673 674
  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]);

675
    read_comp_pred(cm, r);
676 677 678 679 680 681 682 683 684 685 686 687 688

    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);
  }
689
}
690

691
void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r) {
692
  VP9_COMMON *const cm = &pbi->common;
693
  MACROBLOCKD *const xd = &pbi->mb;
694
  MODE_INFO *mi = xd->mode_info_context;
695
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
Jim Bankoski's avatar
Jim Bankoski committed
696 697 698 699 700
  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;
701

702 703 704 705
  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);
706

Jim Bankoski's avatar
Jim Bankoski committed
707 708 709
  for (y = 0; y < y_mis; y++)
    for (x = !y; x < x_mis; x++)
      mi[y * cm->mode_info_stride + x] = *mi;
710
}