vp9_decodemv.c 25.1 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
  return (MB_PREDICTION_MODE)treed_read(r, vp9_intra_mode_tree, p);
}

33 34 35 36 37 38
static MB_PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r,
                                          uint8_t context) {
  MB_PREDICTION_MODE mode = treed_read(r, vp9_inter_mode_tree,
                            cm->fc.inter_mode_probs[context]);
  ++cm->counts.inter_mode[context][inter_mode_offset(mode)];
  return mode;
39 40
}

41 42
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
43
}
44

45 46 47 48 49 50 51 52 53
static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
                                     BLOCK_SIZE_TYPE bsize, vp9_reader *r) {
  const uint8_t context = vp9_get_pred_context_tx_size(xd);
  const vp9_prob *tx_probs = get_tx_probs(bsize, context, &cm->fc.tx_probs);
  TX_SIZE tx_size = vp9_read(r, tx_probs[0]);
  if (tx_size != TX_4X4 && bsize >= BLOCK_SIZE_MB16X16) {
    tx_size += vp9_read(r, tx_probs[1]);
    if (tx_size != TX_8X8 && bsize >= BLOCK_SIZE_SB32X32)
      tx_size += vp9_read(r, tx_probs[2]);
54 55
  }

56
  update_tx_counts(bsize, context, tx_size, &cm->counts.tx);
57
  return tx_size;
58 59
}

60
static TX_SIZE read_tx_size(VP9D_COMP *pbi, TX_MODE tx_mode,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
61
                            BLOCK_SIZE_TYPE bsize, int allow_select,
62
                            vp9_reader *r) {
63 64 65
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
66
  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_SIZE_SB8X8)
67
    return read_selected_tx_size(cm, xd, bsize, r);
68
  else if (tx_mode >= ALLOW_32X32 && bsize >= BLOCK_SIZE_SB32X32)
69
    return TX_32X32;
70
  else if (tx_mode >= ALLOW_16X16 && bsize >= BLOCK_SIZE_MB16X16)
71
    return TX_16X16;
72
  else if (tx_mode >= ALLOW_8X8 && bsize >= BLOCK_SIZE_SB8X8)
73 74 75 76 77
    return TX_8X8;
  else
    return TX_4X4;
}

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

Paul Wilkins's avatar
Paul Wilkins committed
87
  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
88 89 90 91 92 93 94 95 96

  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;
97
  struct segmentation *const seg = &xd->seg;
98
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
99
  int segment_id;
100

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

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
153 154
static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m,
                                       int mi_row, int mi_col, vp9_reader *r) {
155 156 157 158 159
  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;
160

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

  if (bsize >= BLOCK_SIZE_SB8X8) {
167 168 169
    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;
170
    mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
171
  } else {
172
    // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
173 174
    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
175
    int idx, idy;
176

Dmitry Kovalev's avatar
Dmitry Kovalev committed
177 178
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
179
        const int ib = idy * 2 + idx;
180 181 182
        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;
183
        const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
184
                                              vp9_kf_y_mode_prob[A][L]);
185
        m->bmi[ib].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
186
        if (num_4x4_h == 2)
187
          m->bmi[ib + 2].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
188
        if (num_4x4_w == 2)
189
          m->bmi[ib + 1].as_mode = b_mode;
190 191
      }
    }
192

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

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

199 200
static int read_mv_component(vp9_reader *r,
                             const nmv_component *mvcomp, int usehp) {
201

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

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

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

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


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

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

233 234
static INLINE void read_mv(vp9_reader *r, MV *mv, const MV *ref,
                           const nmv_context *ctx,
235
                           nmv_context_counts *counts, int allow_hp) {
236
  const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
237
  const int use_hp = allow_hp && vp9_use_mv_hp(ref);
238 239 240
  MV diff = {0, 0};

  if (mv_joint_vertical(j))
241
    diff.row = read_mv_component(r, &ctx->comps[0], use_hp);
242 243

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

246
  vp9_inc_mv(&diff, counts);
247 248 249 250 251

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

252
static void update_mv(vp9_reader *r, vp9_prob *p, vp9_prob upd_p) {
253
  if (vp9_read(r, upd_p))
254
    *p = (vp9_read_literal(r, 7) << 1) | 1;
255 256
}

257
static void read_mv_probs(vp9_reader *r, nmv_context *mvc, int allow_hp) {
258
  int i, j, k;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
259 260

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

263
  for (i = 0; i < 2; ++i) {
264 265 266
    nmv_component *const comp = &mvc->comps[i];

    update_mv(r, &comp->sign, VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
267
    for (j = 0; j < MV_CLASSES - 1; ++j)
268
      update_mv(r, &comp->classes[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
269 270

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

    for (j = 0; j < MV_OFFSET_BITS; ++j)
274
      update_mv(r, &comp->bits[j], VP9_NMV_UPDATE_PROB);
275 276 277
  }

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

280
    for (j = 0; j < CLASS0_SIZE; ++j)
281
      for (k = 0; k < 3; ++k)
282
        update_mv(r, &comp->class0_fp[j][k], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
283 284

    for (j = 0; j < 3; ++j)
285
      update_mv(r, &comp->fp[j], VP9_NMV_UPDATE_PROB);
286 287
  }

288
  if (allow_hp) {
289
    for (i = 0; i < 2; ++i) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
290 291
      update_mv(r, &mvc->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
      update_mv(r, &mvc->comps[i].hp, VP9_NMV_UPDATE_PROB);
292 293 294 295
    }
  }
}

296
// Read the referncence frame
Dmitry Kovalev's avatar
Dmitry Kovalev committed
297 298
static void read_ref_frames(VP9D_COMP *pbi, vp9_reader *r,
                            int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
299
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
300
  MACROBLOCKD *const xd = &pbi->mb;
301
  FRAME_CONTEXT *const fc = &cm->fc;
302
  FRAME_COUNTS *const counts = &cm->counts;
303

304 305
  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);
306 307
    ref_frame[1] = NONE;
  } else {
308
    const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
309
    int is_comp;
John Koleszar's avatar
John Koleszar committed
310

Ronald S. Bultje's avatar
Ronald S. Bultje committed
311
    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
312
      is_comp = vp9_read(r, fc->comp_inter_prob[comp_ctx]);
313
      counts->comp_inter[comp_ctx][is_comp]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
314 315 316
    } else {
      is_comp = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
    }
John Koleszar's avatar
John Koleszar committed
317

Ronald S. Bultje's avatar
Ronald S. Bultje committed
318 319
    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
    if (is_comp) {
320
      const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
321
      const int ref_ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
322
      const int b = vp9_read(r, fc->comp_ref_prob[ref_ctx]);
323
      counts->comp_ref[ref_ctx][b]++;
324
      ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
325
      ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
326
    } else {
327
      const int ref1_ctx = vp9_get_pred_context_single_ref_p1(xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
328
      ref_frame[1] = NONE;
329
      if (vp9_read(r, fc->single_ref_prob[ref1_ctx][0])) {
330
        const int ref2_ctx = vp9_get_pred_context_single_ref_p2(xd);
331 332
        const int b = vp9_read(r, fc->single_ref_prob[ref2_ctx][1]);
        ref_frame[0] = b ? ALTREF_FRAME : GOLDEN_FRAME;
333 334
        counts->single_ref[ref1_ctx][0][1]++;
        counts->single_ref[ref2_ctx][1][b]++;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
335 336
      } else {
        ref_frame[0] = LAST_FRAME;
337
        counts->single_ref[ref1_ctx][0][0]++;
John Koleszar's avatar
John Koleszar committed
338
      }
339
    }
John Koleszar's avatar
John Koleszar committed
340
  }
341
}
John Koleszar's avatar
John Koleszar committed
342

343
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
344
  int i, j;
345 346 347
  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))
348
        vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
349 350
}

351
static void read_inter_mode_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
352 353
  int i, j;
  for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
354 355
    for (j = 0; j < VP9_INTER_MODES - 1; ++j)
      if (vp9_read(r, VP9_MODE_UPDATE_PROB))
356
        vp9_diff_update_prob(r, &fc->inter_mode_probs[i][j]);
357
}
John Koleszar's avatar
John Koleszar committed
358

359 360 361
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
  COMPPREDMODE_TYPE mode = vp9_read_bit(r);
  if (mode)
362
    mode += vp9_read_bit(r);
363 364 365
  return mode;
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
366 367 368 369 370 371 372 373 374 375
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);
}

376
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
377
    VP9D_COMP *pbi, vp9_reader *r) {
378 379
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
380
  const vp9_prob *probs = vp9_get_pred_probs_switchable_interp(cm, xd);
381
  const int index = treed_read(r, vp9_switchable_interp_tree, probs);
382
  const int ctx = vp9_get_pred_context_switchable_interp(xd);
383
  ++cm->counts.switchable_interp[ctx][index];
384 385 386
  return vp9_switchable_interp[index];
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
387
static void read_intra_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
388
                                  vp9_reader *r) {
389
  VP9_COMMON *const cm = &pbi->common;
390
  MB_MODE_INFO *const mbmi = &mi->mbmi;
391 392
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
393 394 395
  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

396
  if (bsize >= BLOCK_SIZE_SB8X8) {
397
    const int size_group = size_group_lookup[bsize];
398
    mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[size_group]);
399
    cm->counts.y_mode[size_group][mbmi->mode]++;
400
  } else {
401
     // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
402 403
     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
404
     int idx, idy;
405

Dmitry Kovalev's avatar
Dmitry Kovalev committed
406 407
     for (idy = 0; idy < 2; idy += num_4x4_h) {
       for (idx = 0; idx < 2; idx += num_4x4_w) {
408 409
         const int ib = idy * 2 + idx;
         const int b_mode = read_intra_mode(r, cm->fc.y_mode_prob[0]);
410
         mi->bmi[ib].as_mode = b_mode;
411
         cm->counts.y_mode[0][b_mode]++;
412

Dmitry Kovalev's avatar
Dmitry Kovalev committed
413
         if (num_4x4_h == 2)
414
           mi->bmi[ib + 2].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
415
         if (num_4x4_w == 2)
416
           mi->bmi[ib + 1].as_mode = b_mode;
417 418
      }
    }
419
    mbmi->mode = mi->bmi[3].as_mode;
420 421 422
  }

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
426
static int read_is_inter_block(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
427 428 429
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
430 431 432
  if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
    return vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME) !=
           INTRA_FRAME;
433
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
434 435 436 437
    const int ctx = vp9_get_pred_context_intra_inter(xd);
    const int is_inter = vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
    ++cm->counts.intra_inter[ctx][is_inter];
    return is_inter;
438 439 440
  }
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
441
static void read_inter_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
442
                                       int mi_row, int mi_col, vp9_reader *r) {
443
  VP9_COMMON *const cm = &pbi->common;
444
  MACROBLOCKD *const xd = &pbi->mb;
445
  nmv_context *const nmvc = &cm->fc.nmvc;
446
  MB_MODE_INFO *const mbmi = &mi->mbmi;
447 448
  int_mv *const mv0 = &mbmi->mv[0];
  int_mv *const mv1 = &mbmi->mv[1];
449
  const BLOCK_SIZE_TYPE bsize = mbmi->sb_type;
450
  const int allow_hp = xd->allow_high_precision_mv;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
451

452 453
  int_mv nearest, nearby, best_mv;
  int_mv nearest_second, nearby_second, best_mv_second;
454
  uint8_t inter_mode_ctx;
455
  MV_REFERENCE_FRAME ref0, ref1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
456

Dmitry Kovalev's avatar
Dmitry Kovalev committed
457
  read_ref_frames(pbi, r, mbmi->segment_id, mbmi->ref_frame);
458 459
  ref0 = mbmi->ref_frame[0];
  ref1 = mbmi->ref_frame[1];
460

461
  vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
462 463
                   ref0, mbmi->ref_mvs[ref0], cm->ref_frame_sign_bias,
                   mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
464

465
  inter_mode_ctx = mbmi->mb_mode_context[ref0];
466

467
  if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP))
468
    mbmi->mode = ZEROMV;
469 470 471
  else if (bsize >= BLOCK_SIZE_SB8X8)
    mbmi->mode = read_inter_mode(cm, r, inter_mode_ctx);

472
  mbmi->uv_mode = DC_PRED;
473

474 475 476 477 478
  // 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;
  }
479

480 481 482 483 484 485
  mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
                            ? read_switchable_filter_type(pbi, r)
                            : cm->mcomp_filter_type;

  if (ref1 > INTRA_FRAME) {
    vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
486 487
                     ref1, mbmi->ref_mvs[ref1], cm->ref_frame_sign_bias,
                     mi_row, mi_col);
488 489

    if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
490 491 492
      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;
493
    }
494
  }
495

Dmitry Kovalev's avatar
Dmitry Kovalev committed
496 497 498
  if (bsize < BLOCK_SIZE_SB8X8) {
    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
499
    int idx, idy;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
500 501
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
502 503
        int_mv blockmv, secondmv;
        const int j = idy * 2 + idx;
504
        const int b_mode = read_inter_mode(cm, r, inter_mode_ctx);
505

506
        if (b_mode == NEARESTMV || b_mode == NEARMV) {
507 508 509
          vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0,
                                        mi_row, mi_col);

510 511
          if (ref1 > 0)
            vp9_append_sub8x8_mvs_for_idx(cm, xd,  &nearest_second,
512 513
                                         &nearby_second, j, 1,
                                         mi_row, mi_col);
514
        }
515

516
        switch (b_mode) {
517 518
          case NEWMV:
            read_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
519
                    &cm->counts.mv, allow_hp);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
520

521
            if (ref1 > 0)
522
              read_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
523
                      &cm->counts.mv, allow_hp);
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541
            break;
          case NEARESTMV:
            blockmv.as_int = nearest.as_int;
            if (ref1 > 0)
              secondmv.as_int = nearest_second.as_int;
            break;
          case NEARMV:
            blockmv.as_int = nearby.as_int;
            if (ref1 > 0)
              secondmv.as_int = nearby_second.as_int;
            break;
          case ZEROMV:
            blockmv.as_int = 0;
            if (ref1 > 0)
              secondmv.as_int = 0;
            break;
          default:
            assert(!"Invalid inter mode value");
542
        }
543 544 545
        mi->bmi[j].as_mv[0].as_int = blockmv.as_int;
        if (ref1 > 0)
          mi->bmi[j].as_mv[1].as_int = secondmv.as_int;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
546

Dmitry Kovalev's avatar
Dmitry Kovalev committed
547
        if (num_4x4_h == 2)
548
          mi->bmi[j + 2] = mi->bmi[j];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
549
        if (num_4x4_w == 2)
550
          mi->bmi[j + 1] = mi->bmi[j];
551
        mi->mbmi.mode = b_mode;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
552
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
553
    }
554 555 556

    mv0->as_int = mi->bmi[3].as_mv[0].as_int;
    mv1->as_int = mi->bmi[3].as_mv[1].as_int;
John Koleszar's avatar
John Koleszar committed
557
  } else {
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
    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;

    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);
        if (ref1 > 0)
          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);
        if (ref1 > 0)
          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;
        if (ref1 > 0)
          mv1->as_int = 0;
        break;

      case NEWMV:
597
        read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->counts.mv, allow_hp);
598
        if (ref1 > 0)
599 600
          read_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc, &cm->counts.mv,
                  allow_hp);
601 602 603 604
        break;
      default:
        assert(!"Invalid inter mode value");
    }
John Koleszar's avatar
John Koleszar committed
605
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
606
}
John Koleszar's avatar
John Koleszar committed
607

Dmitry Kovalev's avatar
Dmitry Kovalev committed
608 609
static void read_inter_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
                                       int mi_row, int mi_col, vp9_reader *r) {
610 611
  VP9_COMMON *const cm = &pbi->common;
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
612
  int inter_block;
613

Dmitry Kovalev's avatar
Dmitry Kovalev committed
614 615
  mbmi->mv[0].as_int = 0;
  mbmi->mv[1].as_int = 0;
616 617
  mbmi->segment_id = read_inter_segment_id(pbi, mi_row, mi_col, r);
  mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
618
  inter_block = read_is_inter_block(pbi, mbmi->segment_id, r);
619
  mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, mbmi->sb_type,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
620
                                 !mbmi->mb_skip_coeff || !inter_block, r);
621

Dmitry Kovalev's avatar
Dmitry Kovalev committed
622
  if (inter_block)
623
    read_inter_block_mode_info(pbi, mi, mi_row, mi_col, r);
624
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
625
    read_intra_block_mode_info(pbi, mi, r);
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
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]);
}

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

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

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

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

    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);
  }
691
}
692

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

704
  if (cm->frame_type == KEY_FRAME || cm->intra_only)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
705
    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
706
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
707
    read_inter_frame_mode_info(pbi, mi, mi_row, mi_col, r);
708

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