media/libvpx/vp9/decoder/vp9_decodemv.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/media/libvpx/vp9/decoder/vp9_decodemv.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,572 @@
     1.4 +/*
     1.5 +  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     1.6 + *
     1.7 + *  Use of this source code is governed by a BSD-style license
     1.8 + *  that can be found in the LICENSE file in the root of the source
     1.9 + *  tree. An additional intellectual property rights grant can be found
    1.10 + *  in the file PATENTS.  All contributing project authors may
    1.11 + *  be found in the AUTHORS file in the root of the source tree.
    1.12 + */
    1.13 +
    1.14 +#include <assert.h>
    1.15 +
    1.16 +#include "vp9/common/vp9_common.h"
    1.17 +#include "vp9/common/vp9_entropy.h"
    1.18 +#include "vp9/common/vp9_entropymode.h"
    1.19 +#include "vp9/common/vp9_entropymv.h"
    1.20 +#include "vp9/common/vp9_findnearmv.h"
    1.21 +#include "vp9/common/vp9_mvref_common.h"
    1.22 +#include "vp9/common/vp9_pred_common.h"
    1.23 +#include "vp9/common/vp9_reconinter.h"
    1.24 +#include "vp9/common/vp9_seg_common.h"
    1.25 +
    1.26 +#include "vp9/decoder/vp9_decodemv.h"
    1.27 +#include "vp9/decoder/vp9_decodframe.h"
    1.28 +#include "vp9/decoder/vp9_onyxd_int.h"
    1.29 +#include "vp9/decoder/vp9_treereader.h"
    1.30 +
    1.31 +static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
    1.32 +  return (MB_PREDICTION_MODE)treed_read(r, vp9_intra_mode_tree, p);
    1.33 +}
    1.34 +
    1.35 +static MB_PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r,
    1.36 +                                            int size_group) {
    1.37 +  const MB_PREDICTION_MODE y_mode = read_intra_mode(r,
    1.38 +                                        cm->fc.y_mode_prob[size_group]);
    1.39 +  if (!cm->frame_parallel_decoding_mode)
    1.40 +    ++cm->counts.y_mode[size_group][y_mode];
    1.41 +  return y_mode;
    1.42 +}
    1.43 +
    1.44 +static MB_PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r,
    1.45 +                                             MB_PREDICTION_MODE y_mode) {
    1.46 +  const MB_PREDICTION_MODE uv_mode = read_intra_mode(r,
    1.47 +                                         cm->fc.uv_mode_prob[y_mode]);
    1.48 +  if (!cm->frame_parallel_decoding_mode)
    1.49 +    ++cm->counts.uv_mode[y_mode][uv_mode];
    1.50 +  return uv_mode;
    1.51 +}
    1.52 +
    1.53 +static MB_PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r,
    1.54 +                                          int ctx) {
    1.55 +  const int mode = treed_read(r, vp9_inter_mode_tree,
    1.56 +                              cm->fc.inter_mode_probs[ctx]);
    1.57 +  if (!cm->frame_parallel_decoding_mode)
    1.58 +    ++cm->counts.inter_mode[ctx][mode];
    1.59 +
    1.60 +  return NEARESTMV + mode;
    1.61 +}
    1.62 +
    1.63 +static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
    1.64 +  return treed_read(r, vp9_segment_tree, seg->tree_probs);
    1.65 +}
    1.66 +
    1.67 +static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
    1.68 +                                     TX_SIZE max_tx_size, vp9_reader *r) {
    1.69 +  const int ctx = vp9_get_pred_context_tx_size(xd);
    1.70 +  const vp9_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc.tx_probs);
    1.71 +  TX_SIZE tx_size = vp9_read(r, tx_probs[0]);
    1.72 +  if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
    1.73 +    tx_size += vp9_read(r, tx_probs[1]);
    1.74 +    if (tx_size != TX_8X8 && max_tx_size >= TX_32X32)
    1.75 +      tx_size += vp9_read(r, tx_probs[2]);
    1.76 +  }
    1.77 +
    1.78 +  if (!cm->frame_parallel_decoding_mode)
    1.79 +    ++get_tx_counts(max_tx_size, ctx, &cm->counts.tx)[tx_size];
    1.80 +  return tx_size;
    1.81 +}
    1.82 +
    1.83 +static TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, TX_MODE tx_mode,
    1.84 +                            BLOCK_SIZE bsize, int allow_select, vp9_reader *r) {
    1.85 +  const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
    1.86 +  if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
    1.87 +    return read_selected_tx_size(cm, xd, max_tx_size, r);
    1.88 +  else
    1.89 +    return MIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]);
    1.90 +}
    1.91 +
    1.92 +static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE bsize,
    1.93 +                           int mi_row, int mi_col, int segment_id) {
    1.94 +  const int mi_offset = mi_row * cm->mi_cols + mi_col;
    1.95 +  const int bw = num_8x8_blocks_wide_lookup[bsize];
    1.96 +  const int bh = num_8x8_blocks_high_lookup[bsize];
    1.97 +  const int xmis = MIN(cm->mi_cols - mi_col, bw);
    1.98 +  const int ymis = MIN(cm->mi_rows - mi_row, bh);
    1.99 +  int x, y;
   1.100 +
   1.101 +  assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
   1.102 +
   1.103 +  for (y = 0; y < ymis; y++)
   1.104 +    for (x = 0; x < xmis; x++)
   1.105 +      cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
   1.106 +}
   1.107 +
   1.108 +static int read_intra_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   1.109 +                                 int mi_row, int mi_col,
   1.110 +                                 vp9_reader *r) {
   1.111 +  struct segmentation *const seg = &cm->seg;
   1.112 +  const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
   1.113 +  int segment_id;
   1.114 +
   1.115 +  if (!seg->enabled)
   1.116 +    return 0;  // Default for disabled segmentation
   1.117 +
   1.118 +  if (!seg->update_map)
   1.119 +    return 0;
   1.120 +
   1.121 +  segment_id = read_segment_id(r, seg);
   1.122 +  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
   1.123 +  return segment_id;
   1.124 +}
   1.125 +
   1.126 +static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   1.127 +                                 int mi_row, int mi_col, vp9_reader *r) {
   1.128 +  struct segmentation *const seg = &cm->seg;
   1.129 +  const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
   1.130 +  int pred_segment_id, segment_id;
   1.131 +
   1.132 +  if (!seg->enabled)
   1.133 +    return 0;  // Default for disabled segmentation
   1.134 +
   1.135 +  pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
   1.136 +                                       bsize, mi_row, mi_col);
   1.137 +  if (!seg->update_map)
   1.138 +    return pred_segment_id;
   1.139 +
   1.140 +  if (seg->temporal_update) {
   1.141 +    const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
   1.142 +    const int pred_flag = vp9_read(r, pred_prob);
   1.143 +    vp9_set_pred_flag_seg_id(xd, pred_flag);
   1.144 +    segment_id = pred_flag ? pred_segment_id
   1.145 +                           : read_segment_id(r, seg);
   1.146 +  } else {
   1.147 +    segment_id = read_segment_id(r, seg);
   1.148 +  }
   1.149 +  set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
   1.150 +  return segment_id;
   1.151 +}
   1.152 +
   1.153 +static int read_skip_coeff(VP9_COMMON *cm, const MACROBLOCKD *xd,
   1.154 +                           int segment_id, vp9_reader *r) {
   1.155 +  if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
   1.156 +    return 1;
   1.157 +  } else {
   1.158 +    const int ctx = vp9_get_pred_context_mbskip(xd);
   1.159 +    const int skip = vp9_read(r, cm->fc.mbskip_probs[ctx]);
   1.160 +    if (!cm->frame_parallel_decoding_mode)
   1.161 +      ++cm->counts.mbskip[ctx][skip];
   1.162 +    return skip;
   1.163 +  }
   1.164 +}
   1.165 +
   1.166 +static void read_intra_frame_mode_info(VP9_COMMON *const cm,
   1.167 +                                       MACROBLOCKD *const xd,
   1.168 +                                       MODE_INFO *const m,
   1.169 +                                       int mi_row, int mi_col, vp9_reader *r) {
   1.170 +  MB_MODE_INFO *const mbmi = &m->mbmi;
   1.171 +  const BLOCK_SIZE bsize = mbmi->sb_type;
   1.172 +  const MODE_INFO *above_mi = xd->mi_8x8[-cm->mode_info_stride];
   1.173 +  const MODE_INFO *left_mi  = xd->left_available ? xd->mi_8x8[-1] : NULL;
   1.174 +
   1.175 +  mbmi->segment_id = read_intra_segment_id(cm, xd, mi_row, mi_col, r);
   1.176 +  mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
   1.177 +  mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, bsize, 1, r);
   1.178 +  mbmi->ref_frame[0] = INTRA_FRAME;
   1.179 +  mbmi->ref_frame[1] = NONE;
   1.180 +
   1.181 +  if (bsize >= BLOCK_8X8) {
   1.182 +    const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
   1.183 +    const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, 0);
   1.184 +    mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
   1.185 +  } else {
   1.186 +    // Only 4x4, 4x8, 8x4 blocks
   1.187 +    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
   1.188 +    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
   1.189 +    int idx, idy;
   1.190 +
   1.191 +    for (idy = 0; idy < 2; idy += num_4x4_h) {
   1.192 +      for (idx = 0; idx < 2; idx += num_4x4_w) {
   1.193 +        const int ib = idy * 2 + idx;
   1.194 +        const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, ib);
   1.195 +        const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, ib);
   1.196 +        const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
   1.197 +                                              vp9_kf_y_mode_prob[A][L]);
   1.198 +        m->bmi[ib].as_mode = b_mode;
   1.199 +        if (num_4x4_h == 2)
   1.200 +          m->bmi[ib + 2].as_mode = b_mode;
   1.201 +        if (num_4x4_w == 2)
   1.202 +          m->bmi[ib + 1].as_mode = b_mode;
   1.203 +      }
   1.204 +    }
   1.205 +
   1.206 +    mbmi->mode = m->bmi[3].as_mode;
   1.207 +  }
   1.208 +
   1.209 +  mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
   1.210 +}
   1.211 +
   1.212 +static int read_mv_component(vp9_reader *r,
   1.213 +                             const nmv_component *mvcomp, int usehp) {
   1.214 +  int mag, d, fr, hp;
   1.215 +  const int sign = vp9_read(r, mvcomp->sign);
   1.216 +  const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
   1.217 +  const int class0 = mv_class == MV_CLASS_0;
   1.218 +
   1.219 +  // Integer part
   1.220 +  if (class0) {
   1.221 +    d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
   1.222 +  } else {
   1.223 +    int i;
   1.224 +    const int n = mv_class + CLASS0_BITS - 1;  // number of bits
   1.225 +
   1.226 +    d = 0;
   1.227 +    for (i = 0; i < n; ++i)
   1.228 +      d |= vp9_read(r, mvcomp->bits[i]) << i;
   1.229 +  }
   1.230 +
   1.231 +  // Fractional part
   1.232 +  fr = treed_read(r, vp9_mv_fp_tree,
   1.233 +                  class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
   1.234 +
   1.235 +
   1.236 +  // High precision part (if hp is not used, the default value of the hp is 1)
   1.237 +  hp = usehp ? vp9_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp)
   1.238 +             : 1;
   1.239 +
   1.240 +  // Result
   1.241 +  mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
   1.242 +  return sign ? -mag : mag;
   1.243 +}
   1.244 +
   1.245 +static INLINE void read_mv(vp9_reader *r, MV *mv, const MV *ref,
   1.246 +                           const nmv_context *ctx,
   1.247 +                           nmv_context_counts *counts, int allow_hp) {
   1.248 +  const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
   1.249 +  const int use_hp = allow_hp && vp9_use_mv_hp(ref);
   1.250 +  MV diff = {0, 0};
   1.251 +
   1.252 +  if (mv_joint_vertical(j))
   1.253 +    diff.row = read_mv_component(r, &ctx->comps[0], use_hp);
   1.254 +
   1.255 +  if (mv_joint_horizontal(j))
   1.256 +    diff.col = read_mv_component(r, &ctx->comps[1], use_hp);
   1.257 +
   1.258 +  vp9_inc_mv(&diff, counts);
   1.259 +
   1.260 +  mv->row = ref->row + diff.row;
   1.261 +  mv->col = ref->col + diff.col;
   1.262 +}
   1.263 +
   1.264 +static COMPPREDMODE_TYPE read_reference_mode(VP9_COMMON *cm,
   1.265 +                                             const MACROBLOCKD *xd,
   1.266 +                                             vp9_reader *r) {
   1.267 +  const int ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
   1.268 +  const int mode = vp9_read(r, cm->fc.comp_inter_prob[ctx]);
   1.269 +  if (!cm->frame_parallel_decoding_mode)
   1.270 +    ++cm->counts.comp_inter[ctx][mode];
   1.271 +  return mode;  // SINGLE_PREDICTION_ONLY or COMP_PREDICTION_ONLY
   1.272 +}
   1.273 +
   1.274 +// Read the referncence frame
   1.275 +static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   1.276 +                            vp9_reader *r,
   1.277 +                            int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
   1.278 +  FRAME_CONTEXT *const fc = &cm->fc;
   1.279 +  FRAME_COUNTS *const counts = &cm->counts;
   1.280 +
   1.281 +  if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
   1.282 +    ref_frame[0] = vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
   1.283 +    ref_frame[1] = NONE;
   1.284 +  } else {
   1.285 +    const COMPPREDMODE_TYPE mode = (cm->comp_pred_mode == HYBRID_PREDICTION)
   1.286 +                                      ? read_reference_mode(cm, xd, r)
   1.287 +                                      : cm->comp_pred_mode;
   1.288 +
   1.289 +    // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
   1.290 +    if (mode == COMP_PREDICTION_ONLY) {
   1.291 +      const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
   1.292 +      const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
   1.293 +      const int bit = vp9_read(r, fc->comp_ref_prob[ctx]);
   1.294 +      if (!cm->frame_parallel_decoding_mode)
   1.295 +        ++counts->comp_ref[ctx][bit];
   1.296 +      ref_frame[idx] = cm->comp_fixed_ref;
   1.297 +      ref_frame[!idx] = cm->comp_var_ref[bit];
   1.298 +    } else if (mode == SINGLE_PREDICTION_ONLY) {
   1.299 +      const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
   1.300 +      const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
   1.301 +      if (!cm->frame_parallel_decoding_mode)
   1.302 +        ++counts->single_ref[ctx0][0][bit0];
   1.303 +      if (bit0) {
   1.304 +        const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
   1.305 +        const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
   1.306 +        if (!cm->frame_parallel_decoding_mode)
   1.307 +          ++counts->single_ref[ctx1][1][bit1];
   1.308 +        ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
   1.309 +      } else {
   1.310 +        ref_frame[0] = LAST_FRAME;
   1.311 +      }
   1.312 +
   1.313 +      ref_frame[1] = NONE;
   1.314 +    } else {
   1.315 +      assert(!"Invalid prediction mode.");
   1.316 +    }
   1.317 +  }
   1.318 +}
   1.319 +
   1.320 +
   1.321 +static INLINE INTERPOLATION_TYPE read_switchable_filter_type(
   1.322 +    VP9_COMMON *const cm, MACROBLOCKD *const xd, vp9_reader *r) {
   1.323 +  const int ctx = vp9_get_pred_context_switchable_interp(xd);
   1.324 +  const int type = treed_read(r, vp9_switchable_interp_tree,
   1.325 +                              cm->fc.switchable_interp_prob[ctx]);
   1.326 +  if (!cm->frame_parallel_decoding_mode)
   1.327 +    ++cm->counts.switchable_interp[ctx][type];
   1.328 +  return type;
   1.329 +}
   1.330 +
   1.331 +static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
   1.332 +                                       vp9_reader *r) {
   1.333 +  MB_MODE_INFO *const mbmi = &mi->mbmi;
   1.334 +  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
   1.335 +
   1.336 +  mbmi->ref_frame[0] = INTRA_FRAME;
   1.337 +  mbmi->ref_frame[1] = NONE;
   1.338 +
   1.339 +  if (bsize >= BLOCK_8X8) {
   1.340 +    mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
   1.341 +  } else {
   1.342 +     // Only 4x4, 4x8, 8x4 blocks
   1.343 +     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
   1.344 +     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
   1.345 +     int idx, idy;
   1.346 +
   1.347 +     for (idy = 0; idy < 2; idy += num_4x4_h) {
   1.348 +       for (idx = 0; idx < 2; idx += num_4x4_w) {
   1.349 +         const int ib = idy * 2 + idx;
   1.350 +         const int b_mode = read_intra_mode_y(cm, r, 0);
   1.351 +         mi->bmi[ib].as_mode = b_mode;
   1.352 +         if (num_4x4_h == 2)
   1.353 +           mi->bmi[ib + 2].as_mode = b_mode;
   1.354 +         if (num_4x4_w == 2)
   1.355 +           mi->bmi[ib + 1].as_mode = b_mode;
   1.356 +      }
   1.357 +    }
   1.358 +    mbmi->mode = mi->bmi[3].as_mode;
   1.359 +  }
   1.360 +
   1.361 +  mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
   1.362 +}
   1.363 +
   1.364 +static INLINE int assign_mv(VP9_COMMON *cm, MB_PREDICTION_MODE mode,
   1.365 +                             int_mv mv[2], int_mv best_mv[2],
   1.366 +                             int_mv nearest_mv[2], int_mv near_mv[2],
   1.367 +                             int is_compound, int allow_hp, vp9_reader *r) {
   1.368 +  int i;
   1.369 +  int ret = 1;
   1.370 +
   1.371 +  switch (mode) {
   1.372 +    case NEWMV: {
   1.373 +      nmv_context_counts *const mv_counts = cm->frame_parallel_decoding_mode ?
   1.374 +                                            NULL : &cm->counts.mv;
   1.375 +      read_mv(r, &mv[0].as_mv, &best_mv[0].as_mv,
   1.376 +              &cm->fc.nmvc, mv_counts, allow_hp);
   1.377 +      if (is_compound)
   1.378 +        read_mv(r, &mv[1].as_mv, &best_mv[1].as_mv,
   1.379 +                &cm->fc.nmvc, mv_counts, allow_hp);
   1.380 +      for (i = 0; i < 1 + is_compound; ++i) {
   1.381 +        ret = ret && mv[i].as_mv.row < MV_UPP && mv[i].as_mv.row > MV_LOW;
   1.382 +        ret = ret && mv[i].as_mv.col < MV_UPP && mv[i].as_mv.col > MV_LOW;
   1.383 +      }
   1.384 +      break;
   1.385 +    }
   1.386 +    case NEARESTMV: {
   1.387 +      mv[0].as_int = nearest_mv[0].as_int;
   1.388 +      if (is_compound) mv[1].as_int = nearest_mv[1].as_int;
   1.389 +      break;
   1.390 +    }
   1.391 +    case NEARMV: {
   1.392 +      mv[0].as_int = near_mv[0].as_int;
   1.393 +      if (is_compound) mv[1].as_int = near_mv[1].as_int;
   1.394 +      break;
   1.395 +    }
   1.396 +    case ZEROMV: {
   1.397 +      mv[0].as_int = 0;
   1.398 +      if (is_compound) mv[1].as_int = 0;
   1.399 +      break;
   1.400 +    }
   1.401 +    default: {
   1.402 +      return 0;
   1.403 +    }
   1.404 +  }
   1.405 +  return ret;
   1.406 +}
   1.407 +
   1.408 +static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   1.409 +                               int segment_id, vp9_reader *r) {
   1.410 +  if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
   1.411 +    return vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) !=
   1.412 +           INTRA_FRAME;
   1.413 +  } else {
   1.414 +    const int ctx = vp9_get_pred_context_intra_inter(xd);
   1.415 +    const int is_inter = vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
   1.416 +    if (!cm->frame_parallel_decoding_mode)
   1.417 +      ++cm->counts.intra_inter[ctx][is_inter];
   1.418 +    return is_inter;
   1.419 +  }
   1.420 +}
   1.421 +
   1.422 +static void read_inter_block_mode_info(VP9_COMMON *const cm,
   1.423 +                                       MACROBLOCKD *const xd,
   1.424 +                                       const TileInfo *const tile,
   1.425 +                                       MODE_INFO *const mi,
   1.426 +                                       int mi_row, int mi_col, vp9_reader *r) {
   1.427 +  MB_MODE_INFO *const mbmi = &mi->mbmi;
   1.428 +  const BLOCK_SIZE bsize = mbmi->sb_type;
   1.429 +  const int allow_hp = cm->allow_high_precision_mv;
   1.430 +
   1.431 +  int_mv nearest[2], nearmv[2], best[2];
   1.432 +  uint8_t inter_mode_ctx;
   1.433 +  MV_REFERENCE_FRAME ref0;
   1.434 +  int is_compound;
   1.435 +
   1.436 +  mbmi->uv_mode = DC_PRED;
   1.437 +  read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
   1.438 +  ref0 = mbmi->ref_frame[0];
   1.439 +  is_compound = has_second_ref(mbmi);
   1.440 +
   1.441 +  vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi, ref0, mbmi->ref_mvs[ref0],
   1.442 +                   mi_row, mi_col);
   1.443 +
   1.444 +  inter_mode_ctx = mbmi->mode_context[ref0];
   1.445 +
   1.446 +  if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
   1.447 +    mbmi->mode = ZEROMV;
   1.448 +    if (bsize < BLOCK_8X8) {
   1.449 +        vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
   1.450 +                           "Invalid usage of segement feature on small blocks");
   1.451 +        return;
   1.452 +    }
   1.453 +  } else {
   1.454 +    if (bsize >= BLOCK_8X8)
   1.455 +      mbmi->mode = read_inter_mode(cm, r, inter_mode_ctx);
   1.456 +  }
   1.457 +
   1.458 +  // nearest, nearby
   1.459 +  if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
   1.460 +    vp9_find_best_ref_mvs(xd, allow_hp,
   1.461 +                          mbmi->ref_mvs[ref0], &nearest[0], &nearmv[0]);
   1.462 +    best[0].as_int = nearest[0].as_int;
   1.463 +  }
   1.464 +
   1.465 +  if (is_compound) {
   1.466 +    const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
   1.467 +    vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi,
   1.468 +                     ref1, mbmi->ref_mvs[ref1], mi_row, mi_col);
   1.469 +
   1.470 +    if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
   1.471 +      vp9_find_best_ref_mvs(xd, allow_hp,
   1.472 +                            mbmi->ref_mvs[ref1], &nearest[1], &nearmv[1]);
   1.473 +      best[1].as_int = nearest[1].as_int;
   1.474 +    }
   1.475 +  }
   1.476 +
   1.477 +  mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE)
   1.478 +                      ? read_switchable_filter_type(cm, xd, r)
   1.479 +                      : cm->mcomp_filter_type;
   1.480 +
   1.481 +  if (bsize < BLOCK_8X8) {
   1.482 +    const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
   1.483 +    const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
   1.484 +    int idx, idy;
   1.485 +    int b_mode;
   1.486 +    for (idy = 0; idy < 2; idy += num_4x4_h) {
   1.487 +      for (idx = 0; idx < 2; idx += num_4x4_w) {
   1.488 +        int_mv block[2];
   1.489 +        const int j = idy * 2 + idx;
   1.490 +        b_mode = read_inter_mode(cm, r, inter_mode_ctx);
   1.491 +
   1.492 +        if (b_mode == NEARESTMV || b_mode == NEARMV) {
   1.493 +          vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[0],
   1.494 +                                        &nearmv[0], j, 0,
   1.495 +                                        mi_row, mi_col);
   1.496 +
   1.497 +          if (is_compound)
   1.498 +            vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[1],
   1.499 +                                          &nearmv[1], j, 1,
   1.500 +                                          mi_row, mi_col);
   1.501 +        }
   1.502 +
   1.503 +        if (!assign_mv(cm, b_mode, block, best, nearest, nearmv,
   1.504 +                       is_compound, allow_hp, r)) {
   1.505 +          xd->corrupted |= 1;
   1.506 +          break;
   1.507 +        };
   1.508 +
   1.509 +
   1.510 +        mi->bmi[j].as_mv[0].as_int = block[0].as_int;
   1.511 +        if (is_compound)
   1.512 +          mi->bmi[j].as_mv[1].as_int = block[1].as_int;
   1.513 +
   1.514 +        if (num_4x4_h == 2)
   1.515 +          mi->bmi[j + 2] = mi->bmi[j];
   1.516 +        if (num_4x4_w == 2)
   1.517 +          mi->bmi[j + 1] = mi->bmi[j];
   1.518 +      }
   1.519 +    }
   1.520 +
   1.521 +    mi->mbmi.mode = b_mode;
   1.522 +
   1.523 +    mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
   1.524 +    mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
   1.525 +  } else {
   1.526 +    xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv,
   1.527 +                                best, nearest, nearmv,
   1.528 +                                is_compound, allow_hp, r);
   1.529 +  }
   1.530 +}
   1.531 +
   1.532 +static void read_inter_frame_mode_info(VP9_COMMON *const cm,
   1.533 +                                       MACROBLOCKD *const xd,
   1.534 +                                       const TileInfo *const tile,
   1.535 +                                       MODE_INFO *const mi,
   1.536 +                                       int mi_row, int mi_col, vp9_reader *r) {
   1.537 +  MB_MODE_INFO *const mbmi = &mi->mbmi;
   1.538 +  int inter_block;
   1.539 +
   1.540 +  mbmi->mv[0].as_int = 0;
   1.541 +  mbmi->mv[1].as_int = 0;
   1.542 +  mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
   1.543 +  mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
   1.544 +  inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
   1.545 +  mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
   1.546 +                               !mbmi->skip_coeff || !inter_block, r);
   1.547 +
   1.548 +  if (inter_block)
   1.549 +    read_inter_block_mode_info(cm, xd, tile, mi, mi_row, mi_col, r);
   1.550 +  else
   1.551 +    read_intra_block_mode_info(cm, mi, r);
   1.552 +}
   1.553 +
   1.554 +void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
   1.555 +                        const TileInfo *const tile,
   1.556 +                        int mi_row, int mi_col, vp9_reader *r) {
   1.557 +  MODE_INFO *const mi = xd->mi_8x8[0];
   1.558 +  const BLOCK_SIZE bsize = mi->mbmi.sb_type;
   1.559 +  const int bw = num_8x8_blocks_wide_lookup[bsize];
   1.560 +  const int bh = num_8x8_blocks_high_lookup[bsize];
   1.561 +  const int y_mis = MIN(bh, cm->mi_rows - mi_row);
   1.562 +  const int x_mis = MIN(bw, cm->mi_cols - mi_col);
   1.563 +  int x, y, z;
   1.564 +
   1.565 +  if (frame_is_intra_only(cm))
   1.566 +    read_intra_frame_mode_info(cm, xd, mi, mi_row, mi_col, r);
   1.567 +  else
   1.568 +    read_inter_frame_mode_info(cm, xd, tile, mi, mi_row, mi_col, r);
   1.569 +
   1.570 +  for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride) {
   1.571 +    for (x = !y; x < x_mis; x++) {
   1.572 +      xd->mi_8x8[z + x] = mi;
   1.573 +    }
   1.574 +  }
   1.575 +}

mercurial