media/libvpx/vp9/decoder/vp9_decodemv.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /*
     2   Copyright (c) 2010 The WebM project authors. All Rights Reserved.
     3  *
     4  *  Use of this source code is governed by a BSD-style license
     5  *  that can be found in the LICENSE file in the root of the source
     6  *  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.
     9  */
    11 #include <assert.h>
    13 #include "vp9/common/vp9_common.h"
    14 #include "vp9/common/vp9_entropy.h"
    15 #include "vp9/common/vp9_entropymode.h"
    16 #include "vp9/common/vp9_entropymv.h"
    17 #include "vp9/common/vp9_findnearmv.h"
    18 #include "vp9/common/vp9_mvref_common.h"
    19 #include "vp9/common/vp9_pred_common.h"
    20 #include "vp9/common/vp9_reconinter.h"
    21 #include "vp9/common/vp9_seg_common.h"
    23 #include "vp9/decoder/vp9_decodemv.h"
    24 #include "vp9/decoder/vp9_decodframe.h"
    25 #include "vp9/decoder/vp9_onyxd_int.h"
    26 #include "vp9/decoder/vp9_treereader.h"
    28 static MB_PREDICTION_MODE read_intra_mode(vp9_reader *r, const vp9_prob *p) {
    29   return (MB_PREDICTION_MODE)treed_read(r, vp9_intra_mode_tree, p);
    30 }
    32 static MB_PREDICTION_MODE read_intra_mode_y(VP9_COMMON *cm, vp9_reader *r,
    33                                             int size_group) {
    34   const MB_PREDICTION_MODE y_mode = read_intra_mode(r,
    35                                         cm->fc.y_mode_prob[size_group]);
    36   if (!cm->frame_parallel_decoding_mode)
    37     ++cm->counts.y_mode[size_group][y_mode];
    38   return y_mode;
    39 }
    41 static MB_PREDICTION_MODE read_intra_mode_uv(VP9_COMMON *cm, vp9_reader *r,
    42                                              MB_PREDICTION_MODE y_mode) {
    43   const MB_PREDICTION_MODE uv_mode = read_intra_mode(r,
    44                                          cm->fc.uv_mode_prob[y_mode]);
    45   if (!cm->frame_parallel_decoding_mode)
    46     ++cm->counts.uv_mode[y_mode][uv_mode];
    47   return uv_mode;
    48 }
    50 static MB_PREDICTION_MODE read_inter_mode(VP9_COMMON *cm, vp9_reader *r,
    51                                           int ctx) {
    52   const int mode = treed_read(r, vp9_inter_mode_tree,
    53                               cm->fc.inter_mode_probs[ctx]);
    54   if (!cm->frame_parallel_decoding_mode)
    55     ++cm->counts.inter_mode[ctx][mode];
    57   return NEARESTMV + mode;
    58 }
    60 static int read_segment_id(vp9_reader *r, const struct segmentation *seg) {
    61   return treed_read(r, vp9_segment_tree, seg->tree_probs);
    62 }
    64 static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
    65                                      TX_SIZE max_tx_size, vp9_reader *r) {
    66   const int ctx = vp9_get_pred_context_tx_size(xd);
    67   const vp9_prob *tx_probs = get_tx_probs(max_tx_size, ctx, &cm->fc.tx_probs);
    68   TX_SIZE tx_size = vp9_read(r, tx_probs[0]);
    69   if (tx_size != TX_4X4 && max_tx_size >= TX_16X16) {
    70     tx_size += vp9_read(r, tx_probs[1]);
    71     if (tx_size != TX_8X8 && max_tx_size >= TX_32X32)
    72       tx_size += vp9_read(r, tx_probs[2]);
    73   }
    75   if (!cm->frame_parallel_decoding_mode)
    76     ++get_tx_counts(max_tx_size, ctx, &cm->counts.tx)[tx_size];
    77   return tx_size;
    78 }
    80 static TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, TX_MODE tx_mode,
    81                             BLOCK_SIZE bsize, int allow_select, vp9_reader *r) {
    82   const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
    83   if (allow_select && tx_mode == TX_MODE_SELECT && bsize >= BLOCK_8X8)
    84     return read_selected_tx_size(cm, xd, max_tx_size, r);
    85   else
    86     return MIN(max_tx_size, tx_mode_to_biggest_tx_size[tx_mode]);
    87 }
    89 static void set_segment_id(VP9_COMMON *cm, BLOCK_SIZE bsize,
    90                            int mi_row, int mi_col, int segment_id) {
    91   const int mi_offset = mi_row * cm->mi_cols + mi_col;
    92   const int bw = num_8x8_blocks_wide_lookup[bsize];
    93   const int bh = num_8x8_blocks_high_lookup[bsize];
    94   const int xmis = MIN(cm->mi_cols - mi_col, bw);
    95   const int ymis = MIN(cm->mi_rows - mi_row, bh);
    96   int x, y;
    98   assert(segment_id >= 0 && segment_id < MAX_SEGMENTS);
   100   for (y = 0; y < ymis; y++)
   101     for (x = 0; x < xmis; x++)
   102       cm->last_frame_seg_map[mi_offset + y * cm->mi_cols + x] = segment_id;
   103 }
   105 static int read_intra_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   106                                  int mi_row, int mi_col,
   107                                  vp9_reader *r) {
   108   struct segmentation *const seg = &cm->seg;
   109   const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
   110   int segment_id;
   112   if (!seg->enabled)
   113     return 0;  // Default for disabled segmentation
   115   if (!seg->update_map)
   116     return 0;
   118   segment_id = read_segment_id(r, seg);
   119   set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
   120   return segment_id;
   121 }
   123 static int read_inter_segment_id(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   124                                  int mi_row, int mi_col, vp9_reader *r) {
   125   struct segmentation *const seg = &cm->seg;
   126   const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
   127   int pred_segment_id, segment_id;
   129   if (!seg->enabled)
   130     return 0;  // Default for disabled segmentation
   132   pred_segment_id = vp9_get_segment_id(cm, cm->last_frame_seg_map,
   133                                        bsize, mi_row, mi_col);
   134   if (!seg->update_map)
   135     return pred_segment_id;
   137   if (seg->temporal_update) {
   138     const vp9_prob pred_prob = vp9_get_pred_prob_seg_id(seg, xd);
   139     const int pred_flag = vp9_read(r, pred_prob);
   140     vp9_set_pred_flag_seg_id(xd, pred_flag);
   141     segment_id = pred_flag ? pred_segment_id
   142                            : read_segment_id(r, seg);
   143   } else {
   144     segment_id = read_segment_id(r, seg);
   145   }
   146   set_segment_id(cm, bsize, mi_row, mi_col, segment_id);
   147   return segment_id;
   148 }
   150 static int read_skip_coeff(VP9_COMMON *cm, const MACROBLOCKD *xd,
   151                            int segment_id, vp9_reader *r) {
   152   if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
   153     return 1;
   154   } else {
   155     const int ctx = vp9_get_pred_context_mbskip(xd);
   156     const int skip = vp9_read(r, cm->fc.mbskip_probs[ctx]);
   157     if (!cm->frame_parallel_decoding_mode)
   158       ++cm->counts.mbskip[ctx][skip];
   159     return skip;
   160   }
   161 }
   163 static void read_intra_frame_mode_info(VP9_COMMON *const cm,
   164                                        MACROBLOCKD *const xd,
   165                                        MODE_INFO *const m,
   166                                        int mi_row, int mi_col, vp9_reader *r) {
   167   MB_MODE_INFO *const mbmi = &m->mbmi;
   168   const BLOCK_SIZE bsize = mbmi->sb_type;
   169   const MODE_INFO *above_mi = xd->mi_8x8[-cm->mode_info_stride];
   170   const MODE_INFO *left_mi  = xd->left_available ? xd->mi_8x8[-1] : NULL;
   172   mbmi->segment_id = read_intra_segment_id(cm, xd, mi_row, mi_col, r);
   173   mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
   174   mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, bsize, 1, r);
   175   mbmi->ref_frame[0] = INTRA_FRAME;
   176   mbmi->ref_frame[1] = NONE;
   178   if (bsize >= BLOCK_8X8) {
   179     const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, 0);
   180     const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, 0);
   181     mbmi->mode = read_intra_mode(r, vp9_kf_y_mode_prob[A][L]);
   182   } else {
   183     // Only 4x4, 4x8, 8x4 blocks
   184     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
   185     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
   186     int idx, idy;
   188     for (idy = 0; idy < 2; idy += num_4x4_h) {
   189       for (idx = 0; idx < 2; idx += num_4x4_w) {
   190         const int ib = idy * 2 + idx;
   191         const MB_PREDICTION_MODE A = above_block_mode(m, above_mi, ib);
   192         const MB_PREDICTION_MODE L = left_block_mode(m, left_mi, ib);
   193         const MB_PREDICTION_MODE b_mode = read_intra_mode(r,
   194                                               vp9_kf_y_mode_prob[A][L]);
   195         m->bmi[ib].as_mode = b_mode;
   196         if (num_4x4_h == 2)
   197           m->bmi[ib + 2].as_mode = b_mode;
   198         if (num_4x4_w == 2)
   199           m->bmi[ib + 1].as_mode = b_mode;
   200       }
   201     }
   203     mbmi->mode = m->bmi[3].as_mode;
   204   }
   206   mbmi->uv_mode = read_intra_mode(r, vp9_kf_uv_mode_prob[mbmi->mode]);
   207 }
   209 static int read_mv_component(vp9_reader *r,
   210                              const nmv_component *mvcomp, int usehp) {
   211   int mag, d, fr, hp;
   212   const int sign = vp9_read(r, mvcomp->sign);
   213   const int mv_class = treed_read(r, vp9_mv_class_tree, mvcomp->classes);
   214   const int class0 = mv_class == MV_CLASS_0;
   216   // Integer part
   217   if (class0) {
   218     d = treed_read(r, vp9_mv_class0_tree, mvcomp->class0);
   219   } else {
   220     int i;
   221     const int n = mv_class + CLASS0_BITS - 1;  // number of bits
   223     d = 0;
   224     for (i = 0; i < n; ++i)
   225       d |= vp9_read(r, mvcomp->bits[i]) << i;
   226   }
   228   // Fractional part
   229   fr = treed_read(r, vp9_mv_fp_tree,
   230                   class0 ? mvcomp->class0_fp[d] : mvcomp->fp);
   233   // High precision part (if hp is not used, the default value of the hp is 1)
   234   hp = usehp ? vp9_read(r, class0 ? mvcomp->class0_hp : mvcomp->hp)
   235              : 1;
   237   // Result
   238   mag = vp9_get_mv_mag(mv_class, (d << 3) | (fr << 1) | hp) + 1;
   239   return sign ? -mag : mag;
   240 }
   242 static INLINE void read_mv(vp9_reader *r, MV *mv, const MV *ref,
   243                            const nmv_context *ctx,
   244                            nmv_context_counts *counts, int allow_hp) {
   245   const MV_JOINT_TYPE j = treed_read(r, vp9_mv_joint_tree, ctx->joints);
   246   const int use_hp = allow_hp && vp9_use_mv_hp(ref);
   247   MV diff = {0, 0};
   249   if (mv_joint_vertical(j))
   250     diff.row = read_mv_component(r, &ctx->comps[0], use_hp);
   252   if (mv_joint_horizontal(j))
   253     diff.col = read_mv_component(r, &ctx->comps[1], use_hp);
   255   vp9_inc_mv(&diff, counts);
   257   mv->row = ref->row + diff.row;
   258   mv->col = ref->col + diff.col;
   259 }
   261 static COMPPREDMODE_TYPE read_reference_mode(VP9_COMMON *cm,
   262                                              const MACROBLOCKD *xd,
   263                                              vp9_reader *r) {
   264   const int ctx = vp9_get_pred_context_comp_inter_inter(cm, xd);
   265   const int mode = vp9_read(r, cm->fc.comp_inter_prob[ctx]);
   266   if (!cm->frame_parallel_decoding_mode)
   267     ++cm->counts.comp_inter[ctx][mode];
   268   return mode;  // SINGLE_PREDICTION_ONLY or COMP_PREDICTION_ONLY
   269 }
   271 // Read the referncence frame
   272 static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   273                             vp9_reader *r,
   274                             int segment_id, MV_REFERENCE_FRAME ref_frame[2]) {
   275   FRAME_CONTEXT *const fc = &cm->fc;
   276   FRAME_COUNTS *const counts = &cm->counts;
   278   if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
   279     ref_frame[0] = vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME);
   280     ref_frame[1] = NONE;
   281   } else {
   282     const COMPPREDMODE_TYPE mode = (cm->comp_pred_mode == HYBRID_PREDICTION)
   283                                       ? read_reference_mode(cm, xd, r)
   284                                       : cm->comp_pred_mode;
   286     // FIXME(rbultje) I'm pretty sure this breaks segmentation ref frame coding
   287     if (mode == COMP_PREDICTION_ONLY) {
   288       const int idx = cm->ref_frame_sign_bias[cm->comp_fixed_ref];
   289       const int ctx = vp9_get_pred_context_comp_ref_p(cm, xd);
   290       const int bit = vp9_read(r, fc->comp_ref_prob[ctx]);
   291       if (!cm->frame_parallel_decoding_mode)
   292         ++counts->comp_ref[ctx][bit];
   293       ref_frame[idx] = cm->comp_fixed_ref;
   294       ref_frame[!idx] = cm->comp_var_ref[bit];
   295     } else if (mode == SINGLE_PREDICTION_ONLY) {
   296       const int ctx0 = vp9_get_pred_context_single_ref_p1(xd);
   297       const int bit0 = vp9_read(r, fc->single_ref_prob[ctx0][0]);
   298       if (!cm->frame_parallel_decoding_mode)
   299         ++counts->single_ref[ctx0][0][bit0];
   300       if (bit0) {
   301         const int ctx1 = vp9_get_pred_context_single_ref_p2(xd);
   302         const int bit1 = vp9_read(r, fc->single_ref_prob[ctx1][1]);
   303         if (!cm->frame_parallel_decoding_mode)
   304           ++counts->single_ref[ctx1][1][bit1];
   305         ref_frame[0] = bit1 ? ALTREF_FRAME : GOLDEN_FRAME;
   306       } else {
   307         ref_frame[0] = LAST_FRAME;
   308       }
   310       ref_frame[1] = NONE;
   311     } else {
   312       assert(!"Invalid prediction mode.");
   313     }
   314   }
   315 }
   318 static INLINE INTERPOLATION_TYPE read_switchable_filter_type(
   319     VP9_COMMON *const cm, MACROBLOCKD *const xd, vp9_reader *r) {
   320   const int ctx = vp9_get_pred_context_switchable_interp(xd);
   321   const int type = treed_read(r, vp9_switchable_interp_tree,
   322                               cm->fc.switchable_interp_prob[ctx]);
   323   if (!cm->frame_parallel_decoding_mode)
   324     ++cm->counts.switchable_interp[ctx][type];
   325   return type;
   326 }
   328 static void read_intra_block_mode_info(VP9_COMMON *const cm, MODE_INFO *mi,
   329                                        vp9_reader *r) {
   330   MB_MODE_INFO *const mbmi = &mi->mbmi;
   331   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
   333   mbmi->ref_frame[0] = INTRA_FRAME;
   334   mbmi->ref_frame[1] = NONE;
   336   if (bsize >= BLOCK_8X8) {
   337     mbmi->mode = read_intra_mode_y(cm, r, size_group_lookup[bsize]);
   338   } else {
   339      // Only 4x4, 4x8, 8x4 blocks
   340      const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
   341      const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
   342      int idx, idy;
   344      for (idy = 0; idy < 2; idy += num_4x4_h) {
   345        for (idx = 0; idx < 2; idx += num_4x4_w) {
   346          const int ib = idy * 2 + idx;
   347          const int b_mode = read_intra_mode_y(cm, r, 0);
   348          mi->bmi[ib].as_mode = b_mode;
   349          if (num_4x4_h == 2)
   350            mi->bmi[ib + 2].as_mode = b_mode;
   351          if (num_4x4_w == 2)
   352            mi->bmi[ib + 1].as_mode = b_mode;
   353       }
   354     }
   355     mbmi->mode = mi->bmi[3].as_mode;
   356   }
   358   mbmi->uv_mode = read_intra_mode_uv(cm, r, mbmi->mode);
   359 }
   361 static INLINE int assign_mv(VP9_COMMON *cm, MB_PREDICTION_MODE mode,
   362                              int_mv mv[2], int_mv best_mv[2],
   363                              int_mv nearest_mv[2], int_mv near_mv[2],
   364                              int is_compound, int allow_hp, vp9_reader *r) {
   365   int i;
   366   int ret = 1;
   368   switch (mode) {
   369     case NEWMV: {
   370       nmv_context_counts *const mv_counts = cm->frame_parallel_decoding_mode ?
   371                                             NULL : &cm->counts.mv;
   372       read_mv(r, &mv[0].as_mv, &best_mv[0].as_mv,
   373               &cm->fc.nmvc, mv_counts, allow_hp);
   374       if (is_compound)
   375         read_mv(r, &mv[1].as_mv, &best_mv[1].as_mv,
   376                 &cm->fc.nmvc, mv_counts, allow_hp);
   377       for (i = 0; i < 1 + is_compound; ++i) {
   378         ret = ret && mv[i].as_mv.row < MV_UPP && mv[i].as_mv.row > MV_LOW;
   379         ret = ret && mv[i].as_mv.col < MV_UPP && mv[i].as_mv.col > MV_LOW;
   380       }
   381       break;
   382     }
   383     case NEARESTMV: {
   384       mv[0].as_int = nearest_mv[0].as_int;
   385       if (is_compound) mv[1].as_int = nearest_mv[1].as_int;
   386       break;
   387     }
   388     case NEARMV: {
   389       mv[0].as_int = near_mv[0].as_int;
   390       if (is_compound) mv[1].as_int = near_mv[1].as_int;
   391       break;
   392     }
   393     case ZEROMV: {
   394       mv[0].as_int = 0;
   395       if (is_compound) mv[1].as_int = 0;
   396       break;
   397     }
   398     default: {
   399       return 0;
   400     }
   401   }
   402   return ret;
   403 }
   405 static int read_is_inter_block(VP9_COMMON *const cm, MACROBLOCKD *const xd,
   406                                int segment_id, vp9_reader *r) {
   407   if (vp9_segfeature_active(&cm->seg, segment_id, SEG_LVL_REF_FRAME)) {
   408     return vp9_get_segdata(&cm->seg, segment_id, SEG_LVL_REF_FRAME) !=
   409            INTRA_FRAME;
   410   } else {
   411     const int ctx = vp9_get_pred_context_intra_inter(xd);
   412     const int is_inter = vp9_read(r, vp9_get_pred_prob_intra_inter(cm, xd));
   413     if (!cm->frame_parallel_decoding_mode)
   414       ++cm->counts.intra_inter[ctx][is_inter];
   415     return is_inter;
   416   }
   417 }
   419 static void read_inter_block_mode_info(VP9_COMMON *const cm,
   420                                        MACROBLOCKD *const xd,
   421                                        const TileInfo *const tile,
   422                                        MODE_INFO *const mi,
   423                                        int mi_row, int mi_col, vp9_reader *r) {
   424   MB_MODE_INFO *const mbmi = &mi->mbmi;
   425   const BLOCK_SIZE bsize = mbmi->sb_type;
   426   const int allow_hp = cm->allow_high_precision_mv;
   428   int_mv nearest[2], nearmv[2], best[2];
   429   uint8_t inter_mode_ctx;
   430   MV_REFERENCE_FRAME ref0;
   431   int is_compound;
   433   mbmi->uv_mode = DC_PRED;
   434   read_ref_frames(cm, xd, r, mbmi->segment_id, mbmi->ref_frame);
   435   ref0 = mbmi->ref_frame[0];
   436   is_compound = has_second_ref(mbmi);
   438   vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi, ref0, mbmi->ref_mvs[ref0],
   439                    mi_row, mi_col);
   441   inter_mode_ctx = mbmi->mode_context[ref0];
   443   if (vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
   444     mbmi->mode = ZEROMV;
   445     if (bsize < BLOCK_8X8) {
   446         vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
   447                            "Invalid usage of segement feature on small blocks");
   448         return;
   449     }
   450   } else {
   451     if (bsize >= BLOCK_8X8)
   452       mbmi->mode = read_inter_mode(cm, r, inter_mode_ctx);
   453   }
   455   // nearest, nearby
   456   if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
   457     vp9_find_best_ref_mvs(xd, allow_hp,
   458                           mbmi->ref_mvs[ref0], &nearest[0], &nearmv[0]);
   459     best[0].as_int = nearest[0].as_int;
   460   }
   462   if (is_compound) {
   463     const MV_REFERENCE_FRAME ref1 = mbmi->ref_frame[1];
   464     vp9_find_mv_refs(cm, xd, tile, mi, xd->last_mi,
   465                      ref1, mbmi->ref_mvs[ref1], mi_row, mi_col);
   467     if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
   468       vp9_find_best_ref_mvs(xd, allow_hp,
   469                             mbmi->ref_mvs[ref1], &nearest[1], &nearmv[1]);
   470       best[1].as_int = nearest[1].as_int;
   471     }
   472   }
   474   mbmi->interp_filter = (cm->mcomp_filter_type == SWITCHABLE)
   475                       ? read_switchable_filter_type(cm, xd, r)
   476                       : cm->mcomp_filter_type;
   478   if (bsize < BLOCK_8X8) {
   479     const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];  // 1 or 2
   480     const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];  // 1 or 2
   481     int idx, idy;
   482     int b_mode;
   483     for (idy = 0; idy < 2; idy += num_4x4_h) {
   484       for (idx = 0; idx < 2; idx += num_4x4_w) {
   485         int_mv block[2];
   486         const int j = idy * 2 + idx;
   487         b_mode = read_inter_mode(cm, r, inter_mode_ctx);
   489         if (b_mode == NEARESTMV || b_mode == NEARMV) {
   490           vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[0],
   491                                         &nearmv[0], j, 0,
   492                                         mi_row, mi_col);
   494           if (is_compound)
   495             vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, &nearest[1],
   496                                           &nearmv[1], j, 1,
   497                                           mi_row, mi_col);
   498         }
   500         if (!assign_mv(cm, b_mode, block, best, nearest, nearmv,
   501                        is_compound, allow_hp, r)) {
   502           xd->corrupted |= 1;
   503           break;
   504         };
   507         mi->bmi[j].as_mv[0].as_int = block[0].as_int;
   508         if (is_compound)
   509           mi->bmi[j].as_mv[1].as_int = block[1].as_int;
   511         if (num_4x4_h == 2)
   512           mi->bmi[j + 2] = mi->bmi[j];
   513         if (num_4x4_w == 2)
   514           mi->bmi[j + 1] = mi->bmi[j];
   515       }
   516     }
   518     mi->mbmi.mode = b_mode;
   520     mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
   521     mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
   522   } else {
   523     xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv,
   524                                 best, nearest, nearmv,
   525                                 is_compound, allow_hp, r);
   526   }
   527 }
   529 static void read_inter_frame_mode_info(VP9_COMMON *const cm,
   530                                        MACROBLOCKD *const xd,
   531                                        const TileInfo *const tile,
   532                                        MODE_INFO *const mi,
   533                                        int mi_row, int mi_col, vp9_reader *r) {
   534   MB_MODE_INFO *const mbmi = &mi->mbmi;
   535   int inter_block;
   537   mbmi->mv[0].as_int = 0;
   538   mbmi->mv[1].as_int = 0;
   539   mbmi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
   540   mbmi->skip_coeff = read_skip_coeff(cm, xd, mbmi->segment_id, r);
   541   inter_block = read_is_inter_block(cm, xd, mbmi->segment_id, r);
   542   mbmi->tx_size = read_tx_size(cm, xd, cm->tx_mode, mbmi->sb_type,
   543                                !mbmi->skip_coeff || !inter_block, r);
   545   if (inter_block)
   546     read_inter_block_mode_info(cm, xd, tile, mi, mi_row, mi_col, r);
   547   else
   548     read_intra_block_mode_info(cm, mi, r);
   549 }
   551 void vp9_read_mode_info(VP9_COMMON *cm, MACROBLOCKD *xd,
   552                         const TileInfo *const tile,
   553                         int mi_row, int mi_col, vp9_reader *r) {
   554   MODE_INFO *const mi = xd->mi_8x8[0];
   555   const BLOCK_SIZE bsize = mi->mbmi.sb_type;
   556   const int bw = num_8x8_blocks_wide_lookup[bsize];
   557   const int bh = num_8x8_blocks_high_lookup[bsize];
   558   const int y_mis = MIN(bh, cm->mi_rows - mi_row);
   559   const int x_mis = MIN(bw, cm->mi_cols - mi_col);
   560   int x, y, z;
   562   if (frame_is_intra_only(cm))
   563     read_intra_frame_mode_info(cm, xd, mi, mi_row, mi_col, r);
   564   else
   565     read_inter_frame_mode_info(cm, xd, tile, mi, mi_row, mi_col, r);
   567   for (y = 0, z = 0; y < y_mis; y++, z += cm->mode_info_stride) {
   568     for (x = !y; x < x_mis; x++) {
   569       xd->mi_8x8[z + x] = mi;
   570     }
   571   }
   572 }

mercurial