vp9_decodemv.c 22.9 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
367
      vp9_diff_update_prob(r, MODE_UPDATE_PROB,
                           &fc->switchable_interp_prob[j][i]);
368
369
}

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

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

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

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

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

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

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

426
  mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
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
467
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
468
static int read_is_inter_block(VP9D_COMP *pbi, int segment_id, vp9_reader *r) {
469
470
471
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

472
473
  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
474
           INTRA_FRAME;
475
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
476
477
478
479
    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;
480
481
482
  }
}

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

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

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

501
502
  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
503

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

506
  if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
507
    mbmi->mode = ZEROMV;
508
    assert(bsize >= BLOCK_8X8);
509
510
511
512
  } else {
    if (bsize >= BLOCK_8X8)
      mbmi->mode = read_inter_mode(cm, r, inter_mode_ctx);
  }
513

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

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

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

531
532
533
534
  mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
                              ? read_switchable_filter_type(pbi, r)
                              : cm->mcomp_filter_type;

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

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

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

557
558
        assign_mv(cm, b_mode, block, best, nearest, nearmv,
                  is_compound, allow_hp, r);
559

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

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

571
    mi->mbmi.mode = b_mode;
572

573
574
575
576
577
    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
578
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
579
}
John Koleszar's avatar
John Koleszar committed
580

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

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

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

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

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

  if (cm->comp_pred_mode != SINGLE_PREDICTION_ONLY)
    for (i = 0; i < REF_CONTEXTS; i++)
619
      vp9_diff_update_prob(r, MODE_UPDATE_PROB, &cm->fc.comp_ref_prob[i]);
620
621
}

622
623
void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
624
  int k;
625

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

631
632
633
634
635
636
637
638
639
640
641
  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++)
642
      vp9_diff_update_prob(r, MODE_UPDATE_PROB, &cm->fc.intra_inter_prob[i]);
643

644
    read_comp_pred(cm, r);
645
646

    for (j = 0; j < BLOCK_SIZE_GROUPS; j++)
647
      for (i = 0; i < INTRA_MODES - 1; ++i)
648
        vp9_diff_update_prob(r, MODE_UPDATE_PROB, &cm->fc.y_mode_prob[j][i]);
649
650
651

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

    read_mv_probs(r, nmvc, xd->allow_high_precision_mv);
  }
657
}
658

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

670
  if (cm->frame_type == KEY_FRAME || cm->intra_only)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
671
    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
672
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
673
    read_inter_frame_mode_info(pbi, mi, mi_row, mi_col, r);
674

675
676
677
678
  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;
      }
679
}