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

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

41
42
static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
  return treed_read(r, vp9_segment_tree, seg->tree_probs);
Scott LaVarnway's avatar
Scott LaVarnway committed
43
}
44

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

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

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

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

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

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

  for (y = 0; y < ymis; y++)
    for (x = 0; x < xmis; x++)
      cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
}

static int read_intra_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
                                 vp9_reader *r) {
  MACROBLOCKD *const xd = &pbi->mb;
97
  struct segmentation *const seg = &xd->seg;
98
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
99
  int segment_id;
100

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

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

  segment_id = read_segment_id(r, seg);
  set_segment_id(&pbi->common, bsize, mi_row, mi_col, segment_id);
  return segment_id;
}

static int read_inter_segment_id(VP9D_COMP *pbi, int mi_row, int mi_col,
                                 vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
  struct segmentation *const seg = &xd->seg;
  const BLOCK_SIZE_TYPE bsize = xd->mode_info_context->mbmi.sb_type;
  int pred_segment_id, segment_id;

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

  pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
                                       bsize, mi_row, mi_col);
  if (!seg->update_map)
    return pred_segment_id;

  if (seg->temporal_update) {
    const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(xd);
    const int pred_flag = vp9_read(r, pred_prob);
131
    vp9_set_pred_flag_seg_id(cm, bsize, mi_row, mi_col, pred_flag);
132
133
134
135
    segment_id = pred_flag ? pred_segment_id
                           : read_segment_id(r, seg);
  } else {
    segment_id = read_segment_id(r, seg);
136
  }
137
138
  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
  return segment_id;
139
140
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
153
154
static void read_intra_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *m,
                                       int mi_row, int mi_col, vp9_reader *r) {
155
156
157
158
159
  VP9_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;
  MB_MODE_INFO *const mbmi = &m->mbmi;
  const BLOCK_SIZE_TYPE bsize = mbmi->sb_type;
  const int mis = cm->mode_info_stride;
160

161
162
  mbmi->segment_id = read_intra_segment_id(pbi, mi_row, mi_col, r);
  mbmi->mb_skip_coeff = read_skip_coeff(pbi, mbmi->segment_id, r);
163
  mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, bsize, 1, r);
164
165
166
  mbmi->ref_frame[0] = INTRA_FRAME;

  if (bsize >= BLOCK_SIZE_SB8X8) {
167
168
169
    const MB_PREDICTION_MODE A = above_block_mode(m, 0, mis);
    const MB_PREDICTION_MODE L = xd->left_available ?
                                  left_block_mode(m, 0) : DC_PRED;
170
    mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
171
  } else {
172
    // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
173
174
    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
175
    int idx, idy;
176

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

304
305
  if (vp9_segfeature_active(&xd->seg, segment_id, SEG_LVL_REF_FRAME)) {
    ref_frame[0] = vp9_get_segdata(&xd->seg, segment_id, SEG_LVL_REF_FRAME);
306
307
    ref_frame[1] = NONE;
  } else {
308
    const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
309
    int is_comp;
John Koleszar's avatar
John Koleszar committed
310

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

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

343
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
344
  int i, j;
345
346
347
  for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j)
    for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i)
      if (vp9_read(r, VP9_MODE_UPDATE_PROB))
348
        vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
349
350
}

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
366
367
368
369
370
371
372
373
374
375
static INLINE void assign_and_clamp_mv(int_mv *dst, const int_mv *src,
                                       int mb_to_left_edge,
                                       int mb_to_right_edge,
                                       int mb_to_top_edge,
                                       int mb_to_bottom_edge) {
  dst->as_int = src->as_int;
  clamp_mv(dst, mb_to_left_edge, mb_to_right_edge, mb_to_top_edge,
           mb_to_bottom_edge);
}

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

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

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

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

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

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

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

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

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

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

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

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

461
462
  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
463

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

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

471
  mbmi->uv_mode = DC_PRED;
472

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

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
494
495
496
  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
497
    int idx, idy;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
498
499
    for (idy = 0; idy < 2; idy += num_4x4_h) {
      for (idx = 0; idx < 2; idx += num_4x4_w) {
500
501
        int_mv blockmv, secondmv;
        const int j = idy * 2 + idx;
502
        const int b_mode = read_inter_mode(cm, r, inter_mode_ctx);
503

504
        if (b_mode == NEARESTMV || b_mode == NEARMV) {
505
506
507
508
509
          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);
        }
510

511
        switch (b_mode) {
512
513
          case NEWMV:
            read_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
514
                    &cm->counts.mv, allow_hp);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
515

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

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

    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
552
  } else {
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
    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:
592
        read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->counts.mv, allow_hp);
593
        if (ref1 > 0)
594
595
          read_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc, &cm->counts.mv,
                  allow_hp);
596
597
598
599
        break;
      default:
        assert(!"Invalid inter mode value");
    }
John Koleszar's avatar
John Koleszar committed
600
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
601
}
John Koleszar's avatar
John Koleszar committed
602

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
617
618
  if (inter_block)
    read_inter_block_mode_info(pbi, mi, r);
619
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
620
    read_intra_block_mode_info(pbi, mi, r);
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
646
647
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]);
}

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

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

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

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

    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);
  }
686
}
687

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

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

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