vp9_decodemv.c 47.3 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 "vp9/decoder/vp9_treereader.h"
13 14
#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_entropymode.h"
15
#include "vp9/common/vp9_reconinter.h"
16
#include "vp9/decoder/vp9_onyxd_int.h"
17
#include "vp9/common/vp9_findnearmv.h"
Ronald S. Bultje's avatar
Ronald S. Bultje committed
18
#include "vp9/common/vp9_common.h"
19 20 21 22 23
#include "vp9/common/vp9_seg_common.h"
#include "vp9/common/vp9_pred_common.h"
#include "vp9/common/vp9_entropy.h"
#include "vp9/decoder/vp9_decodemv.h"
#include "vp9/common/vp9_mvref_common.h"
John Koleszar's avatar
John Koleszar committed
24 25 26
#if CONFIG_DEBUG
#include <assert.h>
#endif
27

John Koleszar's avatar
John Koleszar committed
28
// #define DEBUG_DEC_MV
29 30 31
#ifdef DEBUG_DEC_MV
int dec_mvcount = 0;
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
32

33 34 35 36
// #define DEC_DEBUG
#ifdef DEC_DEBUG
extern int dec_debug;
#endif
37

38 39
static B_PREDICTION_MODE read_bmode(vp9_reader *r, const vp9_prob *p) {
  B_PREDICTION_MODE m = treed_read(r, vp9_bmode_tree, p);
40 41 42 43 44 45 46 47
#if CONFIG_NEWBINTRAMODES
  if (m == B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS)
    m = B_CONTEXT_PRED;
  assert(m < B_CONTEXT_PRED - CONTEXT_PRED_REPLACEMENTS || m == B_CONTEXT_PRED);
#endif
  return m;
}

48 49
static B_PREDICTION_MODE read_kf_bmode(vp9_reader *r, const vp9_prob *p) {
  return (B_PREDICTION_MODE)treed_read(r, vp9_kf_bmode_tree, p);
Scott LaVarnway's avatar
Scott LaVarnway committed
50 51
}

52 53
static MB_PREDICTION_MODE read_ymode(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(r, vp9_ymode_tree, p);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
54
}
Scott LaVarnway's avatar
Scott LaVarnway committed
55

56 57
static MB_PREDICTION_MODE read_sb_ymode(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(r, vp9_sb_ymode_tree, p);
58 59
}

60 61
static MB_PREDICTION_MODE read_kf_sb_ymode(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(r, vp9_uv_mode_tree, p);
Scott LaVarnway's avatar
Scott LaVarnway committed
62 63
}

64 65
static MB_PREDICTION_MODE read_kf_mb_ymode(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(r, vp9_kf_ymode_tree, p);
Scott LaVarnway's avatar
Scott LaVarnway committed
66 67
}

68 69
static int read_i8x8_mode(vp9_reader *r, const vp9_prob *p) {
  return treed_read(r, vp9_i8x8_mode_tree, p);
Yaowu Xu's avatar
Yaowu Xu committed
70
}
Scott LaVarnway's avatar
Scott LaVarnway committed
71

72 73
static MB_PREDICTION_MODE read_uv_mode(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(r, vp9_uv_mode_tree, p);
Scott LaVarnway's avatar
Scott LaVarnway committed
74 75
}

76 77 78 79
static int read_mb_segid(vp9_reader *r, MACROBLOCKD *xd) {
  const vp9_prob *const p = xd->mb_segment_tree_probs;
  return vp9_read(r, p[0]) ? 2 + vp9_read(r, p[2])
                           :     vp9_read(r, p[1]);
Scott LaVarnway's avatar
Scott LaVarnway committed
80
}
81

82 83
// This function reads the current macro block's segnent id from the bitstream
// It should only be called if a segment map update is indicated.
84 85 86
static int read_mb_segid_except(vp9_reader *r,
                                VP9_COMMON *cm, MACROBLOCKD *xd,
                                int mb_row, int mb_col) {
87 88 89 90
  const int mb_index = mb_row * cm->mb_cols + mb_col;
  const int pred_seg_id = vp9_get_pred_mb_segid(cm, xd, mb_index);
  const vp9_prob *const p = xd->mb_segment_tree_probs;
  const vp9_prob prob = xd->mb_segment_mispred_tree_probs[pred_seg_id];
91

92 93 94
  return vp9_read(r, prob)
             ? 2 + (pred_seg_id  < 2 ? vp9_read(r, p[2]) : (pred_seg_id == 2))
             :     (pred_seg_id >= 2 ? vp9_read(r, p[1]) : (pred_seg_id == 0));
95 96
}

97 98 99 100 101 102 103 104 105 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 131 132 133 134 135 136 137 138 139 140 141 142
static void set_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi,
                           int mb_row, int mb_col, int segment_id) {
  const int mb_index = mb_row * cm->mb_cols + mb_col;
  const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
  if (sb_type) {
    const int bw = 1 << mb_width_log2(sb_type);
    const int bh = 1 << mb_height_log2(sb_type);
    const int ymbs = MIN(cm->mb_rows - mb_row, bh);
    const int xmbs = MIN(cm->mb_cols - mb_col, bw);
    int x, y;

    for (y = 0; y < ymbs; y++) {
      for (x = 0; x < xmbs; x++) {
        const int index = mb_index + (y * cm->mb_cols + x);
        cm->last_frame_seg_map[index] = segment_id;
      }
    }
  } else {
    cm->last_frame_seg_map[mb_index] = segment_id;
  }
}

static int get_segment_id(VP9_COMMON *cm, MB_MODE_INFO *mbmi,
                          int mb_row, int mb_col) {
  const int mb_index = mb_row * cm->mb_cols + mb_col;
  const BLOCK_SIZE_TYPE sb_type = mbmi->sb_type;
  if (sb_type) {
    const int bw = 1 << mb_width_log2(sb_type);
    const int bh = 1 << mb_height_log2(sb_type);
    const int ymbs = MIN(cm->mb_rows - mb_row, bh);
    const int xmbs = MIN(cm->mb_cols - mb_col, bw);
    int segment_id = INT_MAX;
    int x, y;

    for (y = 0; y < ymbs; y++) {
      for (x = 0; x < xmbs; x++) {
        const int index = mb_index + (y * cm->mb_cols + x);
        segment_id = MIN(segment_id, cm->last_frame_seg_map[index]);
      }
    }
    return segment_id;
  } else {
    return cm->last_frame_seg_map[mb_index];
  }
}

143
extern const int vp9_i8x8_block[4];
144 145 146
static void kfread_modes(VP9D_COMP *pbi, MODE_INFO *m,
                         int mb_row, int mb_col,
                         vp9_reader *r) {
147
  VP9_COMMON *const cm = &pbi->common;
148 149
  MACROBLOCKD *const xd = &pbi->mb;
  const int mis = cm->mode_info_stride;
150 151
  m->mbmi.ref_frame = INTRA_FRAME;

John Koleszar's avatar
John Koleszar committed
152 153 154
  // Read the Macroblock segmentation map if it is being updated explicitly
  // this frame (reset to 0 by default).
  m->mbmi.segment_id = 0;
155 156 157
  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
    m->mbmi.segment_id = read_mb_segid(r, xd);
    set_segment_id(cm, &m->mbmi, mb_row, mb_col, m->mbmi.segment_id);
John Koleszar's avatar
John Koleszar committed
158 159
  }

160 161 162
  m->mbmi.mb_skip_coeff = vp9_segfeature_active(&pbi->mb, m->mbmi.segment_id,
                                                SEG_LVL_SKIP);
  if (!m->mbmi.mb_skip_coeff)
163
    m->mbmi.mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
John Koleszar's avatar
John Koleszar committed
164

165 166 167
  m->mbmi.mode = m->mbmi.sb_type ?
      read_kf_sb_ymode(r, cm->sb_kf_ymode_prob[cm->kf_ymode_probs_index]):
      read_kf_mb_ymode(r, cm->kf_ymode_prob[cm->kf_ymode_probs_index]);
168

John Koleszar's avatar
John Koleszar committed
169
  m->mbmi.ref_frame = INTRA_FRAME;
Paul Wilkins's avatar
Paul Wilkins committed
170

171
  if (m->mbmi.mode == I4X4_PRED) {
John Koleszar's avatar
John Koleszar committed
172 173
    int i = 0;
    do {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
174
      const B_PREDICTION_MODE a = above_block_mode(m, i, mis);
175
      const B_PREDICTION_MODE l = xd->left_available || (i & 3) ?
176
                                  left_block_mode(m, i) : B_DC_PRED;
Paul Wilkins's avatar
Paul Wilkins committed
177

178
      m->bmi[i].as_mode.first = read_kf_bmode(r, cm->kf_bmode_prob[a][l]);
John Koleszar's avatar
John Koleszar committed
179 180
    } while (++i < 16);
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
181

182
  if (m->mbmi.mode == I8X8_PRED) {
John Koleszar's avatar
John Koleszar committed
183 184
    int i;
    for (i = 0; i < 4; i++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
185
      const int ib = vp9_i8x8_block[i];
186
      const int mode8x8 = read_i8x8_mode(r, cm->fc.i8x8_mode_prob);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
187

John Koleszar's avatar
John Koleszar committed
188 189 190 191 192
      m->bmi[ib + 0].as_mode.first = mode8x8;
      m->bmi[ib + 1].as_mode.first = mode8x8;
      m->bmi[ib + 4].as_mode.first = mode8x8;
      m->bmi[ib + 5].as_mode.first = mode8x8;
    }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
193
  } else {
194
    m->mbmi.uv_mode = read_uv_mode(r, cm->kf_uv_mode_prob[m->mbmi.mode]);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
195
  }
196

Dmitry Kovalev's avatar
Dmitry Kovalev committed
197 198
  if (cm->txfm_mode == TX_MODE_SELECT &&
      m->mbmi.mb_skip_coeff == 0 &&
199
      m->mbmi.mode <= I8X8_PRED) {
200
    // FIXME(rbultje) code ternary symbol once all experiments are merged
201
    m->mbmi.txfm_size = vp9_read(r, cm->prob_tx[0]);
202
    if (m->mbmi.txfm_size != TX_4X4 && m->mbmi.mode != I8X8_PRED) {
203
      m->mbmi.txfm_size += vp9_read(r, cm->prob_tx[1]);
204
      if (m->mbmi.txfm_size != TX_8X8 && m->mbmi.sb_type >= BLOCK_SIZE_SB32X32)
205
        m->mbmi.txfm_size += vp9_read(r, cm->prob_tx[2]);
206
    }
207 208
  } else if (cm->txfm_mode >= ALLOW_32X32 &&
             m->mbmi.sb_type >= BLOCK_SIZE_SB32X32) {
209
    m->mbmi.txfm_size = TX_32X32;
210
  } else if (cm->txfm_mode >= ALLOW_16X16 && m->mbmi.mode <= TM_PRED) {
211
    m->mbmi.txfm_size = TX_16X16;
Yaowu Xu's avatar
Yaowu Xu committed
212
  } else if (cm->txfm_mode >= ALLOW_8X8 && m->mbmi.mode != I4X4_PRED) {
213 214 215 216
    m->mbmi.txfm_size = TX_8X8;
  } else {
    m->mbmi.txfm_size = TX_4X4;
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
217
}
John Koleszar's avatar
John Koleszar committed
218

219
static int read_nmv_component(vp9_reader *r,
220 221
                              int rv,
                              const nmv_component *mvcomp) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
222 223 224 225 226
  int mag, d;
  const int sign = vp9_read(r, mvcomp->sign);
  const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
237 238
  mag = vp9_get_mv_mag(mv_class, d << 3);
  return sign ? -(mag + 8) : (mag + 8);
239 240
}

241
static int read_nmv_component_fp(vp9_reader *r,
242 243 244 245
                                 int v,
                                 int rv,
                                 const nmv_component *mvcomp,
                                 int usehp) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
246 247 248 249 250 251 252
  const int sign = v < 0;
  int mag = ((sign ? -v : v) - 1) & ~7;  // magnitude - 1
  int offset;
  const int mv_class = vp9_get_mv_class(mag, &offset);
  const int f = mv_class == MV_CLASS_0 ?
      treed_read(r, vp9_mv_fp_tree, mvcomp->class0_fp[offset >> 3]):
      treed_read(r, vp9_mv_fp_tree, mvcomp->fp);
253

Dmitry Kovalev's avatar
Dmitry Kovalev committed
254
  offset += f << 1;
255 256

  if (usehp) {
257 258
    const vp9_prob p = mv_class == MV_CLASS_0 ? mvcomp->class0_hp : mvcomp->hp;
    offset += vp9_read(r, p);
259
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
260
    offset += 1;  // If hp is not used, the default value of the hp bit is 1
261
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
262 263
  mag = vp9_get_mv_mag(mv_class, offset);
  return sign ? -(mag + 1) : (mag + 1);
264 265
}

266
static void read_nmv(vp9_reader *r, MV *mv, const MV *ref,
267
                     const nmv_context *mvctx) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
268
  const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, mvctx->joints);
269 270
  mv->row = mv->col = 0;

271
  if (mv_joint_vertical(j))
272
    mv->row = read_nmv_component(r, ref->row, &mvctx->comps[0]);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
273

274
  if (mv_joint_horizontal(j))
275 276 277
    mv->col = read_nmv_component(r, ref->col, &mvctx->comps[1]);
}

278
static void read_nmv_fp(vp9_reader *r, MV *mv, const MV *ref,
279
                        const nmv_context *mvctx, int usehp) {
280
  const MV_JOINT_TYPE j = vp9_get_mv_joint(mv);
281
  usehp = usehp && vp9_use_nmv_hp(ref);
282
  if (mv_joint_vertical(j))
283 284
    mv->row = read_nmv_component_fp(r, mv->row, ref->row, &mvctx->comps[0],
                                    usehp);
285

286
  if (mv_joint_horizontal(j))
287 288 289 290
    mv->col = read_nmv_component_fp(r, mv->col, ref->col, &mvctx->comps[1],
                                    usehp);
}

291
static void update_nmv(vp9_reader *r, vp9_prob *const p,
292
                       const vp9_prob upd_p) {
293
  if (vp9_read(r, upd_p)) {
294
#ifdef LOW_PRECISION_MV_UPDATE
295
    *p = (vp9_read_literal(r, 7) << 1) | 1;
296
#else
297
    *p = (vp9_read_literal(r, 8));
298 299 300 301
#endif
  }
}

302
static void read_nmvprobs(vp9_reader *r, nmv_context *mvctx,
303 304
                          int usehp) {
  int i, j, k;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
305

306
#ifdef MV_GROUP_UPDATE
307
  if (!vp9_read_bit(r))
Dmitry Kovalev's avatar
Dmitry Kovalev committed
308
    return;
309
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
310
  for (j = 0; j < MV_JOINTS - 1; ++j)
311
    update_nmv(r, &mvctx->joints[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
312

313
  for (i = 0; i < 2; ++i) {
314
    update_nmv(r, &mvctx->comps[i].sign, VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
315
    for (j = 0; j < MV_CLASSES - 1; ++j)
316
      update_nmv(r, &mvctx->comps[i].classes[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
317 318

    for (j = 0; j < CLASS0_SIZE - 1; ++j)
319
      update_nmv(r, &mvctx->comps[i].class0[j], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
320 321

    for (j = 0; j < MV_OFFSET_BITS; ++j)
322
      update_nmv(r, &mvctx->comps[i].bits[j], VP9_NMV_UPDATE_PROB);
323 324 325
  }

  for (i = 0; i < 2; ++i) {
326
    for (j = 0; j < CLASS0_SIZE; ++j)
327
      for (k = 0; k < 3; ++k)
328
        update_nmv(r, &mvctx->comps[i].class0_fp[j][k], VP9_NMV_UPDATE_PROB);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
329 330

    for (j = 0; j < 3; ++j)
331
      update_nmv(r, &mvctx->comps[i].fp[j], VP9_NMV_UPDATE_PROB);
332 333 334 335
  }

  if (usehp) {
    for (i = 0; i < 2; ++i) {
336 337
      update_nmv(r, &mvctx->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
      update_nmv(r, &mvctx->comps[i].hp, VP9_NMV_UPDATE_PROB);
338 339 340 341
    }
  }
}

342
// Read the referncence frame
343
static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
344
                                         vp9_reader *r,
345
                                         int segment_id) {
John Koleszar's avatar
John Koleszar committed
346
  MV_REFERENCE_FRAME ref_frame;
347
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
348 349
  MACROBLOCKD *const xd = &pbi->mb;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
350
  int seg_ref_count = 0;
351 352 353 354 355 356 357
  const int seg_ref_active = vp9_segfeature_active(xd, segment_id,
                                                   SEG_LVL_REF_FRAME);

  const int intra = vp9_check_segref(xd, segment_id, INTRA_FRAME);
  const int last = vp9_check_segref(xd, segment_id, LAST_FRAME);
  const int golden = vp9_check_segref(xd, segment_id, GOLDEN_FRAME);
  const int altref = vp9_check_segref(xd, segment_id, ALTREF_FRAME);
John Koleszar's avatar
John Koleszar committed
358 359 360

  // If segment coding enabled does the segment allow for more than one
  // possible reference frame
361 362
  if (seg_ref_active)
    seg_ref_count = intra + last + golden + altref;
John Koleszar's avatar
John Koleszar committed
363 364 365

  // Segment reference frame features not available or allows for
  // multiple reference frame options
366
  if (!seg_ref_active || seg_ref_count > 1) {
John Koleszar's avatar
John Koleszar committed
367 368 369 370
    // Values used in prediction model coding
    MV_REFERENCE_FRAME pred_ref;

    // Get the context probability the prediction flag
Dmitry Kovalev's avatar
Dmitry Kovalev committed
371
    vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
John Koleszar's avatar
John Koleszar committed
372 373

    // Read the prediction status flag
374
    unsigned char prediction_flag = vp9_read(r, pred_prob);
John Koleszar's avatar
John Koleszar committed
375 376

    // Store the prediction flag.
Paul Wilkins's avatar
Paul Wilkins committed
377
    vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
John Koleszar's avatar
John Koleszar committed
378 379

    // Get the predicted reference frame.
Paul Wilkins's avatar
Paul Wilkins committed
380
    pred_ref = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
381 382 383 384

    // If correctly predicted then use the predicted value
    if (prediction_flag) {
      ref_frame = pred_ref;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
385 386
    } else {
      // decode the explicitly coded value
387
      vp9_prob mod_refprobs[PREDICTION_PROBS];
388 389
      vpx_memcpy(mod_refprobs, cm->mod_refprobs[pred_ref],
                 sizeof(mod_refprobs));
John Koleszar's avatar
John Koleszar committed
390 391 392 393

      // If segment coding enabled blank out options that cant occur by
      // setting the branch probability to 0.
      if (seg_ref_active) {
394 395 396
        mod_refprobs[INTRA_FRAME] *= intra;
        mod_refprobs[LAST_FRAME] *= last;
        mod_refprobs[GOLDEN_FRAME] *= golden * altref;
John Koleszar's avatar
John Koleszar committed
397 398 399 400 401 402 403
      }

      // Default to INTRA_FRAME (value 0)
      ref_frame = INTRA_FRAME;

      // Do we need to decode the Intra/Inter branch
      if (mod_refprobs[0])
404
        ref_frame = vp9_read(r, mod_refprobs[0]);
John Koleszar's avatar
John Koleszar committed
405 406 407 408 409 410
      else
        ref_frame++;

      if (ref_frame) {
        // Do we need to decode the Last/Gf_Arf branch
        if (mod_refprobs[1])
411
          ref_frame += vp9_read(r, mod_refprobs[1]);
412
        else
John Koleszar's avatar
John Koleszar committed
413 414 415 416
          ref_frame++;

        if (ref_frame > 1) {
          // Do we need to decode the GF/Arf branch
417
          if (mod_refprobs[2]) {
418
            ref_frame += vp9_read(r, mod_refprobs[2]);
419
          } else {
420 421 422 423 424 425
            if (seg_ref_active)
              ref_frame = pred_ref == GOLDEN_FRAME || !golden ? ALTREF_FRAME
                                                              : GOLDEN_FRAME;
            else
              ref_frame = pred_ref == GOLDEN_FRAME ? ALTREF_FRAME
                                                   : GOLDEN_FRAME;
John Koleszar's avatar
John Koleszar committed
426
          }
427
        }
John Koleszar's avatar
John Koleszar committed
428
      }
429
    }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
430 431
  } else {
    // Segment reference frame features are enabled
John Koleszar's avatar
John Koleszar committed
432 433 434
    // The reference frame for the mb is considered as correclty predicted
    // if it is signaled at the segment level for the purposes of the
    // common prediction model
Paul Wilkins's avatar
Paul Wilkins committed
435 436
    vp9_set_pred_flag(xd, PRED_REF, 1);
    ref_frame = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
437 438
  }

439
  return ref_frame;
440
}
John Koleszar's avatar
John Koleszar committed
441

442 443
static MB_PREDICTION_MODE read_sb_mv_ref(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE) treed_read(r, vp9_sb_mv_ref_tree, p);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
444
}
John Koleszar's avatar
John Koleszar committed
445

446 447
static MB_PREDICTION_MODE read_mv_ref(vp9_reader *r, const vp9_prob *p) {
  return (MB_PREDICTION_MODE) treed_read(r, vp9_mv_ref_tree, p);
John Koleszar's avatar
John Koleszar committed
448 449
}

450
static B_PREDICTION_MODE read_sub_mv_ref(vp9_reader *r, const vp9_prob *p) {
451
  return (B_PREDICTION_MODE) treed_read(r, vp9_sub_mv_ref_tree, p);
John Koleszar's avatar
John Koleszar committed
452
}
Scott LaVarnway's avatar
Scott LaVarnway committed
453 454

#ifdef VPX_MODE_COUNT
455
unsigned int vp9_mv_cont_count[5][4] = {
John Koleszar's avatar
John Koleszar committed
456 457 458 459 460
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 }
John Koleszar's avatar
John Koleszar committed
461
};
Scott LaVarnway's avatar
Scott LaVarnway committed
462
#endif
John Koleszar's avatar
John Koleszar committed
463

Dmitry Kovalev's avatar
Dmitry Kovalev committed
464
static const unsigned char mbsplit_fill_count[4] = { 8, 8, 4, 1 };
465
static const unsigned char mbsplit_fill_offset[4][16] = {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
466 467 468 469
  { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15 },
  { 0,  1,  4,  5,  8,  9, 12, 13,  2,  3,   6,  7, 10, 11, 14, 15 },
  { 0,  1,  4,  5,  2,  3,  6,  7,  8,  9,  12, 13, 10, 11, 14, 15 },
  { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15 }
Scott LaVarnway's avatar
Scott LaVarnway committed
470
};
John Koleszar's avatar
John Koleszar committed
471

472
static void read_switchable_interp_probs(VP9D_COMP* const pbi, vp9_reader *r) {
473
  VP9_COMMON *const cm = &pbi->common;
474
  int i, j;
475 476 477
  for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j)
    for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i)
      cm->fc.switchable_interp_prob[j][i] = vp9_read_prob(r);
478
}
John Koleszar's avatar
John Koleszar committed
479

480 481 482 483 484 485 486 487
static INLINE COMPPREDMODE_TYPE read_comp_pred_mode(vp9_reader *r) {
  COMPPREDMODE_TYPE mode = vp9_read_bit(r);
  if (mode)
     mode += vp9_read_bit(r);
  return mode;
}

static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *r) {
488
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
489

490 491
  if (cm->frame_type == KEY_FRAME) {
    if (!cm->kf_ymode_probs_update)
492
      cm->kf_ymode_probs_index = vp9_read_literal(r, 3);
493
  } else {
494 495 496
    nmv_context *const nmvc = &pbi->common.fc.nmvc;
    MACROBLOCKD *const xd = &pbi->mb;
    int i, j;
497

498
    if (cm->mcomp_filter_type == SWITCHABLE)
499
      read_switchable_interp_probs(pbi, r);
500 501
#if CONFIG_COMP_INTERINTRA_PRED
    if (cm->use_interintra) {
502 503
      if (vp9_read(r, VP9_UPD_INTERINTRA_PROB))
        cm->fc.interintra_prob = vp9_read_prob(r);
504 505
    }
#endif
506 507 508 509
    // Baseline probabilities for decoding reference frame
    cm->prob_intra_coded = vp9_read_prob(r);
    cm->prob_last_coded  = vp9_read_prob(r);
    cm->prob_gf_coded    = vp9_read_prob(r);
John Koleszar's avatar
John Koleszar committed
510 511 512

    // Computes a modified set of probabilities for use when reference
    // frame prediction fails.
Paul Wilkins's avatar
Paul Wilkins committed
513
    vp9_compute_mod_refprobs(cm);
John Koleszar's avatar
John Koleszar committed
514

515 516
    cm->comp_pred_mode = read_comp_pred_mode(r);
    if (cm->comp_pred_mode == HYBRID_PREDICTION)
John Koleszar's avatar
John Koleszar committed
517
      for (i = 0; i < COMP_PRED_CONTEXTS; i++)
518
        cm->prob_comppred[i] = vp9_read_prob(r);
John Koleszar's avatar
John Koleszar committed
519

520 521
    // VP9_YMODES
    if (vp9_read_bit(r))
522
      for (i = 0; i < VP9_YMODES - 1; ++i)
523
        cm->fc.ymode_prob[i] = vp9_read_prob(r);
524

525 526
    // VP9_I32X32_MODES
    if (vp9_read_bit(r))
527
      for (i = 0; i < VP9_I32X32_MODES - 1; ++i)
528
        cm->fc.sb_ymode_prob[i] = vp9_read_prob(r);
529

530 531 532 533 534 535 536 537
    for (j = 0; j < PARTITION_PLANES; j++) {
      if (vp9_read_bit(r)) {
        for (i = 0; i < PARTITION_TYPES - 1; i++)
          cm->fc.partition_prob[j][i] = vp9_read_prob(r);
      }
    }

    read_nmvprobs(r, nmvc, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
538
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
539
}
John Koleszar's avatar
John Koleszar committed
540

541 542 543
// This function either reads the segment id for the current macroblock from
// the bitstream or if the value is temporally predicted asserts the predicted
// value
544
static void read_mb_segment_id(VP9D_COMP *pbi,
John Koleszar's avatar
John Koleszar committed
545
                               int mb_row, int mb_col,
546
                               vp9_reader *r) {
547
  VP9_COMMON *const cm = &pbi->common;
548
  MACROBLOCKD *const xd = &pbi->mb;
549 550 551
  MODE_INFO *const mi = xd->mode_info_context;
  MB_MODE_INFO *const mbmi = &mi->mbmi;
  const int mb_index = mb_row * cm->mb_cols + mb_col;
John Koleszar's avatar
John Koleszar committed
552 553 554 555 556 557 558

  if (xd->segmentation_enabled) {
    if (xd->update_mb_segmentation_map) {
      // Is temporal coding of the segment id for this mb enabled.
      if (cm->temporal_update) {
        // Get the context based probability for reading the
        // prediction status flag
Dmitry Kovalev's avatar
Dmitry Kovalev committed
559
        vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_SEG_ID);
560

John Koleszar's avatar
John Koleszar committed
561
        // Read the prediction status flag
562
        unsigned char seg_pred_flag = vp9_read(r, pred_prob);
563

John Koleszar's avatar
John Koleszar committed
564
        // Store the prediction flag.
Paul Wilkins's avatar
Paul Wilkins committed
565
        vp9_set_pred_flag(xd, PRED_SEG_ID, seg_pred_flag);
John Koleszar's avatar
John Koleszar committed
566 567

        // If the value is flagged as correctly predicted
568 569 570 571
        // then use the predicted value, otherwise decode it explicitly
        mbmi->segment_id = seg_pred_flag ?
                               vp9_get_pred_mb_segid(cm, xd, mb_index) :
                               read_mb_segid_except(r, cm, xd, mb_row, mb_col);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
572 573
      } else {
        // Normal unpredicted coding mode
574
        mbmi->segment_id = read_mb_segid(r, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
575
      }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
576

577
      set_segment_id(cm, mbmi, mb_row, mb_col, mbmi->segment_id);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
578
    } else {
579
      mbmi->segment_id = get_segment_id(cm, mbmi, mb_row, mb_col);
580
    }
John Koleszar's avatar
John Koleszar committed
581 582 583 584 585
  } else {
    // The encoder explicitly sets the segment_id to 0
    // when segmentation is disabled
    mbmi->segment_id = 0;
  }
586
}
587

Dmitry Kovalev's avatar
Dmitry Kovalev committed
588 589 590 591 592 593 594 595 596 597 598

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

599 600 601
static INLINE void process_mv(vp9_reader *r, MV *mv, const MV *ref,
                              const nmv_context *nmvc,
                              nmv_context_counts *mvctx,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
602
                              int usehp) {
603 604
  read_nmv(r, mv, ref, nmvc);
  read_nmv_fp(r, mv, ref, nmvc, usehp);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
605 606 607 608 609
  vp9_increment_nmv(mv, ref, mvctx, usehp);
  mv->row += ref->row;
  mv->col += ref->col;
}

610
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
611 612
    VP9D_COMP *pbi, vp9_reader *r) {
  const int index = treed_read(r, vp9_switchable_interp_tree,
613 614 615 616 617
                               vp9_get_pred_probs(&pbi->common, &pbi->mb,
                                                  PRED_SWITCHABLE_INTERP));
  return vp9_switchable_interp[index];
}

618
static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
619
                             MODE_INFO *prev_mi,
John Koleszar's avatar
John Koleszar committed
620
                             int mb_row, int mb_col,
621
                             vp9_reader *r) {
622
  VP9_COMMON *const cm = &pbi->common;
623 624
  nmv_context *const nmvc = &cm->fc.nmvc;
  const int mis = cm->mode_info_stride;
625
  MACROBLOCKD *const xd = &pbi->mb;
John Koleszar's avatar
John Koleszar committed
626

627 628
  int_mv *const mv0 = &mbmi->mv[0];
  int_mv *const mv1 = &mbmi->mv[1];
629 630
  const int bw = 1 << mb_width_log2(mi->mbmi.sb_type);
  const int bh = 1 << mb_height_log2(mi->mbmi.sb_type);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
631

632 633
  const int use_prev_in_find_mv_refs = cm->width == cm->last_width &&
                                       cm->height == cm->last_height &&
634
                                       !cm->error_resilient_mode;
John Koleszar's avatar
John Koleszar committed
635

636
  int mb_to_left_edge, mb_to_right_edge, mb_to_top_edge, mb_to_bottom_edge;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
637

John Koleszar's avatar
John Koleszar committed
638 639
  mbmi->need_to_clamp_mvs = 0;
  mbmi->need_to_clamp_secondmv = 0;
640
  mbmi->second_ref_frame = NONE;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
641

642 643 644 645 646
  // Make sure the MACROBLOCKD mode info pointer is pointed at the
  // correct entry for the current macroblock.
  xd->mode_info_context = mi;
  xd->prev_mode_info_context = prev_mi;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
647 648 649
  // Distance of Mb to the various image edges.
  // These specified to 8th pel as they are always compared to MV values
  // that are in 1/8th pel units
650 651
  set_mb_row(cm, xd, mb_row, bh);
  set_mb_col(cm, xd, mb_col, bw);
652

653 654
  mb_to_top_edge = xd->mb_to_top_edge - LEFT_TOP_MARGIN;
  mb_to_bottom_edge = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
655 656
  mb_to_left_edge = xd->mb_to_left_edge - LEFT_TOP_MARGIN;
  mb_to_right_edge = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN;
John Koleszar's avatar
John Koleszar committed
657 658

  // Read the macroblock segment id.
659
  read_mb_segment_id(pbi, mb_row, mb_col, r);
John Koleszar's avatar
John Koleszar committed
660

661 662 663
  mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id,
                                              SEG_LVL_SKIP);
  if (!mbmi->mb_skip_coeff)
664
    mbmi->mb_skip_coeff = vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
John Koleszar's avatar
John Koleszar committed
665 666

  // Read the reference frame
667
  mbmi->ref_frame = read_ref_frame(pbi, r, mbmi->segment_id);
668

John Koleszar's avatar
John Koleszar committed
669 670 671 672
  // If reference frame is an Inter frame
  if (mbmi->ref_frame) {
    int_mv nearest, nearby, best_mv;
    int_mv nearest_second, nearby_second, best_mv_second;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
673
    vp9_prob mv_ref_p[VP9_MVREFS - 1];
John Koleszar's avatar
John Koleszar committed
674

675 676 677 678
    const MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame;
    struct scale_factors *sf0 = &xd->scale_factor[0];
    struct scale_factors *sf_uv0 = &xd->scale_factor_uv[0];
    *sf0 = cm->active_ref_scale[mbmi->ref_frame - 1];
679 680

    {
681
      // Select the appropriate reference frame for this MB
Dmitry Kovalev's avatar
Dmitry Kovalev committed
682
      const int ref_fb_idx = cm->active_ref_idx[ref_frame - 1];
683

684
      setup_pred_block(&xd->pre, &cm->yv12_fb[ref_fb_idx],
685
                       mb_row, mb_col, sf0, sf_uv0);
686

687 688 689 690 691
#ifdef DEC_DEBUG
      if (dec_debug)
        printf("%d %d\n", xd->mode_info_context->mbmi.mv[0].as_mv.row,
               xd->mode_info_context->mbmi.mv[0].as_mv.col);
#endif
692
      vp9_find_mv_refs(cm, xd, mi, use_prev_in_find_mv_refs ? prev_mi : NULL,
Paul Wilkins's avatar
Paul Wilkins committed
693 694
                       ref_frame, mbmi->ref_mvs[ref_frame],
                       cm->ref_frame_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
695

696
      vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[ref_frame]);
697

698
      // If the segment level skip mode enabled
Paul Wilkins's avatar
Paul Wilkins committed
699 700
      if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) {
        mbmi->mode = ZEROMV;
701
      } else {
702 703
        mbmi->mode = mbmi->sb_type ? read_sb_mv_ref(r, mv_ref_p)
                                   : read_mv_ref(r, mv_ref_p);
704
        vp9_accum_mv_refs(cm, mbmi->mode, mbmi->mb_mode_context[ref_frame]);
705 706 707 708 709 710 711
      }

      if (mbmi->mode != ZEROMV) {
        vp9_find_best_ref_mvs(xd,
                              mbmi->ref_mvs[ref_frame],
                              &nearest, &nearby);

712
        best_mv.as_int = mbmi->ref_mvs[ref_frame][0].as_int;
713
      }
714

715 716 717 718 719 720
#ifdef DEC_DEBUG
      if (dec_debug)
        printf("[D %d %d] %d %d %d %d\n", ref_frame,
               mbmi->mb_mode_context[ref_frame],
               mv_ref_p[0], mv_ref_p[1], mv_ref_p[2], mv_ref_p[3]);
#endif
Paul Wilkins's avatar
Paul Wilkins committed
721
    }
John Koleszar's avatar
John Koleszar committed
722

Dmitry Kovalev's avatar
Dmitry Kovalev committed
723
    if (mbmi->mode >= NEARESTMV && mbmi->mode <= SPLITMV) {
724
      mbmi->interp_filter = cm->mcomp_filter_type == SWITCHABLE
725
                                ? read_switchable_filter_type(pbi, r)
726
                                : cm->mcomp_filter_type;
727
    }
728

John Koleszar's avatar
John Koleszar committed
729 730
    if (cm->comp_pred_mode == COMP_PREDICTION_ONLY ||
        (cm->comp_pred_mode == HYBRID_PREDICTION &&
731
         vp9_read(r, vp9_get_pred_prob(cm, xd, PRED_COMP)))) {
John Koleszar's avatar
John Koleszar committed
732 733 734 735 736 737 738 739 740 741
      /* Since we have 3 reference frames, we can only have 3 unique
       * combinations of combinations of 2 different reference frames
       * (A-G, G-L or A-L). In the bitstream, we use this to simply
       * derive the second reference frame from the first reference
       * frame, by saying it's the next one in the enumerator, and
       * if that's > n_refs, then the second reference frame is the
       * first one in the enumerator. */
      mbmi->second_ref_frame = mbmi->ref_frame + 1;
      if (mbmi->second_ref_frame == 4)
        mbmi->second_ref_frame = 1;
742
      if (mbmi->second_ref_frame > 0) {
743 744 745 746 747
        const MV_REFERENCE_FRAME second_ref_frame = mbmi->second_ref_frame;
        struct scale_factors *sf1 = &xd->scale_factor[1];
        struct scale_factors *sf_uv1 = &xd->scale_factor_uv[1];
        const int second_ref_fb_idx = cm->active_ref_idx[second_ref_frame - 1];
        *sf1 = cm->active_ref_scale[second_ref_frame - 1];
748

749
        setup_pred_block(&xd->second_pre, &cm->yv12_fb[second_ref_fb_idx],
750
                         mb_row, mb_col, sf1, sf_uv1);
751

752 753 754
        vp9_find_mv_refs(cm, xd, mi,
                         use_prev_in_find_mv_refs ? prev_mi : NULL,
                         second_ref_frame, mbmi->ref_mvs[second_ref_frame],
Paul Wilkins's avatar
Paul Wilkins committed
755
                         cm->ref_frame_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
756

757 758
        if (mbmi->mode != ZEROMV) {
          vp9_find_best_ref_mvs(xd,
759
                                mbmi->ref_mvs[second_ref_frame],
760 761
                                &nearest_second,
                                &nearby_second);
762
          best_mv_second.as_int = mbmi->ref_mvs[second_ref_frame][0].as_int;