vp9_decodemv.c 24.8 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 43 44 45 46 47 48 49
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]);
50 51
  }

52
  update_tx_counts(bsize, context, tx_size, &cm->counts.tx);
53
  return tx_size;
54 55
}

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

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

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

Paul Wilkins's avatar
Paul Wilkins committed
83
  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
84 85 86 87 88 89 90 91 92

  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;
93
  struct segmentation *const seg = &xd->seg;
94
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
95
  int segment_id;
96

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

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

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

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

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

157 158
  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);
159
  mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, bsize, 1, r);
160 161 162
  mbmi->ref_frame[0] = INTRA_FRAME;

  if (bsize >= BLOCK_SIZE_SB8X8) {
163 164 165
    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;
166
    mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
167
  } else {
168
    // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
169 170
    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
171
    int idx, idy;
172

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

189
    mbmi->mode = m->bmi[3].as_mode;
John Koleszar's avatar
John Koleszar committed
190
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
191

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

195 196
static int read_mv_component(vp9_reader *r,
                             const nmv_component *mvcomp, int usehp) {
197

198
  int mag, d, fr, hp;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
199 200
  const int sign = vp9_read(r, mvcomp->sign);
  const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
201
  const int class0 = mv_class == MV_CLASS_0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
202

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

210
    d = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
211 212
    for (i = 0; i < n; ++i)
      d |= vp9_read(r, mvcomp->bits[i]) << i;
213 214
  }

215 216
  // Fractional part
  fr = treed_read(r, vp9_mv_fp_tree,
217
                  class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
218 219


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

224
  // Result
225 226
  mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
  return sign ? -mag : mag;
227 228
}

229 230 231 232 233 234 235 236 237 238 239 240 241
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);

242
  vp9_inc_mv(&diff, counts);
243 244 245 246 247

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

248
static void update_mv(vp9_reader *r, vp9_prob *p, vp9_prob upd_p) {
249
  if (vp9_read(r, upd_p))
250
    *p = (vp9_read_literal(r, 7) << 1) | 1;
251 252
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
253
static void read_mv_probs(vp9_reader *r, nmv_context *mvc, int usehp) {
254
  int i, j, k;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
255 256

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

259
  for (i = 0; i < 2; ++i) {
260 261 262
    nmv_component *const comp = &mvc->comps[i];

    update_mv(r, &comp->sign, VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
263
    for (j = 0; j < MV_CLASSES - 1; ++j)
264
      update_mv(r, &comp->classes[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
265 266

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

    for (j = 0; j < MV_OFFSET_BITS; ++j)
270
      update_mv(r, &comp->bits[j], VP9_NMV_UPDATE_PROB);
271 272 273
  }

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

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

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

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

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

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

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

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

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

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

355 356 357
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
  COMPPREDMODE_TYPE mode = vp9_read_bit(r);
  if (mode)
358
    mode += vp9_read_bit(r);
359 360 361
  return mode;
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
362 363 364 365 366 367 368 369 370 371
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);
}

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
389 390 391
  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

392
  if (bsize >= BLOCK_SIZE_SB8X8) {
393
    const int size_group = size_group_lookup[bsize];
394
    mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[size_group]);
395
    cm->counts.y_mode[size_group][mbmi->mode]++;
396
  } else {
397
     // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
398 399
     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
400
     int idx, idy;
401

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
422
static int read_is_inter_block(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
423 424 425
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
426 427 428
  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;
429
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
430 431 432 433
    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;
434 435 436
  }
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
437
static void read_inter_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
438
                                  vp9_reader *r) {
439
  VP9_COMMON *const cm = &pbi->common;
440
  MACROBLOCKD *const xd = &pbi->mb;
441
  nmv_context *const nmvc = &cm->fc.nmvc;
442
  MB_MODE_INFO *const mbmi = &mi->mbmi;
443 444
  int_mv *const mv0 = &mbmi->mv[0];
  int_mv *const mv1 = &mbmi->mv[1];
445
  const BLOCK_SIZE_TYPE bsize = mbmi->sb_type;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
446

447 448 449 450
  int_mv nearest, nearby, best_mv;
  int_mv nearest_second, nearby_second, best_mv_second;
  vp9_prob *mv_ref_p;
  MV_REFERENCE_FRAME ref0, ref1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
451

Dmitry Kovalev's avatar
Dmitry Kovalev committed
452
  read_ref_frames(pbi, r, mbmi->segment_id, mbmi->ref_frame);
453 454
  ref0 = mbmi->ref_frame[0];
  ref1 = mbmi->ref_frame[1];
455

456 457
  vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
                   ref0, mbmi->ref_mvs[ref0], cm->ref_frame_sign_bias);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
458

459
  mv_ref_p = cm->fc.inter_mode_probs[mbmi->mb_mode_context[ref0]];
460

461 462 463 464 465 466 467
  if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
    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;
468

469 470 471 472 473
  // 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;
  }
474

475 476 477 478 479 480 481
  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,
                     ref1, mbmi->ref_mvs[ref1], cm->ref_frame_sign_bias);
482 483

    if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
484 485 486
      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;
487
    }
488
  }
489

Dmitry Kovalev's avatar
Dmitry Kovalev committed
490 491 492
  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
493
    int idx, idy;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
494 495
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
496 497 498
        int_mv blockmv, secondmv;
        const int j = idy * 2 + idx;
        const int blockmode = read_inter_mode(r, mv_ref_p);
499

500 501 502 503 504 505 506
        vp9_accum_mv_refs(cm, blockmode, mbmi->mb_mode_context[ref0]);
        if (blockmode == NEARESTMV || blockmode == NEARMV) {
          vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0);
          if (ref1 > 0)
            vp9_append_sub8x8_mvs_for_idx(cm, xd,  &nearest_second,
                                         &nearby_second, j, 1);
        }
507

508 509 510 511
        switch (blockmode) {
          case NEWMV:
            read_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
                    &cm->counts.mv, xd->allow_high_precision_mv);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
512

513
            if (ref1 > 0)
514
              read_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
515
                      &cm->counts.mv, xd->allow_high_precision_mv);
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533
            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");
534
        }
535 536 537
        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
538

Dmitry Kovalev's avatar
Dmitry Kovalev committed
539
        if (num_4x4_h == 2)
540
          mi->bmi[j + 2] = mi->bmi[j];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
541
        if (num_4x4_w == 2)
542 543
          mi->bmi[j + 1] = mi->bmi[j];
        mi->mbmi.mode = blockmode;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
544
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
545
    }
546 547 548

    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
549
  } else {
550 551 552 553 554 555 556 557 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 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;

    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:
        read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->counts.mv,
                xd->allow_high_precision_mv);
        if (ref1 > 0)
          read_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc,
                  &cm->counts.mv, xd->allow_high_precision_mv);
        break;
      default:
        assert(!"Invalid inter mode value");
    }
John Koleszar's avatar
John Koleszar committed
598
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
599
}
John Koleszar's avatar
John Koleszar committed
600

Dmitry Kovalev's avatar
Dmitry Kovalev committed
601 602
static void read_inter_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
                                       int mi_row, int mi_col, vp9_reader *r) {
603 604
  VP9_COMMON *const cm = &pbi->common;
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
605
  int inter_block;
606

Dmitry Kovalev's avatar
Dmitry Kovalev committed
607 608
  mbmi->mv[0].as_int = 0;
  mbmi->mv[1].as_int = 0;
609 610
  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
611
  inter_block = read_is_inter_block(pbi, mbmi->segment_id, r);
612
  mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, mbmi->sb_type,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
613
                                 !mbmi->mb_skip_coeff || !inter_block, r);
614

Dmitry Kovalev's avatar
Dmitry Kovalev committed
615 616
  if (inter_block)
    read_inter_block_mode_info(pbi, mi, r);
617
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
618
    read_intra_block_mode_info(pbi, mi, r);
619 620
}

621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
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]);
}

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

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

656 657 658 659 660 661 662 663 664 665 666 667 668 669
  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]);

670
    read_comp_pred(cm, r);
671 672 673 674 675 676 677 678 679 680 681 682 683

    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);
  }
684
}
685

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

697
  if (cm->frame_type == KEY_FRAME || cm->intra_only)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
698
    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
699
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
700
    read_inter_frame_mode_info(pbi, mi, mi_row, mi_col, r);
701

Jim Bankoski's avatar
Jim Bankoski committed
702 703 704
  for (y = 0; y < y_mis; y++)
    for (x = !y; x < x_mis; x++)
      mi[y * cm->mode_info_stride + x] = *mi;
705
}