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
115
  const BLOCK_SIZE bsize = xd->this_mi->mbmi.sb_type;
  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->this_mi->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
635
636
637
638
639
640
641
642
643
644
  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++)
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->this_mi;
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 (cm->frame_type == KEY_FRAME || cm->intra_only)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
673
    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
674
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
675
    read_inter_frame_mode_info(pbi, mi, mi_row, mi_col, r);
676

677
678
679
680
  for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride)
    for (x = !y; x < x_mis; x++) {
        xd->mi_8x8[z + x] = mi;
      }
681
}