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

33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
static MB_PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r,
                                            int size_group) {
  const MB_PREDICTION_MODE y_mode = read_intra_mode(r,
                                        cm->fc.y_mode_prob[size_group]);
  ++cm->counts.y_mode[size_group][y_mode];
  return y_mode;
}

static MB_PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r,
                                             MB_PREDICTION_MODE y_mode) {
  const MB_PREDICTION_MODE uv_mode = read_intra_mode(r,
                                         cm->fc.uv_mode_prob[y_mode]);
  ++cm->counts.uv_mode[y_mode][uv_mode];
  return uv_mode;
}

49 50
static MB_PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r,
                                          uint8_t context) {
51 52
  const MB_PREDICTION_MODE mode = treed_read(r, vp9_inter_mode_tree,
                                             cm->fc.inter_mode_probs[context]);
53 54
  ++cm->counts.inter_mode[context][inter_mode_offset(mode)];
  return mode;
55 56
}

57 58
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
59
}
60

61
static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
62
                                     BLOCK_SIZE bsize, vp9_reader *r) {
63 64 65
  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]);
66
  if (tx_size != TX_4X4 && bsize >= BLOCK_16X16) {
67
    tx_size += vp9_read(r, tx_probs[1]);
68
    if (tx_size != TX_8X8 && bsize >= BLOCK_32X32)
69
      tx_size += vp9_read(r, tx_probs[2]);
70 71
  }

72
  update_tx_counts(bsize, context, tx_size, &cm->counts.tx);
73
  return tx_size;
74 75
}

76
static TX_SIZE read_tx_size(VP9D_COMP *pbi, TX_MODE tx_mode,
77
                            BLOCK_SIZE bsize, int allow_select,
78
                            vp9_reader *r) {
79 80 81
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

82
  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
83
    return read_selected_tx_size(cm, xd, bsize, r);
84
  else if (tx_mode >= ALLOW_32X32 && bsize >= BLOCK_32X32)
85
    return TX_32X32;
86
  else if (tx_mode >= ALLOW_16X16 && bsize >= BLOCK_16X16)
87
    return TX_16X16;
88
  else if (tx_mode >= ALLOW_8X8 && bsize >= BLOCK_8X8)
89 90 91 92 93
    return TX_8X8;
  else
    return TX_4X4;
}

94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE bsize,
                           int mi_row, int mi_col, int segment_id) {
  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);
  const int xmis = MIN(cm->mi_cols - mi_col, bw);
  const int ymis = MIN(cm->mi_rows - mi_row, bh);
  int x, y;

  assert(segment_id >= 0 && segment_id < MAX_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;
}

110 111
static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
                                 vp9_reader *r) {
112
  MACROBLOCKD *const xd = &pbi->mb;
113
  struct segmentation *const seg = &pbi->common.seg;
114
  const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
115
  int segment_id;
116

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

  if (!seg->update_map)
121
    return 0;
122

123 124 125
  segment_id = read_segment_id(r, seg);
  set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id);
  return segment_id;
126 127 128 129 130 131
}

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;
132
  struct segmentation *const seg = &cm->seg;
133
  const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
134
  int pred_segment_id, segment_id;
135 136 137 138 139 140 141 142 143 144

  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) {
145
    const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
146
    const int pred_flag = vp9_read(r, pred_prob);
147
    vp9_set_pred_flag_seg_id(xd, pred_flag);
148 149
    segment_id = pred_flag ? pred_segment_id
                           : read_segment_id(r, seg);
150
  } else {
151
    segment_id = read_segment_id(r, seg);
152
  }
153 154
  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
  return segment_id;
155 156
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
169 170
static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m,
                                       int mi_row, int mi_col, vp9_reader *r) {
171 172 173
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
  MB_MODE_INFO *const mbmi = &m->mbmi;
174
  const BLOCK_SIZE bsize = mbmi->sb_type;
175 176
  const MODE_INFO *above_mi = xd->mi_8x8[-cm->mode_info_stride];
  const MODE_INFO *left_mi = xd->mi_8x8[-1];
177

178
  mbmi->segment_id = read_intra_segment_id(pbi, mi_row, mi_col, r);
Paul Wilkins's avatar
Paul Wilkins committed
179
  mbmi->skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
180
  mbmi->tx_size = read_tx_size(pbi, cm->tx_mode, bsize, 1, r);
181
  mbmi->ref_frame[0] = INTRA_FRAME;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
182
  mbmi->ref_frame[1] = NONE;
183

184
  if (bsize >= BLOCK_8X8) {
185
    const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
186
    const MB_PREDICTION_MODE L = xd->left_available ?
187
                                  left_block_mode(m, left_mi, 0) : DC_PRED;
188
    mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
189
  } else {
190
    // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
191 192
    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
193
    int idx, idy;
194

Dmitry Kovalev's avatar
Dmitry Kovalev committed
195 196
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
197
        const int ib = idy * 2 + idx;
198
        const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, ib);
199
        const MB_PREDICTION_MODE L = (xd->left_available || idx) ?
200
                                     left_block_mode(m, left_mi, ib) : DC_PRED;
201
        const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
202
                                              vp9_kf_y_mode_prob[A][L]);
203
        m->bmi[ib].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
204
        if (num_4x4_h == 2)
205
          m->bmi[ib + 2].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
206
        if (num_4x4_w == 2)
207
          m->bmi[ib + 1].as_mode = b_mode;
208 209
      }
    }
210

211
    mbmi->mode = m->bmi[3].as_mode;
John Koleszar's avatar
John Koleszar committed
212
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
213

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

217 218 219
static int read_mv_component(vp9_reader *r,
                             const nmv_component *mvcomp, int usehp) {
  int mag, d, fr, hp;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
220 221
  const int sign = vp9_read(r, mvcomp->sign);
  const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
222
  const int class0 = mv_class == MV_CLASS_0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
223

224
  // Integer part
225
  if (class0) {
226
    d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
227
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
228
    int i;
229
    const int n = mv_class + CLASS0_BITS - 1;  // number of bits
Dmitry Kovalev's avatar
Dmitry Kovalev committed
230

231
    d = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
232 233
    for (i = 0; i < n; ++i)
      d |= vp9_read(r, mvcomp->bits[i]) << i;
234 235
  }

236 237
  // Fractional part
  fr = treed_read(r, vp9_mv_fp_tree,
238
                  class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
239 240


241
  // High precision part (if hp is not used, the default value of the hp is 1)
242
  hp = usehp ? vp9_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp)
243
             : 1;
244

245
  // Result
246 247
  mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
  return sign ? -mag : mag;
248 249
}

250 251
static INLINE void read_mv(vp9_reader *r, MV *mv, const MV *ref,
                           const nmv_context *ctx,
252
                           nmv_context_counts *counts, int allow_hp) {
253
  const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
254
  const int use_hp = allow_hp && vp9_use_mv_hp(ref);
255 256 257
  MV diff = {0, 0};

  if (mv_joint_vertical(j))
258
    diff.row = read_mv_component(r, &ctx->comps[0], use_hp);
259 260

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

263
  vp9_inc_mv(&diff, counts);
264 265 266 267 268

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
269
static void update_mv(vp9_reader *r, vp9_prob *p) {
270
  if (vp9_read(r, NMV_UPDATE_PROB))
271
    *p = (vp9_read_literal(r, 7) << 1) | 1;
272 273
}

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
283 284
    update_mv(r, &comp->sign);

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

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

    for (j = 0; j < MV_OFFSET_BITS; ++j)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
292
      update_mv(r, &comp->bits[j]);
293 294 295
  }

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

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

    for (j = 0; j < 3; ++j)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
303
      update_mv(r, &comp->fp[j]);
304 305
  }

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

314
// Read the referncence frame
Dmitry Kovalev's avatar
Dmitry Kovalev committed
315 316
static void read_ref_frames(VP9D_COMP *pbi, vp9_reader *r,
                            int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
317
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
318
  MACROBLOCKD *const xd = &pbi->mb;
319
  FRAME_CONTEXT *const fc = &cm->fc;
320
  FRAME_COUNTS *const counts = &cm->counts;
321

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

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

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

      ref_frame[1] = NONE;
358
    }
John Koleszar's avatar
John Koleszar committed
359
  }
360
}
John Koleszar's avatar
John Koleszar committed
361

362
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
363
  int i, j;
364 365
  for (j = 0; j < SWITCHABLE_FILTERS + 1; ++j)
    for (i = 0; i < SWITCHABLE_FILTERS - 1; ++i)
366
      vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
367 368
}

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

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

383
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
384
    VP9D_COMP *pbi, vp9_reader *r) {
385 386
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
387
  const int ctx = vp9_get_pred_context_switchable_interp(xd);
388 389
  const int type = treed_read(r, vp9_switchable_interp_tree,
                              cm->fc.switchable_interp_prob[ctx]);
390 391
  ++cm->counts.switchable_interp[ctx][type];
  return type;
392 393
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
394
static void read_intra_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
395
                                  vp9_reader *r) {
396
  VP9_COMMON *const cm = &pbi->common;
397
  MB_MODE_INFO *const mbmi = &mi->mbmi;
398
  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
399

Dmitry Kovalev's avatar
Dmitry Kovalev committed
400 401 402
  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

403
  if (bsize >= BLOCK_8X8) {
404
    mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
405
  } else {
406
     // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
407 408
     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
409
     int idx, idy;
410

Dmitry Kovalev's avatar
Dmitry Kovalev committed
411 412
     for (idy = 0; idy < 2; idy += num_4x4_h) {
       for (idx = 0; idx < 2; idx += num_4x4_w) {
413
         const int ib = idy * 2 + idx;
414
         const int b_mode = read_intra_mode_y(cm, r, 0);
415
         mi->bmi[ib].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
416
         if (num_4x4_h == 2)
417
           mi->bmi[ib + 2].as_mode = b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
418
         if (num_4x4_w == 2)
419
           mi->bmi[ib + 1].as_mode = b_mode;
420 421
      }
    }
422
    mbmi->mode = mi->bmi[3].as_mode;
423 424
  }

425
  mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
426 427
}

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
static INLINE void assign_mv(VP9_COMMON *cm, MB_PREDICTION_MODE mode,
                             int_mv mv[2], int_mv best_mv[2],
                             int_mv nearest_mv[2], int_mv near_mv[2],
                             int is_compound, int allow_hp, vp9_reader *r) {
  int i;

  switch (mode) {
    case NEWMV:
       read_mv(r, &mv[0].as_mv, &best_mv[0].as_mv,
               &cm->fc.nmvc, &cm->counts.mv, allow_hp);
       if (is_compound)
         read_mv(r, &mv[1].as_mv, &best_mv[1].as_mv,
                 &cm->fc.nmvc, &cm->counts.mv, allow_hp);
       break;
    case NEARESTMV:
      mv[0].as_int = nearest_mv[0].as_int;
      if (is_compound)
        mv[1].as_int = nearest_mv[1].as_int;
      break;
    case NEARMV:
      mv[0].as_int = near_mv[0].as_int;
      if (is_compound)
        mv[1].as_int = near_mv[1].as_int;
      break;
    case ZEROMV:
      mv[0].as_int = 0;
      if (is_compound)
        mv[1].as_int = 0;
      break;
    default:
      assert(!"Invalid inter mode value.");
  }

  for (i = 0; i < 1 + is_compound; ++i) {
    assert(mv[i].as_mv.row < MV_UPP && mv[i].as_mv.row > MV_LOW);
    assert(mv[i].as_mv.col < MV_UPP && mv[i].as_mv.col > MV_LOW);
  }
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
467
static int read_is_inter_block(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
468 469 470
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

471 472
  if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
    return vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) !=
Dmitry Kovalev's avatar
Dmitry Kovalev committed
473
           INTRA_FRAME;
474
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
475 476 477 478
    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;
479 480 481
  }
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
482
static void read_inter_block_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
483
                                       int mi_row, int mi_col, vp9_reader *r) {
484
  VP9_COMMON *const cm = &pbi->common;
485
  MACROBLOCKD *const xd = &pbi->mb;
486
  MB_MODE_INFO *const mbmi = &mi->mbmi;
487
  const BLOCK_SIZE bsize = mbmi->sb_type;
488
  const int allow_hp = xd->allow_high_precision_mv;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
489

Yaowu Xu's avatar
Yaowu Xu committed
490
  int_mv nearest[2], nearmv[2], best[2];
491
  uint8_t inter_mode_ctx;
492
  MV_REFERENCE_FRAME ref0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
493
  int is_compound;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
494

495
  mbmi->uv_mode = DC_PRED;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
496
  read_ref_frames(pbi, r, mbmi->segment_id, mbmi->ref_frame);
497
  ref0 = mbmi->ref_frame[0];
498
  is_compound = has_second_ref(mbmi);
499

500 501
  vp9_find_mv_refs(cm, xd, mi, xd->last_mi, ref0, mbmi->ref_mvs[ref0],
                   mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
502

Paul Wilkins's avatar
Paul Wilkins committed
503
  inter_mode_ctx = mbmi->mode_context[ref0];
504

505
  if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
506
    mbmi->mode = ZEROMV;
507 508 509 510 511
    if (bsize < BLOCK_8X8) {
        vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
                           "Invalid usage of segement feature on small blocks");
        return;
    }
512 513 514 515
  } else {
    if (bsize >= BLOCK_8X8)
      mbmi->mode = read_inter_mode(cm, r, inter_mode_ctx);
  }
516

517
  // nearest, nearby
518
  if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
Yaowu Xu's avatar
Yaowu Xu committed
519
    vp9_find_best_ref_mvs(xd, mbmi->ref_mvs[ref0], &nearest[0], &nearmv[0]);
520
    best[0].as_int = nearest[0].as_int;
521
  }
522

Dmitry Kovalev's avatar
Dmitry Kovalev committed
523
  if (is_compound) {
524
    const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
525
    vp9_find_mv_refs(cm, xd, mi, xd->last_mi,
526
                     ref1, mbmi->ref_mvs[ref1], mi_row, mi_col);
527

528
    if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
Yaowu Xu's avatar
Yaowu Xu committed
529
      vp9_find_best_ref_mvs(xd, mbmi->ref_mvs[ref1], &nearest[1], &nearmv[1]);
530
      best[1].as_int = nearest[1].as_int;
531
    }
532
  }
533

534 535 536 537
  mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
                              ? read_switchable_filter_type(pbi, r)
                              : cm->mcomp_filter_type;

538
  if (bsize < BLOCK_8X8) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
539 540
    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
541
    int idx, idy;
542
    int b_mode;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
543 544
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
545
        int_mv block[2];
546
        const int j = idy * 2 + idx;
547
        b_mode = read_inter_mode(cm, r, inter_mode_ctx);
548

549
        if (b_mode == NEARESTMV || b_mode == NEARMV) {
Yaowu Xu's avatar
Yaowu Xu committed
550 551
          vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest[0],
                                        &nearmv[0], j, 0,
552 553
                                        mi_row, mi_col);

Dmitry Kovalev's avatar
Dmitry Kovalev committed
554
          if (is_compound)
Yaowu Xu's avatar
Yaowu Xu committed
555 556
            vp9_append_sub8x8_mvs_for_idx(cm, xd,  &nearest[1],
                                          &nearmv[1], j, 1,
557
                                          mi_row, mi_col);
558
        }
559

560 561
        assign_mv(cm, b_mode, block, best, nearest, nearmv,
                  is_compound, allow_hp, r);
562

563 564
        mi->bmi[j].as_mv[0].as_int = block[0].as_int;
        if (is_compound)
565
          mi->bmi[j].as_mv[1].as_int = block[1].as_int;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
566

Dmitry Kovalev's avatar
Dmitry Kovalev committed
567
        if (num_4x4_h == 2)
568
          mi->bmi[j + 2] = mi->bmi[j];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
569
        if (num_4x4_w == 2)
570
          mi->bmi[j + 1] = mi->bmi[j];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
571
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
572
    }
573

574
    mi->mbmi.mode = b_mode;
575

576 577 578 579 580
    mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
    mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
  } else {
    assign_mv(cm, mbmi->mode, mbmi->mv, best, nearest, nearmv,
              is_compound, allow_hp, r);
John Koleszar's avatar
John Koleszar committed
581
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
582
}
John Koleszar's avatar
John Koleszar committed
583

Dmitry Kovalev's avatar
Dmitry Kovalev committed
584 585
static void read_inter_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
                                       int mi_row, int mi_col, vp9_reader *r) {
586 587
  VP9_COMMON *const cm = &pbi->common;
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
588
  int inter_block;
589

Dmitry Kovalev's avatar
Dmitry Kovalev committed
590 591
  mbmi->mv[0].as_int = 0;
  mbmi->mv[1].as_int = 0;
592
  mbmi->segment_id = read_inter_segment_id(pbi, mi_row, mi_col, r);
Paul Wilkins's avatar
Paul Wilkins committed
593
  mbmi->skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
594
  inter_block = read_is_inter_block(pbi, mbmi->segment_id, r);
595 596
  mbmi->tx_size = read_tx_size(pbi, cm->tx_mode, mbmi->sb_type,
                               !mbmi->skip_coeff || !inter_block, r);
597

Dmitry Kovalev's avatar
Dmitry Kovalev committed
598
  if (inter_block)
599
    read_inter_block_mode_info(pbi, mi, mi_row, mi_col, r);
600
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
601
    read_intra_block_mode_info(pbi, mi, r);
602 603
}

604 605 606 607 608 609 610 611
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++)
612
      vp9_diff_update_prob(r, &cm->fc.comp_inter_prob[i]);
613 614 615

  if (cm->comp_pred_mode != COMP_PREDICTION_ONLY)
    for (i = 0; i < REF_CONTEXTS; i++) {
616 617
      vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][0]);
      vp9_diff_update_prob(r, &cm->fc.single_ref_prob[i][1]);
618 619 620 621
    }

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

625 626
void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
627
  int k;
628

629
  // TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
Deb Mukherjee's avatar
Deb Mukherjee committed
630
  // vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
631
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
632
    vp9_diff_update_prob(r, &cm->fc.mbskip_probs[k]);
633

634
  if (!frame_is_intra_only(cm)) {
635 636 637 638 639 640 641 642 643 644
    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++)
645
      vp9_diff_update_prob(r, &cm->fc.intra_inter_prob[i]);
646

647
    read_comp_pred(cm, r);
648 649

    for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
650
      for (i = 0; i < INTRA_MODES - 1; ++i)
651
        vp9_diff_update_prob(r, &cm->fc.y_mode_prob[j][i]);
652 653 654

    for (j = 0; j < NUM_PARTITION_CONTEXTS; ++j)
      for (i = 0; i < PARTITION_TYPES - 1; ++i)
655
        vp9_diff_update_prob(r, &cm->fc.partition_prob[INTER_FRAME][j][i]);
656 657 658

    read_mv_probs(r, nmvc, xd->allow_high_precision_mv);
  }
659
}
660

661
void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r) {
662
  VP9_COMMON *const cm = &pbi->common;
663
  MACROBLOCKD *const xd = &pbi->mb;
664
  MODE_INFO *mi = xd->mi_8x8[0];
665
  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
Jim Bankoski's avatar
Jim Bankoski committed
666 667 668 669
  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);
670
  int x, y, z;
671

672
  if (frame_is_intra_only(cm))
Dmitry Kovalev's avatar
Dmitry Kovalev committed
673
    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
674
  else