vp9_decodemv.c 24.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
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
  mbmi->ref_frame[0] = INTRA_FRAME;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
165
  mbmi->ref_frame[1] = NONE;
166
167

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
253
254
static void update_mv(vp9_reader *r, vp9_prob *p) {
  if (vp9_read(r, VP9_NMV_UPDATE_PROB))
255
    *p = (vp9_read_literal(r, 7) << 1) | 1;
256
257
}

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

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

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

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

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

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

    for (j = 0; j < MV_OFFSET_BITS; ++j)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276
      update_mv(r, &comp->bits[j]);
277
278
279
  }

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

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

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

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

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

306
307
  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);
308
309
    ref_frame[1] = NONE;
  } else {
310
    const int comp_ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
311
    int is_comp;
John Koleszar's avatar
John Koleszar committed
312

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

Ronald S. Bultje's avatar
Ronald S. Bultje committed
320
321
    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
    if (is_comp) {
322
      const int fix_ref_idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
323
      const int ref_ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
324
      const int b = vp9_read(r, fc->comp_ref_prob[ref_ctx]);
325
      counts->comp_ref[ref_ctx][b]++;
326
      ref_frame[fix_ref_idx] = cm->comp_fixed_ref;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
327
      ref_frame[!fix_ref_idx] = cm->comp_var_ref[b];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
328
    } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
329
330
331
332
333
334
335
336
      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
337
338
      } else {
        ref_frame[0] = LAST_FRAME;
John Koleszar's avatar
John Koleszar committed
339
      }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
340
341

      ref_frame[1] = NONE;
342
    }
John Koleszar's avatar
John Koleszar committed
343
  }
344
}
John Koleszar's avatar
John Koleszar committed
345

346
static void read_switchable_interp_probs(FRAME_CONTEXT *fc, vp9_reader *r) {
347
  int i, j;
348
349
350
  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))
351
        vp9_diff_update_prob(r, &fc->switchable_interp_prob[j][i]);
352
353
}

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

362
363
364
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
  COMPPREDMODE_TYPE mode = vp9_read_bit(r);
  if (mode)
365
    mode += vp9_read_bit(r);
366
367
368
  return mode;
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
369
370
371
372
373
374
375
376
377
378
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);
}

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
396
397
398
  mbmi->ref_frame[0] = INTRA_FRAME;
  mbmi->ref_frame[1] = NONE;

399
  if (bsize >= BLOCK_SIZE_SB8X8) {
400
    const int size_group = size_group_lookup[bsize];
401
    mbmi->mode = read_intra_mode(r, cm->fc.y_mode_prob[size_group]);
402
    cm->counts.y_mode[size_group][mbmi->mode]++;
403
  } else {
404
     // Only 4x4, 4x8, 8x4 blocks
Dmitry Kovalev's avatar
Dmitry Kovalev committed
405
406
     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
407
     int idx, idy;
408

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

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(r, cm->fc.uv_mode_prob[mbmi->mode]);
426
  cm->counts.uv_mode[mbmi->mode][mbmi->uv_mode]++;
427
428
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
433
434
435
  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;
436
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
437
438
439
440
    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;
441
442
443
  }
}

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

455
456
  int_mv nearest, nearby, best_mv;
  int_mv nearest_second, nearby_second, best_mv_second;
457
  uint8_t inter_mode_ctx;
458
  MV_REFERENCE_FRAME ref0, ref1;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
459

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

464
  vp9_find_mv_refs(cm, xd, mi, xd->prev_mode_info_context,
465
466
                   ref0, mbmi->ref_mvs[ref0], cm->ref_frame_sign_bias,
                   mi_row, mi_col);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
467

468
  inter_mode_ctx = mbmi->mb_mode_context[ref0];
469

470
  if (vp9_segfeature_active(&xd->seg, mbmi->segment_id, SEG_LVL_SKIP))
471
    mbmi->mode = ZEROMV;
472
473
474
  else if (bsize >= BLOCK_SIZE_SB8X8)
    mbmi->mode = read_inter_mode(cm, r, inter_mode_ctx);

475
  mbmi->uv_mode = DC_PRED;
476

477
478
479
480
481
  // 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;
  }
482

483
484
485
486
487
488
  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,
489
490
                     ref1, mbmi->ref_mvs[ref1], cm->ref_frame_sign_bias,
                     mi_row, mi_col);
491
492

    if (bsize < BLOCK_SIZE_SB8X8 || mbmi->mode != ZEROMV) {
493
494
495
      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;
496
    }
497
  }
498

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

509
        if (b_mode == NEARESTMV || b_mode == NEARMV) {
510
511
512
          vp9_append_sub8x8_mvs_for_idx(cm, xd, &nearest, &nearby, j, 0,
                                        mi_row, mi_col);

513
514
          if (ref1 > 0)
            vp9_append_sub8x8_mvs_for_idx(cm, xd,  &nearest_second,
515
516
                                         &nearby_second, j, 1,
                                         mi_row, mi_col);
517
        }
518

519
        switch (b_mode) {
520
521
          case NEWMV:
            read_mv(r, &blockmv.as_mv, &best_mv.as_mv, nmvc,
522
                    &cm->counts.mv, allow_hp);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
523

524
            if (ref1 > 0)
525
              read_mv(r, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
526
                      &cm->counts.mv, allow_hp);
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
            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");
545
        }
546
547
548
        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
549

Dmitry Kovalev's avatar
Dmitry Kovalev committed
550
        if (num_4x4_h == 2)
551
          mi->bmi[j + 2] = mi->bmi[j];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
552
        if (num_4x4_w == 2)
553
          mi->bmi[j + 1] = mi->bmi[j];
554
        mi->mbmi.mode = b_mode;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
555
      }
Scott LaVarnway's avatar
Scott LaVarnway committed
556
    }
557
558
559

    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
560
  } else {
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
    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:
600
        read_mv(r, &mv0->as_mv, &best_mv.as_mv, nmvc, &cm->counts.mv, allow_hp);
601
        if (ref1 > 0)
602
603
          read_mv(r, &mv1->as_mv, &best_mv_second.as_mv, nmvc, &cm->counts.mv,
                  allow_hp);
604
605
606
607
        break;
      default:
        assert(!"Invalid inter mode value");
    }
John Koleszar's avatar
John Koleszar committed
608
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
609
}
John Koleszar's avatar
John Koleszar committed
610

Dmitry Kovalev's avatar
Dmitry Kovalev committed
611
612
static void read_inter_frame_mode_info(VP9D_COMP *pbi, MODE_INFO *mi,
                                       int mi_row, int mi_col, vp9_reader *r) {
613
614
  VP9_COMMON *const cm = &pbi->common;
  MB_MODE_INFO *const mbmi = &mi->mbmi;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
615
  int inter_block;
616

Dmitry Kovalev's avatar
Dmitry Kovalev committed
617
618
  mbmi->mv[0].as_int = 0;
  mbmi->mv[1].as_int = 0;
619
620
  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
621
  inter_block = read_is_inter_block(pbi, mbmi->segment_id, r);
622
  mbmi->txfm_size = read_tx_size(pbi, cm->tx_mode, mbmi->sb_type,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
623
                                 !mbmi->mb_skip_coeff || !inter_block, r);
624

Dmitry Kovalev's avatar
Dmitry Kovalev committed
625
  if (inter_block)
626
    read_inter_block_mode_info(pbi, mi, mi_row, mi_col, r);
627
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
628
    read_intra_block_mode_info(pbi, mi, r);
629
630
}

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
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]);
}

656
657
void vp9_prepare_read_mode_info(VP9D_COMP* pbi, vp9_reader *r) {
  VP9_COMMON *const cm = &pbi->common;
658
  int k;
659

660
  // TODO(jkoleszar): does this clear more than MBSKIP_CONTEXTS? Maybe remove.
Deb Mukherjee's avatar
Deb Mukherjee committed
661
  // vpx_memset(cm->fc.mbskip_probs, 0, sizeof(cm->fc.mbskip_probs));
662
663
  for (k = 0; k < MBSKIP_CONTEXTS; ++k)
    if (vp9_read(r, VP9_MODE_UPDATE_PROB))
664
      vp9_diff_update_prob(r, &cm->fc.mbskip_probs[k]);
665

666
667
668
669
670
671
672
673
674
675
676
677
678
679
  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]);

680
    read_comp_pred(cm, r);
681
682
683
684
685
686
687
688
689
690
691
692
693

    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);
  }
694
}
695

696
void vp9_read_mode_info(VP9D_COMP* pbi, int mi_row, int mi_col, vp9_reader *r) {
697
  VP9_COMMON *const cm = &pbi->common;
698
  MACROBLOCKD *const xd = &pbi->mb;
699
  MODE_INFO *mi = xd->mode_info_context;
700
  const BLOCK_SIZE_TYPE bsize = mi->mbmi.sb_type;
Jim Bankoski's avatar
Jim Bankoski committed
701
702
703
704
705
  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;
706

707
  if (cm->frame_type == KEY_FRAME || cm->intra_only)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
708
    read_intra_frame_mode_info(pbi, mi, mi_row, mi_col, r);
709
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
710
    read_inter_frame_mode_info(pbi, mi, mi_row, mi_col, r);
711

Jim Bankoski's avatar
Jim Bankoski committed
712
713
714
  for (y = 0; y < y_mis; y++)
    for (x = !y; x < x_mis; x++)
      mi[y * cm->mode_info_stride + x] = *mi;
715
}