/*
  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


#include "treereader.h"
#include "vp8/common/entropymv.h"
#include "vp8/common/entropymode.h"
#include "onyxd_int.h"
#include "vp8/common/findnearmv.h"

#include "vp8/common/seg_common.h"
#include "vp8/common/pred_common.h"
#include "vp8/common/entropy.h"
#include "vp8/decoder/decodemv.h"
#if CONFIG_DEBUG
#include <assert.h>
#endif

// #define DEBUG_DEC_MV
#ifdef DEBUG_DEC_MV
int dec_mvcount = 0;
#endif

static int vp8_read_bmode(vp8_reader *bc, const vp8_prob *p) {
  return vp8_treed_read(bc, vp8_bmode_tree, p);
}


static int vp8_read_ymode(vp8_reader *bc, const vp8_prob *p) {
  return vp8_treed_read(bc, vp8_ymode_tree, p);
}

#if CONFIG_SUPERBLOCKS
static int vp8_sb_kfread_ymode(vp8_reader *bc, const vp8_prob *p) {
  return vp8_treed_read(bc, vp8_uv_mode_tree, p);
}
#endif

static int vp8_kfread_ymode(vp8_reader *bc, const vp8_prob *p) {
  return vp8_treed_read(bc, vp8_kf_ymode_tree, p);
}

static int vp8_read_i8x8_mode(vp8_reader *bc, const vp8_prob *p) {
  return vp8_treed_read(bc, vp8_i8x8_mode_tree, p);
}


static int vp8_read_uv_mode(vp8_reader *bc, const vp8_prob *p) {
  return vp8_treed_read(bc, vp8_uv_mode_tree, p);
}

// 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 vp8_read_mb_segid(vp8_reader *r, MB_MODE_INFO *mi,
                              MACROBLOCKD *xd) {
  /* Is segmentation enabled */
  if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
    /* If so then read the segment id. */
    if (vp8_read(r, xd->mb_segment_tree_probs[0]))
      mi->segment_id =
        (unsigned char)(2 + vp8_read(r, xd->mb_segment_tree_probs[2]));
    else
      mi->segment_id =
        (unsigned char)(vp8_read(r, xd->mb_segment_tree_probs[1]));
  }
}

#if CONFIG_NEW_MVREF
int vp8_read_mv_ref_id(vp8_reader *r,
                       vp8_prob * ref_id_probs) {
  int ref_index = 0;

  if (vp8_read(r, ref_id_probs[0])) {
    ref_index++;
    if (vp8_read(r, ref_id_probs[1])) {
      ref_index++;
      if (vp8_read(r, ref_id_probs[2]))
        ref_index++;
    }
  }
  return ref_index;
}
#endif

extern const int vp8_i8x8_block[4];
static void kfread_modes(VP8D_COMP *pbi,
                         MODE_INFO *m,
                         int mb_row,
                         int mb_col,
                         BOOL_DECODER* const bc) {
  VP8_COMMON *const cm = &pbi->common;
  const int mis = pbi->common.mode_info_stride;
  int map_index = mb_row * pbi->common.mb_cols + mb_col;
  MB_PREDICTION_MODE y_mode;

  // 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) {
    vp8_read_mb_segid(bc, &m->mbmi, &pbi->mb);
    pbi->common.last_frame_seg_map[map_index] = m->mbmi.segment_id;
  }

  m->mbmi.mb_skip_coeff = 0;
  if (pbi->common.mb_no_coeff_skip &&
      (!segfeature_active(&pbi->mb,
                          m->mbmi.segment_id, SEG_LVL_EOB) ||
       (get_segdata(&pbi->mb,
                    m->mbmi.segment_id, SEG_LVL_EOB) != 0))) {
    MACROBLOCKD *const xd  = &pbi->mb;
    m->mbmi.mb_skip_coeff =
      vp8_read(bc, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
  } else {
    if (segfeature_active(&pbi->mb,
                          m->mbmi.segment_id, SEG_LVL_EOB) &&
        (get_segdata(&pbi->mb,
                     m->mbmi.segment_id, SEG_LVL_EOB) == 0)) {
      m->mbmi.mb_skip_coeff = 1;
    } else
      m->mbmi.mb_skip_coeff = 0;
  }

#if CONFIG_SUPERBLOCKS
  if (m->mbmi.encoded_as_sb) {
    y_mode = (MB_PREDICTION_MODE) vp8_sb_kfread_ymode(bc,
      pbi->common.sb_kf_ymode_prob[pbi->common.kf_ymode_probs_index]);
  } else
#endif
  y_mode = (MB_PREDICTION_MODE) vp8_kfread_ymode(bc,
    pbi->common.kf_ymode_prob[pbi->common.kf_ymode_probs_index]);
#if CONFIG_COMP_INTRA_PRED
  m->mbmi.second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif

  m->mbmi.ref_frame = INTRA_FRAME;

  if ((m->mbmi.mode = y_mode) == B_PRED) {
    int i = 0;
#if CONFIG_COMP_INTRA_PRED
    int use_comp_pred = vp8_read(bc, 128);
#endif
    do {
      const B_PREDICTION_MODE A = above_block_mode(m, i, mis);
      const B_PREDICTION_MODE L = left_block_mode(m, i);

      m->bmi[i].as_mode.first =
        (B_PREDICTION_MODE) vp8_read_bmode(
          bc, pbi->common.kf_bmode_prob [A] [L]);
#if CONFIG_COMP_INTRA_PRED
      if (use_comp_pred) {
        m->bmi[i].as_mode.second =
          (B_PREDICTION_MODE) vp8_read_bmode(
            bc, pbi->common.kf_bmode_prob [A] [L]);
      } else {
        m->bmi[i].as_mode.second = (B_PREDICTION_MODE)(B_DC_PRED - 1);
      }
#endif
    } while (++i < 16);
  }
  if ((m->mbmi.mode = y_mode) == I8X8_PRED) {
    int i;
    int mode8x8;
    for (i = 0; i < 4; i++) {
      int ib = vp8_i8x8_block[i];
      mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.fc.i8x8_mode_prob);
      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;
#if CONFIG_COMP_INTRA_PRED
      m->bmi[ib + 0].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
      m->bmi[ib + 1].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
      m->bmi[ib + 4].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
      m->bmi[ib + 5].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
    }
  } else
    m->mbmi.uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(bc,
                                                           pbi->common.kf_uv_mode_prob[m->mbmi.mode]);
#if CONFIG_COMP_INTRA_PRED
  m->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif

#if CONFIG_SUPERBLOCKS
  if (m->mbmi.encoded_as_sb)
    m->mbmi.txfm_size = TX_8X8;
  else
#endif
  if (cm->txfm_mode == TX_MODE_SELECT && m->mbmi.mb_skip_coeff == 0 &&
      m->mbmi.mode <= I8X8_PRED) {
    // FIXME(rbultje) code ternary symbol once all experiments are merged
    m->mbmi.txfm_size = vp8_read(bc, cm->prob_tx[0]);
    if (m->mbmi.txfm_size != TX_4X4 && m->mbmi.mode != I8X8_PRED)
      m->mbmi.txfm_size += vp8_read(bc, cm->prob_tx[1]);
  } else if (cm->txfm_mode >= ALLOW_16X16 && m->mbmi.mode <= TM_PRED) {
    m->mbmi.txfm_size = TX_16X16;
  } else if (cm->txfm_mode >= ALLOW_8X8 && m->mbmi.mode != B_PRED) {
    m->mbmi.txfm_size = TX_8X8;
  } else {
    m->mbmi.txfm_size = TX_4X4;
  }
}

static int read_nmv_component(vp8_reader *r,
                              int rv,
                              const nmv_component *mvcomp) {
  int v, s, z, c, o, d;
  s = vp8_read(r, mvcomp->sign);
  c = vp8_treed_read(r, vp8_mv_class_tree, mvcomp->classes);
  if (c == MV_CLASS_0) {
    d = vp8_treed_read(r, vp8_mv_class0_tree, mvcomp->class0);
  } else {
    int i, b;
    d = 0;
    b = c + CLASS0_BITS - 1;  /* number of bits */
    for (i = 0; i < b; ++i)
      d |= (vp8_read(r, mvcomp->bits[i]) << i);
  }
  o = d << 3;

  z = vp8_get_mv_mag(c, o);
  v = (s ? -(z + 8) : (z + 8));
  return v;
}

static int read_nmv_component_fp(vp8_reader *r,
                                 int v,
                                 int rv,
                                 const nmv_component *mvcomp,
                                 int usehp) {
  int s, z, c, o, d, e, f;
  s = v < 0;
  z = (s ? -v : v) - 1;       /* magnitude - 1 */
  z &= ~7;

  c = vp8_get_mv_class(z, &o);
  d = o >> 3;

  if (c == MV_CLASS_0) {
    f = vp8_treed_read(r, vp8_mv_fp_tree, mvcomp->class0_fp[d]);
  } else {
    f = vp8_treed_read(r, vp8_mv_fp_tree, mvcomp->fp);
  }
  o += (f << 1);

  if (usehp) {
    if (c == MV_CLASS_0) {
      e = vp8_read(r, mvcomp->class0_hp);
    } else {
      e = vp8_read(r, mvcomp->hp);
    }
    o += e;
  } else {
    ++o;  /* Note if hp is not used, the default value of the hp bit is 1 */
  }
  z = vp8_get_mv_mag(c, o);
  v = (s ? -(z + 1) : (z + 1));
  return v;
}

static void read_nmv(vp8_reader *r, MV *mv, const MV *ref,
                     const nmv_context *mvctx) {
  MV_JOINT_TYPE j = vp8_treed_read(r, vp8_mv_joint_tree, mvctx->joints);
  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]);
  }
  if (j == MV_JOINT_HNZVZ || j == MV_JOINT_HNZVNZ) {
    mv->col = read_nmv_component(r, ref->col, &mvctx->comps[1]);
  }
}

static void read_nmv_fp(vp8_reader *r, MV *mv, const MV *ref,
                        const nmv_context *mvctx, int usehp) {
  MV_JOINT_TYPE j = vp8_get_mv_joint(*mv);
  usehp = usehp && vp8_use_nmv_hp(ref);
  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);
  }
  //printf("  %d: %d %d ref: %d %d\n", usehp, mv->row, mv-> col, ref->row, ref->col);
}

static void update_nmv(vp8_reader *bc, vp8_prob *const p,
                       const vp8_prob upd_p) {
  if (vp8_read(bc, upd_p)) {
#ifdef LOW_PRECISION_MV_UPDATE
    *p = (vp8_read_literal(bc, 7) << 1) | 1;
#else
    *p = (vp8_read_literal(bc, 8));
#endif
  }
}

static void read_nmvprobs(vp8_reader *bc, nmv_context *mvctx,
                          int usehp) {
  int i, j, k;
#ifdef MV_GROUP_UPDATE
  if (!vp8_read_bit(bc)) return;
#endif
  for (j = 0; j < MV_JOINTS - 1; ++j) {
    update_nmv(bc, &mvctx->joints[j],
               VP8_NMV_UPDATE_PROB);
  }
  for (i = 0; i < 2; ++i) {
    update_nmv(bc, &mvctx->comps[i].sign,
               VP8_NMV_UPDATE_PROB);
    for (j = 0; j < MV_CLASSES - 1; ++j) {
      update_nmv(bc, &mvctx->comps[i].classes[j],
                 VP8_NMV_UPDATE_PROB);
    }
    for (j = 0; j < CLASS0_SIZE - 1; ++j) {
      update_nmv(bc, &mvctx->comps[i].class0[j],
                 VP8_NMV_UPDATE_PROB);
    }
    for (j = 0; j < MV_OFFSET_BITS; ++j) {
      update_nmv(bc, &mvctx->comps[i].bits[j],
                 VP8_NMV_UPDATE_PROB);
    }
  }

  for (i = 0; i < 2; ++i) {
    for (j = 0; j < CLASS0_SIZE; ++j) {
      for (k = 0; k < 3; ++k)
        update_nmv(bc, &mvctx->comps[i].class0_fp[j][k],
                   VP8_NMV_UPDATE_PROB);
    }
    for (j = 0; j < 3; ++j) {
      update_nmv(bc, &mvctx->comps[i].fp[j],
                 VP8_NMV_UPDATE_PROB);
    }
  }

  if (usehp) {
    for (i = 0; i < 2; ++i) {
      update_nmv(bc, &mvctx->comps[i].class0_hp,
                 VP8_NMV_UPDATE_PROB);
      update_nmv(bc, &mvctx->comps[i].hp,
                 VP8_NMV_UPDATE_PROB);
    }
  }
}

// Read the referncence frame
static MV_REFERENCE_FRAME read_ref_frame(VP8D_COMP *pbi,
                                         vp8_reader *const bc,
                                         unsigned char segment_id) {
  MV_REFERENCE_FRAME ref_frame;
  int seg_ref_active;
  int seg_ref_count = 0;

  VP8_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd = &pbi->mb;

  seg_ref_active = segfeature_active(xd,
                                     segment_id,
                                     SEG_LVL_REF_FRAME);

  // If segment coding enabled does the segment allow for more than one
  // possible reference frame
  if (seg_ref_active) {
    seg_ref_count = check_segref(xd, segment_id, INTRA_FRAME) +
                    check_segref(xd, segment_id, LAST_FRAME) +
                    check_segref(xd, segment_id, GOLDEN_FRAME) +
                    check_segref(xd, segment_id, ALTREF_FRAME);
  }

  // Segment reference frame features not available or allows for
  // multiple reference frame options
  if (!seg_ref_active || (seg_ref_count > 1)) {
    // Values used in prediction model coding
    unsigned char prediction_flag;
    vp8_prob pred_prob;
    MV_REFERENCE_FRAME pred_ref;

    // Get the context probability the prediction flag
    pred_prob = vp9_get_pred_prob(cm, xd, PRED_REF);

    // Read the prediction status flag
    prediction_flag = (unsigned char)vp8_read(bc, pred_prob);

    // Store the prediction flag.
    vp9_set_pred_flag(xd, PRED_REF, prediction_flag);

    // Get the predicted reference frame.
    pred_ref = vp9_get_pred_ref(cm, xd);

    // If correctly predicted then use the predicted value
    if (prediction_flag) {
      ref_frame = pred_ref;
    }
    // else decode the explicitly coded value
    else {
      vp8_prob mod_refprobs[PREDICTION_PROBS];
      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] *=
          check_segref(xd, segment_id, INTRA_FRAME);
        mod_refprobs[LAST_FRAME] *=
          check_segref(xd, segment_id, LAST_FRAME);
        mod_refprobs[GOLDEN_FRAME] *=
          (check_segref(xd, segment_id, GOLDEN_FRAME) *
           check_segref(xd, segment_id, ALTREF_FRAME));
      }

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

      // Do we need to decode the Intra/Inter branch
      if (mod_refprobs[0])
        ref_frame = (MV_REFERENCE_FRAME) vp8_read(bc, mod_refprobs[0]);
      else
        ref_frame++;

      if (ref_frame) {
        // Do we need to decode the Last/Gf_Arf branch
        if (mod_refprobs[1])
          ref_frame += vp8_read(bc, mod_refprobs[1]);
        else
          ref_frame++;

        if (ref_frame > 1) {
          // Do we need to decode the GF/Arf branch
          if (mod_refprobs[2])
            ref_frame += vp8_read(bc, mod_refprobs[2]);
          else {
            if (seg_ref_active) {
              if ((pred_ref == GOLDEN_FRAME) ||
                  !check_segref(xd, segment_id, GOLDEN_FRAME)) {
                ref_frame = ALTREF_FRAME;
              } else
                ref_frame = GOLDEN_FRAME;
            } else
              ref_frame = (pred_ref == GOLDEN_FRAME)
                          ? ALTREF_FRAME : GOLDEN_FRAME;
          }
        }
      }
    }
  }

  // Segment reference frame features are enabled
  else {
    // 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
    vp9_set_pred_flag(xd, PRED_REF, 1);
    ref_frame = vp9_get_pred_ref(cm, xd);
  }

  return (MV_REFERENCE_FRAME)ref_frame;
}

#if CONFIG_SUPERBLOCKS
static MB_PREDICTION_MODE read_sb_mv_ref(vp8_reader *bc, const vp8_prob *p) {
  return (MB_PREDICTION_MODE) vp8_treed_read(bc, vp8_sb_mv_ref_tree, p);
}
#endif

static MB_PREDICTION_MODE read_mv_ref(vp8_reader *bc, const vp8_prob *p) {
  return (MB_PREDICTION_MODE) vp8_treed_read(bc, vp8_mv_ref_tree, p);
}

static B_PREDICTION_MODE sub_mv_ref(vp8_reader *bc, const vp8_prob *p) {
  return (B_PREDICTION_MODE) vp8_treed_read(bc, vp8_sub_mv_ref_tree, p);
}

#ifdef VPX_MODE_COUNT
unsigned int vp8_mv_cont_count[5][4] = {
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 },
  { 0, 0, 0, 0 }
};
#endif

static const unsigned char mbsplit_fill_count[4] = {8, 8, 4, 1};
static const unsigned char mbsplit_fill_offset[4][16] = {
  { 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}
};

static void read_switchable_interp_probs(VP8D_COMP* const pbi,
                                         BOOL_DECODER* const bc) {
  VP8_COMMON *const cm = &pbi->common;
  int i, j;
  for (j = 0; j <= VP8_SWITCHABLE_FILTERS; ++j) {
    for (i = 0; i < VP8_SWITCHABLE_FILTERS - 1; ++i) {
      cm->fc.switchable_interp_prob[j][i] = vp8_read_literal(bc, 8);
    }
  }
  //printf("DECODER: %d %d\n", cm->fc.switchable_interp_prob[0],
  //cm->fc.switchable_interp_prob[1]);
}

static void mb_mode_mv_init(VP8D_COMP *pbi, vp8_reader *bc) {
  VP8_COMMON *const cm = &pbi->common;
  nmv_context *const nmvc = &pbi->common.fc.nmvc;
  MACROBLOCKD *const xd  = &pbi->mb;

  if (cm->frame_type == KEY_FRAME) {
    if (!cm->kf_ymode_probs_update)
      cm->kf_ymode_probs_index = vp8_read_literal(bc, 3);
  } else {
#if CONFIG_PRED_FILTER
    cm->pred_filter_mode = (vp8_prob)vp8_read_literal(bc, 2);

    if (cm->pred_filter_mode == 2)
      cm->prob_pred_filter_off = (vp8_prob)vp8_read_literal(bc, 8);
#endif
    if (cm->mcomp_filter_type == SWITCHABLE)
      read_switchable_interp_probs(pbi, bc);
    // Decode the baseline probabilities for decoding reference frame
    cm->prob_intra_coded = (vp8_prob)vp8_read_literal(bc, 8);
    cm->prob_last_coded  = (vp8_prob)vp8_read_literal(bc, 8);
    cm->prob_gf_coded    = (vp8_prob)vp8_read_literal(bc, 8);

    // Computes a modified set of probabilities for use when reference
    // frame prediction fails.
    vp9_compute_mod_refprobs(cm);

    pbi->common.comp_pred_mode = vp8_read(bc, 128);
    if (cm->comp_pred_mode)
      cm->comp_pred_mode += vp8_read(bc, 128);
    if (cm->comp_pred_mode == HYBRID_PREDICTION) {
      int i;
      for (i = 0; i < COMP_PRED_CONTEXTS; i++)
        cm->prob_comppred[i] = (vp8_prob)vp8_read_literal(bc, 8);
    }

    if (vp8_read_bit(bc)) {
      int i = 0;

      do {
        cm->fc.ymode_prob[i] = (vp8_prob) vp8_read_literal(bc, 8);
      } while (++i < VP8_YMODES - 1);
    }

#if CONFIG_NEW_MVREF
  // Temp defaults probabilities for ecnoding the MV ref id signal
  vpx_memset(xd->mb_mv_ref_id_probs, 192, sizeof(xd->mb_mv_ref_id_probs));
#endif

    read_nmvprobs(bc, nmvc, xd->allow_high_precision_mv);
  }
}

// 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
static void read_mb_segment_id(VP8D_COMP *pbi,
                               int mb_row, int mb_col,
                               BOOL_DECODER* const bc) {
  VP8_COMMON *const cm = &pbi->common;
  MACROBLOCKD *const xd  = &pbi->mb;
  MODE_INFO *mi = xd->mode_info_context;
  MB_MODE_INFO *mbmi = &mi->mbmi;
  int index = mb_row * pbi->common.mb_cols + mb_col;

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

        // Read the prediction status flag
        unsigned char seg_pred_flag =
          (unsigned char)vp8_read(bc, pred_prob);

        // Store the prediction flag.
        vp9_set_pred_flag(xd, PRED_SEG_ID, seg_pred_flag);

        // If the value is flagged as correctly predicted
        // then use the predicted value
        if (seg_pred_flag) {
          mbmi->segment_id = vp9_get_pred_mb_segid(cm, xd, index);
        }
        // Else .... decode it explicitly
        else {
          vp8_read_mb_segid(bc, mbmi, xd);
        }
      }
      // Normal unpredicted coding mode
      else {
        vp8_read_mb_segid(bc, mbmi, xd);
      }
#if CONFIG_SUPERBLOCKS
      if (mbmi->encoded_as_sb) {
        cm->last_frame_seg_map[index] = mbmi->segment_id;
        if (mb_col + 1 < cm->mb_cols)
          cm->last_frame_seg_map[index + 1] = mbmi->segment_id;
        if (mb_row + 1 < cm->mb_rows) {
          cm->last_frame_seg_map[index + cm->mb_cols] = mbmi->segment_id;
          if (mb_col + 1 < cm->mb_cols)
            cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
        }
      } else
#endif
      {
        cm->last_frame_seg_map[index] = mbmi->segment_id;
      }
    } else {
#if CONFIG_SUPERBLOCKS
      if (mbmi->encoded_as_sb) {
        mbmi->segment_id = cm->last_frame_seg_map[index];
        if (mb_col < cm->mb_cols - 1)
          mbmi->segment_id = mbmi->segment_id &&
                             cm->last_frame_seg_map[index + 1];
        if (mb_row < cm->mb_rows - 1) {
          mbmi->segment_id = mbmi->segment_id &&
                             cm->last_frame_seg_map[index + cm->mb_cols];
          if (mb_col < cm->mb_cols - 1)
            mbmi->segment_id = mbmi->segment_id &&
                               cm->last_frame_seg_map[index + cm->mb_cols + 1];
        }
      } else
#endif
      {
        mbmi->segment_id = cm->last_frame_seg_map[index];
      }
    }
  } else {
    // The encoder explicitly sets the segment_id to 0
    // when segmentation is disabled
    mbmi->segment_id = 0;
  }
}

static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
                             MODE_INFO *prev_mi,
                             int mb_row, int mb_col,
                             BOOL_DECODER* const bc) {
  VP8_COMMON *const cm = &pbi->common;
  nmv_context *const nmvc = &pbi->common.fc.nmvc;
  const int mis = pbi->common.mode_info_stride;
  MACROBLOCKD *const xd  = &pbi->mb;

  int_mv *const mv = &mbmi->mv;
  int mb_to_left_edge;
  int mb_to_right_edge;
  int mb_to_top_edge;
  int mb_to_bottom_edge;

  mb_to_top_edge = xd->mb_to_top_edge;
  mb_to_bottom_edge = xd->mb_to_bottom_edge;
  mb_to_top_edge -= LEFT_TOP_MARGIN;
  mb_to_bottom_edge += RIGHT_BOTTOM_MARGIN;
  mbmi->need_to_clamp_mvs = 0;
  mbmi->need_to_clamp_secondmv = 0;
  mbmi->second_ref_frame = 0;
  /* 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
   */
  xd->mb_to_left_edge =
    mb_to_left_edge = -((mb_col * 16) << 3);
  mb_to_left_edge -= LEFT_TOP_MARGIN;

  xd->mb_to_right_edge =
    mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3;
  mb_to_right_edge += RIGHT_BOTTOM_MARGIN;

  // 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;

  // Read the macroblock segment id.
  read_mb_segment_id(pbi, mb_row, mb_col, bc);

  if (pbi->common.mb_no_coeff_skip &&
      (!segfeature_active(xd,
                          mbmi->segment_id, SEG_LVL_EOB) ||
       (get_segdata(xd, mbmi->segment_id, SEG_LVL_EOB) != 0))) {
    // Read the macroblock coeff skip flag if this feature is in use,
    // else default to 0
    mbmi->mb_skip_coeff = vp8_read(bc, vp9_get_pred_prob(cm, xd, PRED_MBSKIP));
  } else {
    if (segfeature_active(xd,
                          mbmi->segment_id, SEG_LVL_EOB) &&
        (get_segdata(xd, mbmi->segment_id, SEG_LVL_EOB) == 0)) {
      mbmi->mb_skip_coeff = 1;
    } else
      mbmi->mb_skip_coeff = 0;
  }

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

  // If reference frame is an Inter frame
  if (mbmi->ref_frame) {
    int rct[4];
    int_mv nearest, nearby, best_mv;
    int_mv nearest_second, nearby_second, best_mv_second;
    vp8_prob mv_ref_p [VP8_MVREFS - 1];

#if CONFIG_NEWBESTREFMV
    int recon_y_stride, recon_yoffset;
    int recon_uv_stride, recon_uvoffset;
#endif

    vp8_find_near_mvs(xd, mi,
                      prev_mi,
                      &nearest, &nearby, &best_mv, rct,
                      mbmi->ref_frame, cm->ref_frame_sign_bias);

#if CONFIG_NEWBESTREFMV
    {
      int ref_fb_idx;
      MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame;

      /* Select the appropriate reference frame for this MB */
      if (ref_frame == LAST_FRAME)
        ref_fb_idx = cm->lst_fb_idx;
      else if (ref_frame == GOLDEN_FRAME)
        ref_fb_idx = cm->gld_fb_idx;
      else
        ref_fb_idx = cm->alt_fb_idx;

      recon_y_stride = cm->yv12_fb[ref_fb_idx].y_stride  ;
      recon_uv_stride = cm->yv12_fb[ref_fb_idx].uv_stride;

      recon_yoffset = (mb_row * recon_y_stride * 16) + (mb_col * 16);
      recon_uvoffset = (mb_row * recon_uv_stride * 8) + (mb_col * 8);

      xd->pre.y_buffer = cm->yv12_fb[ref_fb_idx].y_buffer + recon_yoffset;
      xd->pre.u_buffer = cm->yv12_fb[ref_fb_idx].u_buffer + recon_uvoffset;
      xd->pre.v_buffer = cm->yv12_fb[ref_fb_idx].v_buffer + recon_uvoffset;

      vp9_find_mv_refs(xd, mi, prev_mi,
                       ref_frame, mbmi->ref_mvs[ref_frame],
                       cm->ref_frame_sign_bias);

      vp8_find_best_ref_mvs(xd,
                            xd->pre.y_buffer,
                            recon_y_stride,
                            mbmi->ref_mvs[ref_frame],
                            &best_mv, &nearest, &nearby);
    }
#endif

    vp8_mv_ref_probs(&pbi->common, mv_ref_p, rct);

    // Is the segment level mode feature enabled for this segment
    if (segfeature_active(xd, mbmi->segment_id, SEG_LVL_MODE)) {
      mbmi->mode =
        get_segdata(xd, mbmi->segment_id, SEG_LVL_MODE);
    } else {
#if CONFIG_SUPERBLOCKS
      if (mbmi->encoded_as_sb) {
        mbmi->mode = read_sb_mv_ref(bc, mv_ref_p);
      } else
#endif
      mbmi->mode = read_mv_ref(bc, mv_ref_p);

      vp8_accum_mv_refs(&pbi->common, mbmi->mode, rct);
    }

#if CONFIG_PRED_FILTER
    if (mbmi->mode >= NEARESTMV && mbmi->mode < SPLITMV) {
      // Is the prediction filter enabled
      if (cm->pred_filter_mode == 2)
        mbmi->pred_filter_enabled =
          vp8_read(bc, cm->prob_pred_filter_off);
      else
        mbmi->pred_filter_enabled = cm->pred_filter_mode;
    }
#endif
    if (mbmi->mode >= NEARESTMV && mbmi->mode <= SPLITMV)
    {
      if (cm->mcomp_filter_type == SWITCHABLE) {
        mbmi->interp_filter = vp8_switchable_interp[
            vp8_treed_read(bc, vp8_switchable_interp_tree,
                           vp9_get_pred_probs(cm, xd, PRED_SWITCHABLE_INTERP))];
      } else {
        mbmi->interp_filter = cm->mcomp_filter_type;
      }
    }

    if (cm->comp_pred_mode == COMP_PREDICTION_ONLY ||
        (cm->comp_pred_mode == HYBRID_PREDICTION &&
         vp8_read(bc, vp9_get_pred_prob(cm, xd, PRED_COMP)))) {
      /* 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;
#if CONFIG_NEWBESTREFMV
      if (mbmi->second_ref_frame) {
        int second_ref_fb_idx;
        /* Select the appropriate reference frame for this MB */
        if (mbmi->second_ref_frame == LAST_FRAME)
          second_ref_fb_idx = cm->lst_fb_idx;
        else if (mbmi->second_ref_frame ==
          GOLDEN_FRAME)
          second_ref_fb_idx = cm->gld_fb_idx;
        else
          second_ref_fb_idx = cm->alt_fb_idx;

        xd->second_pre.y_buffer =
          cm->yv12_fb[second_ref_fb_idx].y_buffer + recon_yoffset;
        xd->second_pre.u_buffer =
          cm->yv12_fb[second_ref_fb_idx].u_buffer + recon_uvoffset;
        xd->second_pre.v_buffer =
          cm->yv12_fb[second_ref_fb_idx].v_buffer + recon_uvoffset;
        vp8_find_near_mvs(xd, mi, prev_mi,
                          &nearest_second, &nearby_second, &best_mv_second,
                          rct,
                          mbmi->second_ref_frame,
                          cm->ref_frame_sign_bias);

        vp9_find_mv_refs(xd, mi, prev_mi,
                         mbmi->second_ref_frame,
                         mbmi->ref_mvs[mbmi->second_ref_frame],
                         cm->ref_frame_sign_bias);

        vp8_find_best_ref_mvs(xd,
                              xd->second_pre.y_buffer,
                              recon_y_stride,
                              mbmi->ref_mvs[mbmi->second_ref_frame],
                              &best_mv_second,
                              &nearest_second,
                              &nearby_second);
      }
#else
      vp8_find_near_mvs(xd, mi, prev_mi,
                        &nearest_second, &nearby_second, &best_mv_second,
                        rct,
                        mbmi->second_ref_frame,
                        pbi->common.ref_frame_sign_bias);
#endif
    } else {
      mbmi->second_ref_frame = 0;
    }

    mbmi->uv_mode = DC_PRED;
    switch (mbmi->mode) {
      case SPLITMV: {
        const int s = mbmi->partitioning =
                        vp8_treed_read(bc, vp8_mbsplit_tree, cm->fc.mbsplit_prob);
        const int num_p = vp8_mbsplit_count [s];
        int j = 0;
        cm->fc.mbsplit_counts[s]++;

        mbmi->need_to_clamp_mvs = 0;
        do { /* for each subset j */
          int_mv leftmv, abovemv, second_leftmv, second_abovemv;
          int_mv blockmv, secondmv;
          int k;  /* first block in subset j */
          int mv_contz;
          int blockmode;

          k = vp8_mbsplit_offset[s][j];

          leftmv.as_int = left_block_mv(mi, k);
          abovemv.as_int = above_block_mv(mi, k, mis);
          if (mbmi->second_ref_frame) {
            second_leftmv.as_int = left_block_second_mv(mi, k);
            second_abovemv.as_int = above_block_second_mv(mi, k, mis);
          }
          mv_contz = vp8_mv_cont(&leftmv, &abovemv);
          blockmode = sub_mv_ref(bc, cm->fc.sub_mv_ref_prob [mv_contz]);
          cm->fc.sub_mv_ref_counts[mv_contz][blockmode - LEFT4X4]++;

          switch (blockmode) {
            case NEW4X4:
              read_nmv(bc, &blockmv.as_mv, &best_mv.as_mv, nmvc);
              read_nmv_fp(bc, &blockmv.as_mv, &best_mv.as_mv, nmvc,
                          xd->allow_high_precision_mv);
              vp8_increment_nmv(&blockmv.as_mv, &best_mv.as_mv,
                                &cm->fc.NMVcount, xd->allow_high_precision_mv);
              blockmv.as_mv.row += best_mv.as_mv.row;
              blockmv.as_mv.col += best_mv.as_mv.col;

              if (mbmi->second_ref_frame) {
                read_nmv(bc, &secondmv.as_mv, &best_mv_second.as_mv, nmvc);
                read_nmv_fp(bc, &secondmv.as_mv, &best_mv_second.as_mv, nmvc,
                            xd->allow_high_precision_mv);
                vp8_increment_nmv(&secondmv.as_mv, &best_mv_second.as_mv,
                                  &cm->fc.NMVcount, xd->allow_high_precision_mv);
                secondmv.as_mv.row += best_mv_second.as_mv.row;
                secondmv.as_mv.col += best_mv_second.as_mv.col;
              }
#ifdef VPX_MODE_COUNT
              vp8_mv_cont_count[mv_contz][3]++;
#endif
              break;
            case LEFT4X4:
              blockmv.as_int = leftmv.as_int;
              if (mbmi->second_ref_frame)
                secondmv.as_int = second_leftmv.as_int;
#ifdef VPX_MODE_COUNT
              vp8_mv_cont_count[mv_contz][0]++;
#endif
              break;
            case ABOVE4X4:
              blockmv.as_int = abovemv.as_int;
              if (mbmi->second_ref_frame)
                secondmv.as_int = second_abovemv.as_int;
#ifdef VPX_MODE_COUNT
              vp8_mv_cont_count[mv_contz][1]++;
#endif
              break;
            case ZERO4X4:
              blockmv.as_int = 0;
              if (mbmi->second_ref_frame)
                secondmv.as_int = 0;
#ifdef VPX_MODE_COUNT
              vp8_mv_cont_count[mv_contz][2]++;
#endif
              break;
            default:
              break;
          }

          mbmi->need_to_clamp_mvs |= vp8_check_mv_bounds(&blockmv,
                                                         mb_to_left_edge,
                                                         mb_to_right_edge,
                                                         mb_to_top_edge,
                                                         mb_to_bottom_edge);
          if (mbmi->second_ref_frame) {
            mbmi->need_to_clamp_mvs |= vp8_check_mv_bounds(&secondmv,
                                                           mb_to_left_edge,
                                                           mb_to_right_edge,
                                                           mb_to_top_edge,
                                                           mb_to_bottom_edge);
          }

          {
            /* Fill (uniform) modes, mvs of jth subset.
             Must do it here because ensuing subsets can
             refer back to us via "left" or "above". */
            const unsigned char *fill_offset;
            unsigned int fill_count = mbsplit_fill_count[s];

            fill_offset = &mbsplit_fill_offset[s][(unsigned char)j * mbsplit_fill_count[s]];

            do {
              mi->bmi[ *fill_offset].as_mv.first.as_int = blockmv.as_int;
              if (mbmi->second_ref_frame)
                mi->bmi[ *fill_offset].as_mv.second.as_int = secondmv.as_int;
              fill_offset++;
            } while (--fill_count);
          }

        } while (++j < num_p);
      }

      mv->as_int = mi->bmi[15].as_mv.first.as_int;
      mbmi->mv[1].as_int = mi->bmi[15].as_mv.second.as_int;

      break;  /* done with SPLITMV */

      case NEARMV:
        mv->as_int = nearby.as_int;
        /* Clip "next_nearest" so that it does not extend to far out of image */
        vp8_clamp_mv(mv, mb_to_left_edge, mb_to_right_edge,
                     mb_to_top_edge, mb_to_bottom_edge);
        if (mbmi->second_ref_frame) {
          mbmi->mv[1].as_int = nearby_second.as_int;
          vp8_clamp_mv(&mbmi->mv[1], mb_to_left_edge, mb_to_right_edge,
                       mb_to_top_edge, mb_to_bottom_edge);
        }
        break;

      case NEARESTMV:
        mv->as_int = nearest.as_int;
        /* Clip "next_nearest" so that it does not extend to far out of image */
        vp8_clamp_mv(mv, mb_to_left_edge, mb_to_right_edge,
                     mb_to_top_edge, mb_to_bottom_edge);
        if (mbmi->second_ref_frame) {
          mbmi->mv[1].as_int = nearest_second.as_int;
          vp8_clamp_mv(&mbmi->mv[1], mb_to_left_edge, mb_to_right_edge,
                       mb_to_top_edge, mb_to_bottom_edge);
        }
        break;

      case ZEROMV:
        mv->as_int = 0;
        if (mbmi->second_ref_frame)
          mbmi->mv[1].as_int = 0;
        break;

      case NEWMV:

#if CONFIG_NEW_MVREF
        {
          int best_index;
          MV_REFERENCE_FRAME ref_frame = mbmi->ref_frame;

          // Encode the index of the choice.
          best_index =
            vp8_read_mv_ref_id(bc, xd->mb_mv_ref_id_probs[ref_frame]);

          best_mv.as_int = mbmi->ref_mvs[ref_frame][best_index].as_int;
        }
#endif

        read_nmv(bc, &mv->as_mv, &best_mv.as_mv, nmvc);
        read_nmv_fp(bc, &mv->as_mv, &best_mv.as_mv, nmvc,
                    xd->allow_high_precision_mv);
        vp8_increment_nmv(&mv->as_mv, &best_mv.as_mv, &cm->fc.NMVcount,
                          xd->allow_high_precision_mv);

        mv->as_mv.row += best_mv.as_mv.row;
        mv->as_mv.col += best_mv.as_mv.col;

        /* Don't need to check this on NEARMV and NEARESTMV modes
         * since those modes clamp the MV. The NEWMV mode does not,
         * so signal to the prediction stage whether special
         * handling may be required.
         */
        mbmi->need_to_clamp_mvs = vp8_check_mv_bounds(mv,
                                                      mb_to_left_edge,
                                                      mb_to_right_edge,
                                                      mb_to_top_edge,
                                                      mb_to_bottom_edge);

        if (mbmi->second_ref_frame) {
#if CONFIG_NEW_MVREF
        {
          int best_index;
          MV_REFERENCE_FRAME ref_frame = mbmi->second_ref_frame;

          // Encode the index of the choice.
          best_index =
            vp8_read_mv_ref_id(bc, xd->mb_mv_ref_id_probs[ref_frame]);
          best_mv_second.as_int = mbmi->ref_mvs[ref_frame][best_index].as_int;
        }
#endif

          read_nmv(bc, &mbmi->mv[1].as_mv, &best_mv_second.as_mv, nmvc);
          read_nmv_fp(bc, &mbmi->mv[1].as_mv, &best_mv_second.as_mv, nmvc,
                      xd->allow_high_precision_mv);
          vp8_increment_nmv(&mbmi->mv[1].as_mv, &best_mv_second.as_mv,
                            &cm->fc.NMVcount, xd->allow_high_precision_mv);
          mbmi->mv[1].as_mv.row += best_mv_second.as_mv.row;
          mbmi->mv[1].as_mv.col += best_mv_second.as_mv.col;
          mbmi->need_to_clamp_secondmv |=
            vp8_check_mv_bounds(&mbmi->mv[1],
                                mb_to_left_edge, mb_to_right_edge,
                                mb_to_top_edge, mb_to_bottom_edge);
        }
        break;
      default:
;
#if CONFIG_DEBUG
        assert(0);
#endif
    }
  } else {
    /* required for left and above block mv */
    mbmi->mv[0].as_int = 0;

    if (segfeature_active(xd, mbmi->segment_id, SEG_LVL_MODE))
      mbmi->mode = (MB_PREDICTION_MODE)
                   get_segdata(xd, mbmi->segment_id, SEG_LVL_MODE);
    else {
      // FIXME write using SB mode tree
      mbmi->mode = (MB_PREDICTION_MODE)
                   vp8_read_ymode(bc, pbi->common.fc.ymode_prob);
      pbi->common.fc.ymode_counts[mbmi->mode]++;
    }
#if CONFIG_COMP_INTRA_PRED
    mbmi->second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif

    // If MB mode is BPRED read the block modes
    if (mbmi->mode == B_PRED) {
      int j = 0;
#if CONFIG_COMP_INTRA_PRED
      int use_comp_pred = vp8_read(bc, 128);
#endif
      do {
        mi->bmi[j].as_mode.first = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob);
        /*
        {
          int p;
          for (p = 0; p < VP8_BINTRAMODES - 1; ++p)
            printf(" %d", pbi->common.fc.bmode_prob[p]);
          printf("\nbmode[%d][%d]: %d\n", pbi->common.current_video_frame, j, mi->bmi[j].as_mode.first);
        }
        */
        pbi->common.fc.bmode_counts[mi->bmi[j].as_mode.first]++;
#if CONFIG_COMP_INTRA_PRED
        if (use_comp_pred) {
          mi->bmi[j].as_mode.second = (B_PREDICTION_MODE)vp8_read_bmode(bc, pbi->common.fc.bmode_prob);
        } else {
          mi->bmi[j].as_mode.second = (B_PREDICTION_MODE)(B_DC_PRED - 1);
        }
#endif
      } while (++j < 16);
    }

    if (mbmi->mode == I8X8_PRED) {
      int i;
      int mode8x8;
      for (i = 0; i < 4; i++) {
        int ib = vp8_i8x8_block[i];
        mode8x8 = vp8_read_i8x8_mode(bc, pbi->common.fc.i8x8_mode_prob);
        mi->bmi[ib + 0].as_mode.first = mode8x8;
        mi->bmi[ib + 1].as_mode.first = mode8x8;
        mi->bmi[ib + 4].as_mode.first = mode8x8;
        mi->bmi[ib + 5].as_mode.first = mode8x8;
        pbi->common.fc.i8x8_mode_counts[mode8x8]++;
#if CONFIG_COMP_INTRA_PRED
        mi->bmi[ib + 0].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
        mi->bmi[ib + 1].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
        mi->bmi[ib + 4].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
        mi->bmi[ib + 5].as_mode.second = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
      }
    } else {
      mbmi->uv_mode = (MB_PREDICTION_MODE)vp8_read_uv_mode(
        bc, pbi->common.fc.uv_mode_prob[mbmi->mode]);
      pbi->common.fc.uv_mode_counts[mbmi->mode][mbmi->uv_mode]++;
    }

#if CONFIG_COMP_INTRA_PRED
    mbmi->second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
#endif
  }

#if CONFIG_SUPERBLOCKS
  if (mbmi->encoded_as_sb)
    mbmi->txfm_size = TX_8X8;
  else
#endif
  if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
      ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
       (mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
                           mbmi->partitioning == PARTITIONING_4X4)))) {
    // FIXME(rbultje) code ternary symbol once all experiments are merged
    mbmi->txfm_size = vp8_read(bc, cm->prob_tx[0]);
    if (mbmi->txfm_size != TX_4X4 && mbmi->mode != I8X8_PRED &&
        mbmi->mode != SPLITMV)
      mbmi->txfm_size += vp8_read(bc, cm->prob_tx[1]);
  } else if (cm->txfm_mode >= ALLOW_16X16 &&
      ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= TM_PRED) ||
       (mbmi->ref_frame != INTRA_FRAME && mbmi->mode != SPLITMV))) {
    mbmi->txfm_size = TX_16X16;
  } else if (cm->txfm_mode >= ALLOW_8X8 &&
      (!(mbmi->ref_frame == INTRA_FRAME && mbmi->mode == B_PRED) &&
       !(mbmi->ref_frame != INTRA_FRAME && mbmi->mode == SPLITMV &&
         mbmi->partitioning == PARTITIONING_4X4))) {
    mbmi->txfm_size = TX_8X8;
  } else {
    mbmi->txfm_size = TX_4X4;
  }
}

void vpx_decode_mode_mvs_init(VP8D_COMP *pbi, BOOL_DECODER* const bc) {
  VP8_COMMON *cm = &pbi->common;

  vpx_memset(cm->mbskip_pred_probs, 0, sizeof(cm->mbskip_pred_probs));
  if (pbi->common.mb_no_coeff_skip) {
    int k;
    for (k = 0; k < MBSKIP_CONTEXTS; ++k)
      cm->mbskip_pred_probs[k] = (vp8_prob)vp8_read_literal(bc, 8);
  }

  mb_mode_mv_init(pbi, bc);
}
void vpx_decode_mb_mode_mv(VP8D_COMP *pbi,
                           MACROBLOCKD *xd,
                           int mb_row,
                           int mb_col,
                           BOOL_DECODER* const bc) {
  MODE_INFO *mi = xd->mode_info_context;
  MODE_INFO *prev_mi = xd->prev_mode_info_context;

  if (pbi->common.frame_type == KEY_FRAME)
    kfread_modes(pbi, mi, mb_row, mb_col, bc);
  else
    read_mb_modes_mv(pbi, mi, &mi->mbmi, prev_mi, mb_row, mb_col, bc);
}
