vp9_decodemv.c 50.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 "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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
38
static B_PREDICTION_MODE read_bmode(vp9_reader *bc, const vp9_prob *p) {
39 40 41 42 43 44 45 46 47
  B_PREDICTION_MODE m = treed_read(bc, vp9_bmode_tree, p);
#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;
}

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
56 57
static MB_PREDICTION_MODE read_sb_ymode(vp9_reader *bc, const vp9_prob *p) {
  return (MB_PREDICTION_MODE)treed_read(bc, vp9_sb_ymode_tree, p);
58 59
}

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

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

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

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

76
// This function reads the current macro block's segnent id from the bitstream
Paul Wilkins's avatar
Paul Wilkins committed
77
// It should only be called if a segment map update is indicated.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
78
static void read_mb_segid(vp9_reader *r, MB_MODE_INFO *mi, MACROBLOCKD *xd) {
Paul Wilkins's avatar
Paul Wilkins committed
79
  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
80 81 82
    const vp9_prob *const p = xd->mb_segment_tree_probs;
    mi->segment_id = vp9_read(r, p[0]) ? 2 + vp9_read(r, p[2])
                                       : vp9_read(r, p[1]);
John Koleszar's avatar
John Koleszar committed
83
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
84
}
85

86 87 88 89 90
// 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.
static void read_mb_segid_except(VP9_COMMON *cm,
                                 vp9_reader *r, MB_MODE_INFO *mi,
                                 MACROBLOCKD *xd, int mb_row, int mb_col) {
91 92 93 94
  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];
95 96

  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
97 98 99
    mi->segment_id = 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));
100 101 102
  }
}

103
#if CONFIG_NEW_MVREF
Dmitry Kovalev's avatar
Dmitry Kovalev committed
104
int vp9_read_mv_ref_id(vp9_reader *r, vp9_prob *ref_id_probs) {
105 106
  int ref_index = 0;

107
  if (vp9_read(r, ref_id_probs[0])) {
108
    ref_index++;
109
    if (vp9_read(r, ref_id_probs[1])) {
110
      ref_index++;
111
      if (vp9_read(r, ref_id_probs[2]))
112 113 114 115 116 117 118
        ref_index++;
    }
  }
  return ref_index;
}
#endif

119
extern const int vp9_i8x8_block[4];
120
static void kfread_modes(VP9D_COMP *pbi,
John Koleszar's avatar
John Koleszar committed
121 122 123 124
                         MODE_INFO *m,
                         int mb_row,
                         int mb_col,
                         BOOL_DECODER* const bc) {
125
  VP9_COMMON *const cm = &pbi->common;
126
  MACROBLOCKD *const xd  = &pbi->mb;
John Koleszar's avatar
John Koleszar committed
127 128 129 130
  const int mis = pbi->common.mode_info_stride;
  int map_index = mb_row * pbi->common.mb_cols + mb_col;
  MB_PREDICTION_MODE y_mode;

131 132
  m->mbmi.ref_frame = INTRA_FRAME;

John Koleszar's avatar
John Koleszar committed
133 134 135 136
  // Read the Macroblock segmentation map if it is being updated explicitly
  // this frame (reset to 0 by default).
  m->mbmi.segment_id = 0;
  if (pbi->mb.update_mb_segmentation_map) {
137
    read_mb_segid(bc, &m->mbmi, &pbi->mb);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
138 139 140 141 142 143 144 145 146 147 148 149
    if (m->mbmi.sb_type) {
      const int nmbs = 1 << m->mbmi.sb_type;
      const int ymbs = MIN(cm->mb_rows - mb_row, nmbs);
      const int xmbs = MIN(cm->mb_cols - mb_col, nmbs);
      int x, y;

      for (y = 0; y < ymbs; y++) {
        for (x = 0; x < xmbs; x++) {
          cm->last_frame_seg_map[map_index + x + y * cm->mb_cols] =
              m->mbmi.segment_id;
        }
      }
150
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
151 152
      cm->last_frame_seg_map[map_index] = m->mbmi.segment_id;
    }
John Koleszar's avatar
John Koleszar committed
153 154 155 156
  }

  m->mbmi.mb_skip_coeff = 0;
  if (pbi->common.mb_no_coeff_skip &&
Dmitry Kovalev's avatar
Dmitry Kovalev committed
157
      (!vp9_segfeature_active(&pbi->mb, m->mbmi.segment_id, SEG_LVL_SKIP))) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
158 159
    m->mbmi.mb_skip_coeff = vp9_read(bc, vp9_get_pred_prob(cm, &pbi->mb,
                                                           PRED_MBSKIP));
John Koleszar's avatar
John Koleszar committed
160
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
161 162
    m->mbmi.mb_skip_coeff = vp9_segfeature_active(&pbi->mb, m->mbmi.segment_id,
                                                  SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
163 164
  }

Dmitry Kovalev's avatar
Dmitry Kovalev committed
165 166 167 168 169
  y_mode = m->mbmi.sb_type ?
      read_kf_sb_ymode(bc,
          pbi->common.sb_kf_ymode_prob[pbi->common.kf_ymode_probs_index]):
      read_kf_mb_ymode(bc,
          pbi->common.kf_ymode_prob[pbi->common.kf_ymode_probs_index]);
170

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

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
180 181
      m->bmi[i].as_mode.first = read_kf_bmode(bc,
                                              pbi->common.kf_bmode_prob[a][l]);
John Koleszar's avatar
John Koleszar committed
182 183
    } while (++i < 16);
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
184

John Koleszar's avatar
John Koleszar committed
185 186 187
  if ((m->mbmi.mode = y_mode) == I8X8_PRED) {
    int i;
    for (i = 0; i < 4; i++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
188 189 190
      const int ib = vp9_i8x8_block[i];
      const int mode8x8 = read_i8x8_mode(bc, pbi->common.fc.i8x8_mode_prob);

John Koleszar's avatar
John Koleszar committed
191 192 193 194 195
      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
196 197 198 199
  } else {
    m->mbmi.uv_mode = read_uv_mode(bc,
                                   pbi->common.kf_uv_mode_prob[m->mbmi.mode]);
  }
200

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

222
static int read_nmv_component(vp9_reader *r,
223 224
                              int rv,
                              const nmv_component *mvcomp) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
225 226 227 228 229
  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) {
230
    d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
231
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
232 233 234
    int i;
    int n = mv_class + CLASS0_BITS - 1;  // number of bits

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

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

244
static int read_nmv_component_fp(vp9_reader *r,
245 246 247 248
                                 int v,
                                 int rv,
                                 const nmv_component *mvcomp,
                                 int usehp) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
249 250 251 252 253 254 255
  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);
256

Dmitry Kovalev's avatar
Dmitry Kovalev committed
257
  offset += f << 1;
258 259

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

269
static void read_nmv(vp9_reader *r, MV *mv, const MV *ref,
270
                     const nmv_context *mvctx) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
271
  const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, mvctx->joints);
272 273 274 275
  mv->row = mv-> col = 0;
  if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) {
    mv->row = read_nmv_component(r, ref->row, &mvctx->comps[0]);
  }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276

277 278 279 280 281
  if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) {
    mv->col = read_nmv_component(r, ref->col, &mvctx->comps[1]);
  }
}

282
static void read_nmv_fp(vp9_reader *r, MV *mv, const MV *ref,
283
                        const nmv_context *mvctx, int usehp) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
284
  const MV_JOINT_TYPE j = vp9_get_mv_joint(*mv);
285
  usehp = usehp && vp9_use_nmv_hp(ref);
286 287 288 289 290 291 292 293
  if (j == MV_JOINT_HZVNZ || j == MV_JOINT_HNZVNZ) {
    mv->row = read_nmv_component_fp(r, mv->row, ref->row, &mvctx->comps[0],
                                    usehp);
  }
  if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) {
    mv->col = read_nmv_component_fp(r, mv->col, ref->col, &mvctx->comps[1],
                                    usehp);
  }
294 295 296 297
  /*
  printf("MV: %d %d REF: %d %d\n", mv->row + ref->row, mv->col + ref->col,
	 ref->row, ref->col);
	 */
298 299
}

300 301 302
static void update_nmv(vp9_reader *bc, vp9_prob *const p,
                       const vp9_prob upd_p) {
  if (vp9_read(bc, upd_p)) {
303
#ifdef LOW_PRECISION_MV_UPDATE
304
    *p = (vp9_read_literal(bc, 7) << 1) | 1;
305
#else
306
    *p = (vp9_read_literal(bc, 8));
307 308 309 310
#endif
  }
}

311
static void read_nmvprobs(vp9_reader *bc, nmv_context *mvctx,
312 313
                          int usehp) {
  int i, j, k;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
314

315
#ifdef MV_GROUP_UPDATE
Dmitry Kovalev's avatar
Dmitry Kovalev committed
316 317
  if (!vp9_read_bit(bc))
    return;
318
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
319 320 321
  for (j = 0; j < MV_JOINTS - 1; ++j)
    update_nmv(bc, &mvctx->joints[j], VP9_NMV_UPDATE_PROB);

322
  for (i = 0; i < 2; ++i) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
323 324 325 326 327 328 329 330 331
    update_nmv(bc, &mvctx->comps[i].sign, VP9_NMV_UPDATE_PROB);
    for (j = 0; j < MV_CLASSES - 1; ++j)
      update_nmv(bc, &mvctx->comps[i].classes[j], VP9_NMV_UPDATE_PROB);

    for (j = 0; j < CLASS0_SIZE - 1; ++j)
      update_nmv(bc, &mvctx->comps[i].class0[j], VP9_NMV_UPDATE_PROB);

    for (j = 0; j < MV_OFFSET_BITS; ++j)
      update_nmv(bc, &mvctx->comps[i].bits[j], VP9_NMV_UPDATE_PROB);
332 333 334
  }

  for (i = 0; i < 2; ++i) {
335
    for (j = 0; j < CLASS0_SIZE; ++j)
336
      for (k = 0; k < 3; ++k)
Dmitry Kovalev's avatar
Dmitry Kovalev committed
337 338 339 340
        update_nmv(bc, &mvctx->comps[i].class0_fp[j][k], VP9_NMV_UPDATE_PROB);

    for (j = 0; j < 3; ++j)
      update_nmv(bc, &mvctx->comps[i].fp[j], VP9_NMV_UPDATE_PROB);
341 342 343 344
  }

  if (usehp) {
    for (i = 0; i < 2; ++i) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
345 346
      update_nmv(bc, &mvctx->comps[i].class0_hp, VP9_NMV_UPDATE_PROB);
      update_nmv(bc, &mvctx->comps[i].hp, VP9_NMV_UPDATE_PROB);
347 348 349 350
    }
  }
}

351
// Read the referncence frame
352
static MV_REFERENCE_FRAME read_ref_frame(VP9D_COMP *pbi,
353
                                         vp9_reader *const bc,
John Koleszar's avatar
John Koleszar committed
354 355
                                         unsigned char segment_id) {
  MV_REFERENCE_FRAME ref_frame;
356
  VP9_COMMON *const cm = &pbi->common;
John Koleszar's avatar
John Koleszar committed
357 358
  MACROBLOCKD *const xd = &pbi->mb;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
359 360
  int seg_ref_count = 0;
  int seg_ref_active = vp9_segfeature_active(xd, segment_id, SEG_LVL_REF_FRAME);
John Koleszar's avatar
John Koleszar committed
361 362 363 364

  // If segment coding enabled does the segment allow for more than one
  // possible reference frame
  if (seg_ref_active) {
365 366 367 368
    seg_ref_count = vp9_check_segref(xd, segment_id, INTRA_FRAME) +
                    vp9_check_segref(xd, segment_id, LAST_FRAME) +
                    vp9_check_segref(xd, segment_id, GOLDEN_FRAME) +
                    vp9_check_segref(xd, segment_id, ALTREF_FRAME);
John Koleszar's avatar
John Koleszar committed
369 370 371 372
  }

  // Segment reference frame features not available or allows for
  // multiple reference frame options
373
  if (!seg_ref_active || seg_ref_count > 1) {
John Koleszar's avatar
John Koleszar committed
374 375 376 377
    // 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
378
    vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);
John Koleszar's avatar
John Koleszar committed
379 380

    // Read the prediction status flag
Dmitry Kovalev's avatar
Dmitry Kovalev committed
381
    unsigned char prediction_flag = vp9_read(bc, pred_prob);
John Koleszar's avatar
John Koleszar committed
382 383

    // Store the prediction flag.
Paul Wilkins's avatar
Paul Wilkins committed
384
    vp9_set_pred_flag(xd, PRED_REF, prediction_flag);
John Koleszar's avatar
John Koleszar committed
385 386

    // Get the predicted reference frame.
Paul Wilkins's avatar
Paul Wilkins committed
387
    pred_ref = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
388 389 390 391

    // If correctly predicted then use the predicted value
    if (prediction_flag) {
      ref_frame = pred_ref;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
392 393
    } else {
      // decode the explicitly coded value
394
      vp9_prob mod_refprobs[PREDICTION_PROBS];
John Koleszar's avatar
John Koleszar committed
395 396 397 398 399 400 401
      vpx_memcpy(mod_refprobs,
                 cm->mod_refprobs[pred_ref], sizeof(mod_refprobs));

      // If segment coding enabled blank out options that cant occur by
      // setting the branch probability to 0.
      if (seg_ref_active) {
        mod_refprobs[INTRA_FRAME] *=
402
          vp9_check_segref(xd, segment_id, INTRA_FRAME);
John Koleszar's avatar
John Koleszar committed
403
        mod_refprobs[LAST_FRAME] *=
404
          vp9_check_segref(xd, segment_id, LAST_FRAME);
John Koleszar's avatar
John Koleszar committed
405
        mod_refprobs[GOLDEN_FRAME] *=
406 407
          vp9_check_segref(xd, segment_id, GOLDEN_FRAME) *
          vp9_check_segref(xd, segment_id, ALTREF_FRAME);
John Koleszar's avatar
John Koleszar committed
408 409 410 411 412 413 414
      }

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

      // Do we need to decode the Intra/Inter branch
      if (mod_refprobs[0])
415
        ref_frame = vp9_read(bc, mod_refprobs[0]);
John Koleszar's avatar
John Koleszar committed
416 417 418 419 420 421
      else
        ref_frame++;

      if (ref_frame) {
        // Do we need to decode the Last/Gf_Arf branch
        if (mod_refprobs[1])
422
          ref_frame += vp9_read(bc, mod_refprobs[1]);
423
        else
John Koleszar's avatar
John Koleszar committed
424 425 426 427
          ref_frame++;

        if (ref_frame > 1) {
          // Do we need to decode the GF/Arf branch
428
          if (mod_refprobs[2]) {
429
            ref_frame += vp9_read(bc, mod_refprobs[2]);
430
          } else {
John Koleszar's avatar
John Koleszar committed
431
            if (seg_ref_active) {
432 433 434 435 436 437 438 439 440
              ref_frame = pred_ref == GOLDEN_FRAME ||
                          !vp9_check_segref(xd, segment_id, GOLDEN_FRAME)
                              ? ALTREF_FRAME
                              : GOLDEN_FRAME;
            } else {
              ref_frame = pred_ref == GOLDEN_FRAME
                              ? ALTREF_FRAME
                              : GOLDEN_FRAME;
            }
John Koleszar's avatar
John Koleszar committed
441
          }
442
        }
John Koleszar's avatar
John Koleszar committed
443
      }
444
    }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
445 446
  } else {
    // Segment reference frame features are enabled
John Koleszar's avatar
John Koleszar committed
447 448 449
    // 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
450 451
    vp9_set_pred_flag(xd, PRED_REF, 1);
    ref_frame = vp9_get_pred_ref(cm, xd);
John Koleszar's avatar
John Koleszar committed
452 453
  }

454
  return ref_frame;
455
}
John Koleszar's avatar
John Koleszar committed
456

457 458
static MB_PREDICTION_MODE read_sb_mv_ref(vp9_reader *bc, const vp9_prob *p) {
  return (MB_PREDICTION_MODE) treed_read(bc, vp9_sb_mv_ref_tree, p);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
459
}
John Koleszar's avatar
John Koleszar committed
460

461 462
static MB_PREDICTION_MODE read_mv_ref(vp9_reader *bc, const vp9_prob *p) {
  return (MB_PREDICTION_MODE) treed_read(bc, vp9_mv_ref_tree, p);
John Koleszar's avatar
John Koleszar committed
463 464
}

465 466
static B_PREDICTION_MODE sub_mv_ref(vp9_reader *bc, const vp9_prob *p) {
  return (B_PREDICTION_MODE) treed_read(bc, vp9_sub_mv_ref_tree, p);
John Koleszar's avatar
John Koleszar committed
467
}
Scott LaVarnway's avatar
Scott LaVarnway committed
468 469

#ifdef VPX_MODE_COUNT
470
unsigned int vp9_mv_cont_count[5][4] = {
John Koleszar's avatar
John Koleszar committed
471 472 473 474 475
  { 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
476
};
Scott LaVarnway's avatar
Scott LaVarnway committed
477
#endif
John Koleszar's avatar
John Koleszar committed
478

Dmitry Kovalev's avatar
Dmitry Kovalev committed
479
static const unsigned char mbsplit_fill_count[4] = { 8, 8, 4, 1 };
480
static const unsigned char mbsplit_fill_offset[4][16] = {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
481 482 483 484
  { 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
485
};
John Koleszar's avatar
John Koleszar committed
486

487
static void read_switchable_interp_probs(VP9D_COMP* const pbi,
John Koleszar's avatar
John Koleszar committed
488
                                         BOOL_DECODER* const bc) {
489
  VP9_COMMON *const cm = &pbi->common;
490
  int i, j;
491
  for (j = 0; j < VP9_SWITCHABLE_FILTERS + 1; ++j) {
492
    for (i = 0; i < VP9_SWITCHABLE_FILTERS - 1; ++i) {
493
      cm->fc.switchable_interp_prob[j][i] = vp9_read_prob(bc);
494 495 496 497 498
    }
  }
  //printf("DECODER: %d %d\n", cm->fc.switchable_interp_prob[0],
  //cm->fc.switchable_interp_prob[1]);
}
John Koleszar's avatar
John Koleszar committed
499

500
static void mb_mode_mv_init(VP9D_COMP *pbi, vp9_reader *bc) {
501
  VP9_COMMON *const cm = &pbi->common;
502
  nmv_context *const nmvc = &pbi->common.fc.nmvc;
503
  MACROBLOCKD *const xd = &pbi->mb;
John Koleszar's avatar
John Koleszar committed
504

505 506
  if (cm->frame_type == KEY_FRAME) {
    if (!cm->kf_ymode_probs_update)
507
      cm->kf_ymode_probs_index = vp9_read_literal(bc, 3);
508
  } else {
509
    if (cm->mcomp_filter_type == SWITCHABLE)
John Koleszar's avatar
John Koleszar committed
510
      read_switchable_interp_probs(pbi, bc);
511 512 513
#if CONFIG_COMP_INTERINTRA_PRED
    if (cm->use_interintra) {
      if (vp9_read(bc, VP9_UPD_INTERINTRA_PROB))
514
        cm->fc.interintra_prob = vp9_read_prob(bc);
515 516
    }
#endif
John Koleszar's avatar
John Koleszar committed
517
    // Decode the baseline probabilities for decoding reference frame
518 519 520
    cm->prob_intra_coded = vp9_read_prob(bc);
    cm->prob_last_coded  = vp9_read_prob(bc);
    cm->prob_gf_coded    = vp9_read_prob(bc);
John Koleszar's avatar
John Koleszar committed
521 522 523

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

526
    cm->comp_pred_mode = vp9_read_bit(bc);
John Koleszar's avatar
John Koleszar committed
527
    if (cm->comp_pred_mode)
528 529
      cm->comp_pred_mode += vp9_read_bit(bc);

John Koleszar's avatar
John Koleszar committed
530 531 532
    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
      int i;
      for (i = 0; i < COMP_PRED_CONTEXTS; i++)
533
        cm->prob_comppred[i] = vp9_read_prob(bc);
John Koleszar's avatar
John Koleszar committed
534
    }
John Koleszar's avatar
John Koleszar committed
535

536
    if (vp9_read_bit(bc)) {
537 538
      int i;
      for (i = 0; i < VP9_YMODES - 1; ++i)
539
        cm->fc.ymode_prob[i] = vp9_read_prob(bc);
John Koleszar's avatar
John Koleszar committed
540
    }
541

542
    if (vp9_read_bit(bc)) {
543 544
      int i;
      for (i = 0; i < VP9_I32X32_MODES - 1; ++i)
545
        cm->fc.sb_ymode_prob[i] = vp9_read_prob(bc);
546 547
    }

548
    read_nmvprobs(bc, nmvc, xd->allow_high_precision_mv);
John Koleszar's avatar
John Koleszar committed
549
  }
Scott LaVarnway's avatar
Scott LaVarnway committed
550
}
John Koleszar's avatar
John Koleszar committed
551

552 553 554
// 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
555
static void read_mb_segment_id(VP9D_COMP *pbi,
John Koleszar's avatar
John Koleszar committed
556 557
                               int mb_row, int mb_col,
                               BOOL_DECODER* const bc) {
558
  VP9_COMMON *const cm = &pbi->common;
559
  MACROBLOCKD *const xd = &pbi->mb;
John Koleszar's avatar
John Koleszar committed
560 561
  MODE_INFO *mi = xd->mode_info_context;
  MB_MODE_INFO *mbmi = &mi->mbmi;
562
  int mb_index = mb_row * pbi->common.mb_cols + mb_col;
John Koleszar's avatar
John Koleszar committed
563 564 565 566 567 568 569

  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
570
        vp9_prob pred_prob = vp9_get_pred_prob(cm, xd, PRED_SEG_ID);
571

John Koleszar's avatar
John Koleszar committed
572
        // Read the prediction status flag
Dmitry Kovalev's avatar
Dmitry Kovalev committed
573
        unsigned char seg_pred_flag = vp9_read(bc, pred_prob);
574

John Koleszar's avatar
John Koleszar committed
575
        // Store the prediction flag.
Paul Wilkins's avatar
Paul Wilkins committed
576
        vp9_set_pred_flag(xd, PRED_SEG_ID, seg_pred_flag);
John Koleszar's avatar
John Koleszar committed
577 578 579 580

        // If the value is flagged as correctly predicted
        // then use the predicted value
        if (seg_pred_flag) {
581
          mbmi->segment_id = vp9_get_pred_mb_segid(cm, xd, mb_index);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
582 583
        } else {
          // Decode it explicitly
584
          read_mb_segid_except(cm, bc, mbmi, xd, mb_row, mb_col);
John Koleszar's avatar
John Koleszar committed
585
        }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
586 587
      } else {
        // Normal unpredicted coding mode
588
        read_mb_segid(bc, mbmi, xd);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
589
      }
Dmitry Kovalev's avatar
Dmitry Kovalev committed
590

Ronald S. Bultje's avatar
Ronald S. Bultje committed
591 592 593 594 595 596 597 598
      if (mbmi->sb_type) {
        const int nmbs = 1 << mbmi->sb_type;
        const int ymbs = MIN(cm->mb_rows - mb_row, nmbs);
        const int xmbs = MIN(cm->mb_cols - mb_col, nmbs);
        int x, y;

        for (y = 0; y < ymbs; y++) {
          for (x = 0; x < xmbs; x++) {
599
            cm->last_frame_seg_map[mb_index + x + y * cm->mb_cols] =
Ronald S. Bultje's avatar
Ronald S. Bultje committed
600 601
                mbmi->segment_id;
          }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
602
        }
603
      } else {
604
        cm->last_frame_seg_map[mb_index] = mbmi->segment_id;
John Koleszar's avatar
John Koleszar committed
605
      }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
606
    } else {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
607 608 609 610 611 612 613 614 615 616
      if (mbmi->sb_type) {
        const int nmbs = 1 << mbmi->sb_type;
        const int ymbs = MIN(cm->mb_rows - mb_row, nmbs);
        const int xmbs = MIN(cm->mb_cols - mb_col, nmbs);
        unsigned segment_id = -1;
        int x, y;

        for (y = 0; y < ymbs; y++) {
          for (x = 0; x < xmbs; x++) {
            segment_id = MIN(segment_id,
617
                cm->last_frame_seg_map[mb_index + x + y * cm->mb_cols]);
Ronald S. Bultje's avatar
Ronald S. Bultje committed
618
          }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
619
        }
Ronald S. Bultje's avatar
Ronald S. Bultje committed
620
        mbmi->segment_id = segment_id;
621
      } else {
622
        mbmi->segment_id = cm->last_frame_seg_map[mb_index];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
623
      }
624
    }
John Koleszar's avatar
John Koleszar committed
625 626 627 628 629
  } else {
    // The encoder explicitly sets the segment_id to 0
    // when segmentation is disabled
    mbmi->segment_id = 0;
  }
630
}
631

Dmitry Kovalev's avatar
Dmitry Kovalev committed
632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652

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

static INLINE void process_mv(BOOL_DECODER* bc, MV *mv, MV *ref,
                              nmv_context *nmvc, nmv_context_counts *mvctx,
                              int usehp) {
  read_nmv(bc, mv, ref, nmvc);
  read_nmv_fp(bc, mv, ref, nmvc, usehp);
  vp9_increment_nmv(mv, ref, mvctx, usehp);
  mv->row += ref->row;
  mv->col += ref->col;
}

653 654 655 656 657 658 659 660 661
static INLINE INTERPOLATIONFILTERTYPE read_switchable_filter_type(
    VP9D_COMP *pbi, BOOL_DECODER* bc) {
  const int index = treed_read(bc,
                               vp9_switchable_interp_tree,
                               vp9_get_pred_probs(&pbi->common, &pbi->mb,
                                                  PRED_SWITCHABLE_INTERP));
  return vp9_switchable_interp[index];
}

662
static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
663
                             MODE_INFO *prev_mi,
John Koleszar's avatar
John Koleszar committed
664 665
                             int mb_row, int mb_col,
                             BOOL_DECODER* const bc) {
666
  VP9_COMMON *const cm = &pbi->common;
667
  nmv_context *const nmvc = &pbi->common.fc.nmvc;
John Koleszar's avatar
John Koleszar committed
668
  const int mis = pbi->common.mode_info_stride;
669
  MACROBLOCKD *const xd = &pbi->mb;
John Koleszar's avatar
John Koleszar committed
670

671
  int_mv *const mv = &mbmi->mv[0];
Ronald S. Bultje's avatar
Ronald S. Bultje committed
672
  const int mb_size = 1 << mi->mbmi.sb_type;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
673

674 675
  const int use_prev_in_find_mv_refs = cm->width == cm->last_width &&
                                       cm->height == cm->last_height &&
676
                                       !cm->error_resilient_mode;
John Koleszar's avatar
John Koleszar committed
677

678
  int mb_to_left_edge, mb_to_right_edge, mb_to_top_edge, mb_to_bottom_edge;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
679

John Koleszar's avatar
John Koleszar committed
680 681
  mbmi->need_to_clamp_mvs = 0;
  mbmi->need_to_clamp_secondmv = 0;
682
  mbmi->second_ref_frame = NONE;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
683

684 685 686 687 688
  // 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
689 690 691
  // 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
692 693 694
  set_mb_row(cm, xd, mb_row, mb_size);
  set_mb_col(cm, xd, mb_col, mb_size);

695 696
  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
697 698
  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
699 700

  // Read the macroblock segment id.
John Koleszar's avatar
John Koleszar committed
701
  read_mb_segment_id(pbi, mb_row, mb_col, bc);
John Koleszar's avatar
John Koleszar committed
702 703

  if (pbi->common.mb_no_coeff_skip &&
Paul Wilkins's avatar
Paul Wilkins committed
704
      (!vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP))) {
John Koleszar's avatar
John Koleszar committed
705 706
    // Read the macroblock coeff skip flag if this feature is in use,
    // else default to 0
707
    mbmi->mb_skip_coeff = vp9_read(bc, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
John Koleszar's avatar
John Koleszar committed
708
  } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
709 710
    mbmi->mb_skip_coeff = vp9_segfeature_active(xd, mbmi->segment_id,
                                                SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
711 712 713
  }

  // Read the reference frame
Paul Wilkins's avatar
Paul Wilkins committed
714
  mbmi->ref_frame = read_ref_frame(pbi, bc, mbmi->segment_id);
John Koleszar's avatar
John Koleszar committed
715

716 717
  // if (pbi->common.current_video_frame == 1)
  //   printf("ref frame: %d [%d %d]\n", mbmi->ref_frame, mb_row, mb_col);
718

John Koleszar's avatar
John Koleszar committed
719 720 721 722
  // 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
723
    vp9_prob mv_ref_p[VP9_MVREFS - 1];
John Koleszar's avatar
John Koleszar committed
724

725 726 727 728
    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];
729 730

    {
731 732 733 734
      const int use_prev_in_find_best_ref = sf0->x_num == sf0->x_den &&
                                            sf0->y_num == sf0->y_den &&
                                            !cm->error_resilient_mode &&
                                            !cm->frame_parallel_decoding_mode;
735

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

739
      setup_pred_block(&xd->pre, &cm->yv12_fb[ref_fb_idx],
740
                       mb_row, mb_col, sf0, sf_uv0);
741

742 743 744 745 746
#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
747
      vp9_find_mv_refs(cm, xd, mi, use_prev_in_find_mv_refs ? prev_mi : NULL,
Paul Wilkins's avatar
Paul Wilkins committed
748 749
                       ref_frame, mbmi->ref_mvs[ref_frame],
                       cm->ref_frame_sign_bias);
Paul Wilkins's avatar
Paul Wilkins committed
750

751
      vp9_mv_ref_probs(cm, mv_ref_p, mbmi->mb_mode_context[ref_frame]);
752

753
      // If the segment level skip mode enabled
Paul Wilkins's avatar
Paul Wilkins committed
754 755
      if (vp9_segfeature_active(xd, mbmi->segment_id, SEG_LVL_SKIP)) {
        mbmi->mode = ZEROMV;
756
      } else {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
757 758
        mbmi->mode = mbmi->sb_type ? read_sb_mv_ref(bc, mv_ref_p)
                                   : read_mv_ref(bc, mv_ref_p);
759
        vp9_accum_mv_refs(cm, mbmi->mode, mbmi->mb_mode_context[ref_frame]);
760 761 762 763
      }

      if (mbmi->mode != ZEROMV) {
        vp9_find_best_ref_mvs(xd,
764 765
                              use_prev_in_find_best_ref ? xd->pre.y_buffer
                                                        : NULL,
766
                              xd->pre.y_stride,
767 768 769
                              mbmi->ref_mvs[ref_frame],
                              &nearest, &nearby);

770
        best_mv.as_int = mbmi->ref_mvs[ref_frame][0].as_int;
771
      }
772

773 774 775 776 777 778
#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
779
    }
John Koleszar's avatar
John Koleszar committed
780