Merge "vp9_reconinter.h static functions in header converted to global"
authorJim Bankoski <jimbankoski@google.com>
Mon, 10 Mar 2014 14:36:05 +0000 (07:36 -0700)
committerGerrit Code Review <gerrit@gerrit.golo.chromium.org>
Mon, 10 Mar 2014 14:36:05 +0000 (07:36 -0700)
1  2 
vp9/decoder/vp9_decodeframe.c
vp9/decoder/vp9_dthread.c
vp9/encoder/vp9_encodeframe.c
vp9/encoder/vp9_firstpass.c
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_rdopt.c

@@@ -35,7 -35,7 +35,7 @@@
  #include "vp9/decoder/vp9_decodemv.h"
  #include "vp9/decoder/vp9_dsubexp.h"
  #include "vp9/decoder/vp9_dthread.h"
 -#include "vp9/decoder/vp9_onyxd_int.h"
 +#include "vp9/decoder/vp9_onyxd.h"
  #include "vp9/decoder/vp9_read_bit_buffer.h"
  #include "vp9/decoder/vp9_reader.h"
  #include "vp9/decoder/vp9_thread.h"
@@@ -146,7 -146,7 +146,7 @@@ static void read_frame_reference_mode_p
  static void update_mv_probs(vp9_prob *p, int n, vp9_reader *r) {
    int i;
    for (i = 0; i < n; ++i)
 -    if (vp9_read(r, NMV_UPDATE_PROB))
 +    if (vp9_read(r, MV_UPDATE_PROB))
        p[i] = (vp9_read_literal(r, 7) << 1) | 1;
  }
  
@@@ -362,7 -362,7 +362,7 @@@ static void set_offsets(VP9_COMMON *con
    // as they are always compared to values that are in 1/8th pel units
    set_mi_row_col(xd, tile, mi_row, bh, mi_col, bw, cm->mi_rows, cm->mi_cols);
  
-   setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
+   vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
  }
  
  static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd,
    if (!vp9_is_valid_scale(&ref_buffer->sf))
      vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM,
                         "Invalid scale factors");
-   setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col, &ref_buffer->sf);
+   vp9_setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col,
+                        &ref_buffer->sf);
    xd->corrupted |= ref_buffer->buf->corrupted;
  }
  
@@@ -9,13 -9,10 +9,13 @@@
   */
  
  #include "./vpx_config.h"
 +
 +#include "vpx_mem/vpx_mem.h"
 +
  #include "vp9/common/vp9_reconinter.h"
 +
  #include "vp9/decoder/vp9_dthread.h"
 -#include "vp9/decoder/vp9_onyxd_int.h"
 -#include "vpx_mem/vpx_mem.h"
 +#include "vp9/decoder/vp9_onyxd.h"
  
  #if CONFIG_MULTITHREAD
  static INLINE void mutex_lock(pthread_mutex_t *const mutex) {
@@@ -107,7 -104,7 +107,7 @@@ static void loop_filter_rows_mt(const Y
  
        sync_read(lf_sync, r, c);
  
-       setup_dst_planes(xd, frame_buffer, mi_row, mi_col);
+       vp9_setup_dst_planes(xd, frame_buffer, mi_row, mi_col);
        vp9_setup_mask(cm, mi_row, mi_col, mi_8x8 + mi_col, cm->mode_info_stride,
                       &lfm);
  
@@@ -607,7 -607,7 +607,7 @@@ static void set_offsets(VP9_COMP *cpi, 
    mbmi = &xd->mi_8x8[0]->mbmi;
  
    // Set up destination pointers
-   setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
+   vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), mi_row, mi_col);
  
    // Set up limit values for MV components
    // mv beyond the range do not produce new/different prediction block
@@@ -2010,6 -2010,7 +2010,6 @@@ static void encode_rd_sb_row(VP9_COMP *
        const int idx_str = cm->mode_info_stride * mi_row + mi_col;
        MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
        MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
 -
        cpi->mb.source_variance = UINT_MAX;
        if (cpi->sf.partition_search_type == FIXED_PARTITION) {
          set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64);
@@@ -2082,8 -2083,9 +2082,9 @@@ static void init_encode_frame_mb_contex
    vp9_setup_src_planes(x, cpi->Source, 0, 0);
  
    // TODO(jkoleszar): are these initializations required?
-   setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0, NULL);
-   setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0);
+   vp9_setup_pre_planes(xd, 0, get_ref_frame_buffer(cpi, LAST_FRAME), 0, 0,
+                        NULL);
+   vp9_setup_dst_planes(xd, get_frame_new_buffer(cm), 0, 0);
  
    vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
  
@@@ -2295,13 -2297,19 +2296,13 @@@ typedef enum 
  
  static void set_mode_info(MB_MODE_INFO *mbmi, BLOCK_SIZE bsize,
                            MB_PREDICTION_MODE mode) {
 -  mbmi->interp_filter = EIGHTTAP;
    mbmi->mode = mode;
 +  mbmi->uv_mode = mode;
    mbmi->mv[0].as_int = 0;
    mbmi->mv[1].as_int = 0;
 -  if (mode < NEARESTMV) {
 -    mbmi->ref_frame[0] = INTRA_FRAME;
 -  } else {
 -    mbmi->ref_frame[0] = LAST_FRAME;
 -  }
 -
 -  mbmi->ref_frame[1] = INTRA_FRAME;
 +  mbmi->ref_frame[0] = INTRA_FRAME;
 +  mbmi->ref_frame[1] = NONE;
    mbmi->tx_size = max_txsize_lookup[bsize];
 -  mbmi->uv_mode = mode;
    mbmi->skip = 0;
    mbmi->sb_type = bsize;
    mbmi->segment_id = 0;
@@@ -2425,9 -2433,6 +2426,9 @@@ static void encode_frame_internal(VP9_C
    vp9_zero(cpi->coef_counts);
    vp9_zero(cm->counts.eob_branch);
  
 +  // Set frame level transform size use case
 +  select_tx_mode(cpi);
 +
    cpi->mb.e_mbd.lossless = cm->base_qindex == 0 && cm->y_dc_delta_q == 0
        && cm->uv_dc_delta_q == 0 && cm->uv_ac_delta_q == 0;
    switch_lossless_mode(cpi, cpi->mb.e_mbd.lossless);
  
    vp9_initialize_rd_consts(cpi);
    vp9_initialize_me_consts(cpi, cm->base_qindex);
 -  switch_tx_mode(cpi);
  
    if (cpi->oxcf.tuning == VP8_TUNE_SSIM) {
      // Initialize encode frame context.
            vp9_tile_init(&tile, cm, tile_row, tile_col);
            for (mi_row = tile.mi_row_start;
                 mi_row < tile.mi_row_end; mi_row += MI_BLOCK_SIZE) {
 -            if (cpi->sf.use_nonrd_pick_mode)
 +            if (cpi->sf.use_nonrd_pick_mode && cm->frame_type != KEY_FRAME)
                encode_nonrd_sb_row(cpi, &tile, mi_row, &tp);
              else
                encode_rd_sb_row(cpi, &tile, mi_row, &tp);
@@@ -2595,6 -2601,8 +2596,6 @@@ void vp9_encode_frame(VP9_COMP *cpi) 
  
      cpi->mb.e_mbd.lossless = cpi->oxcf.lossless;
  
 -    /* transform size selection (4x4, 8x8, 16x16 or select-per-mb) */
 -    select_tx_mode(cpi);
      cm->reference_mode = reference_mode;
  
      encode_frame_internal(cpi);
        }
      }
    } else {
 +    cpi->mb.e_mbd.lossless = cpi->oxcf.lossless;
 +    cm->reference_mode = SINGLE_REFERENCE;
      // Force the usage of the BILINEAR interp_filter.
      cm->interp_filter = BILINEAR;
      encode_frame_internal(cpi);
@@@ -2801,7 -2807,8 +2802,8 @@@ static void encode_superblock(VP9_COMP 
      for (ref = 0; ref < 1 + is_compound; ++ref) {
        YV12_BUFFER_CONFIG *cfg = get_ref_frame_buffer(cpi,
                                                       mbmi->ref_frame[ref]);
-       setup_pre_planes(xd, ref, cfg, mi_row, mi_col, &xd->block_refs[ref]->sf);
+       vp9_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
+                            &xd->block_refs[ref]->sf);
      }
      vp9_build_inter_predictors_sb(xd, mi_row, mi_col, MAX(bsize, BLOCK_8X8));
  
@@@ -20,7 -20,7 +20,7 @@@
  
  #include "vp9/common/vp9_entropymv.h"
  #include "vp9/common/vp9_quant_common.h"
- #include "vp9/common/vp9_reconinter.h"  // setup_dst_planes()
+ #include "vp9/common/vp9_reconinter.h"  // vp9_setup_dst_planes()
  #include "vp9/common/vp9_systemdependent.h"
  
  #include "vp9/encoder/vp9_block.h"
@@@ -95,7 -95,7 +95,7 @@@ static int kfboost_qadjust(int qindex) 
  // Resets the first pass file to the given position using a relative seek from
  // the current position.
  static void reset_fpf_position(struct twopass_rc *p,
 -                               FIRSTPASS_STATS *position) {
 +                               const FIRSTPASS_STATS *position) {
    p->stats_in = position;
  }
  
@@@ -415,8 -415,6 +415,8 @@@ static void first_pass_motion_search(VP
                                      x->sadperbit16, &num00, &v_fn_ptr,
                                      x->nmvjointcost,
                                      x->mvcost, ref_mv);
 +  if (tmp_err < INT_MAX)
 +    tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
    if (tmp_err < INT_MAX - new_mv_mode_penalty)
      tmp_err += new_mv_mode_penalty;
  
                                          &num00, &v_fn_ptr,
                                          x->nmvjointcost,
                                          x->mvcost, ref_mv);
 +      if (tmp_err < INT_MAX)
 +        tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
        if (tmp_err < INT_MAX - new_mv_mode_penalty)
          tmp_err += new_mv_mode_penalty;
  
@@@ -504,8 -500,8 +504,8 @@@ void vp9_first_pass(VP9_COMP *cpi) 
    vp9_clear_system_state();
  
    vp9_setup_src_planes(x, cpi->Source, 0, 0);
-   setup_pre_planes(xd, 0, lst_yv12, 0, 0, NULL);
-   setup_dst_planes(xd, new_yv12, 0, 0);
+   vp9_setup_pre_planes(xd, 0, lst_yv12, 0, 0, NULL);
+   vp9_setup_dst_planes(xd, new_yv12, 0, 0);
  
    xd->mi_8x8 = cm->mi_grid_visible;
    xd->mi_8x8[0] = cm->mi;
            mv.as_mv.row *= 8;
            mv.as_mv.col *= 8;
            this_error = motion_error;
 -          vp9_set_mbmode_and_mvs(xd, NEWMV, &mv.as_mv);
 +          xd->mi_8x8[0]->mbmi.mode = NEWMV;
 +          xd->mi_8x8[0]->mbmi.mv[0] = mv;
            xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
            xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME;
            xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE;
@@@ -903,7 -898,7 +903,7 @@@ extern void vp9_new_framerate(VP9_COMP 
  
  void vp9_init_second_pass(VP9_COMP *cpi) {
    FIRSTPASS_STATS this_frame;
 -  FIRSTPASS_STATS *start_pos;
 +  const FIRSTPASS_STATS *start_pos;
    struct twopass_rc *const twopass = &cpi->twopass;
    const VP9_CONFIG *const oxcf = &cpi->oxcf;
  
@@@ -1011,7 -1006,7 +1011,7 @@@ static int detect_transition_to_still(V
        loop_decay_rate >= 0.999 &&
        last_decay_rate < 0.9) {
      int j;
 -    FIRSTPASS_STATS *position = cpi->twopass.stats_in;
 +    const FIRSTPASS_STATS *position = cpi->twopass.stats_in;
      FIRSTPASS_STATS tmp_next_frame;
  
      // Look ahead a few frames to see if static condition persists...
@@@ -1346,7 -1341,7 +1346,7 @@@ void define_fixed_arf_period(VP9_COMP *
  // Analyse and define a gf/arf group.
  static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
    FIRSTPASS_STATS next_frame = { 0 };
 -  FIRSTPASS_STATS *start_pos;
 +  const FIRSTPASS_STATS *start_pos;
    struct twopass_rc *const twopass = &cpi->twopass;
    int i;
    double boost_score = 0.0;
@@@ -1793,12 -1788,19 +1793,12 @@@ static int test_candidate_kf(VP9_COMP *
           ((next_frame->intra_error /
             DOUBLE_DIVIDE_CHECK(next_frame->coded_error)) > 3.5))))) {
      int i;
 -    FIRSTPASS_STATS *start_pos;
 -
 -    FIRSTPASS_STATS local_next_frame;
 -
 +    const FIRSTPASS_STATS *start_pos = cpi->twopass.stats_in;
 +    FIRSTPASS_STATS local_next_frame = *next_frame;
      double boost_score = 0.0;
      double old_boost_score = 0.0;
      double decay_accumulator = 1.0;
  
 -    local_next_frame = *next_frame;
 -
 -    // Note the starting file position so we can reset to it.
 -    start_pos = cpi->twopass.stats_in;
 -
      // Examine how well the key frame predicts subsequent frames.
      for (i = 0; i < 16; ++i) {
        double next_iiratio = (IIKFACTOR1 * local_next_frame.intra_error /
@@@ -1854,7 -1856,7 +1854,7 @@@ static void find_next_key_frame(VP9_COM
    FIRSTPASS_STATS last_frame;
    FIRSTPASS_STATS first_frame;
    FIRSTPASS_STATS next_frame;
 -  FIRSTPASS_STATS *start_position;
 +  const FIRSTPASS_STATS *start_position;
  
    double decay_accumulator = 1.0;
    double zero_motion_accumulator = 1.0;
@@@ -34,11 -34,11 +34,11 @@@ static int full_pixel_motion_search(VP9
    MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
    struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
    int bestsme = INT_MAX;
 -  int further_steps, step_param;
 +  int step_param;
    int sadpb = x->sadperbit16;
    MV mvp_full;
    int ref = mbmi->ref_frame[0];
 -  int_mv ref_mv = mbmi->ref_mvs[ref][0];
 +  const MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
    int i;
  
    int tmp_col_min = x->mv_col_min;
      for (i = 0; i < MAX_MB_PLANE; i++)
        backup_yv12[i] = xd->plane[i].pre[0];
  
-     setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
+     vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
    }
  
 -  vp9_set_mv_search_range(x, &ref_mv.as_mv);
 +  vp9_set_mv_search_range(x, &ref_mv);
  
    // TODO(jingning) exploiting adaptive motion search control in non-RD
    // mode decision too.
    step_param = 6;
 -  further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
  
    for (i = LAST_FRAME; i <= LAST_FRAME && cpi->common.show_frame; ++i) {
      if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
    mvp_full.row >>= 3;
  
    if (cpi->sf.search_method == FAST_HEX) {
 -    bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb,
 -                                  &cpi->fn_ptr[bsize], 1,
 -                                  &ref_mv.as_mv, &tmp_mv->as_mv);
 +    // NOTE: this returns SAD
 +    vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
 +                        &cpi->fn_ptr[bsize], 1,
 +                        &ref_mv, &tmp_mv->as_mv);
    } else if (cpi->sf.search_method == HEX) {
 -    bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
 -                             &cpi->fn_ptr[bsize], 1,
 -                             &ref_mv.as_mv, &tmp_mv->as_mv);
 +    // NOTE: this returns SAD
 +    vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
 +                   &cpi->fn_ptr[bsize], 1,
 +                   &ref_mv, &tmp_mv->as_mv);
    } else if (cpi->sf.search_method == SQUARE) {
 -    bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
 -                                &cpi->fn_ptr[bsize], 1,
 -                                &ref_mv.as_mv, &tmp_mv->as_mv);
 +    // NOTE: this returns SAD
 +    vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
 +                      &cpi->fn_ptr[bsize], 1,
 +                      &ref_mv, &tmp_mv->as_mv);
    } else if (cpi->sf.search_method == BIGDIA) {
 -    bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
 -                                &cpi->fn_ptr[bsize], 1,
 -                                &ref_mv.as_mv, &tmp_mv->as_mv);
 +    // NOTE: this returns SAD
 +    vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
 +                      &cpi->fn_ptr[bsize], 1,
 +                      &ref_mv, &tmp_mv->as_mv);
    } else {
 -    bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
 -                                     sadpb, further_steps, 1,
 -                                     &cpi->fn_ptr[bsize],
 -                                     &ref_mv.as_mv, &tmp_mv->as_mv);
 +    int further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
 +    // NOTE: this returns variance
 +    vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
 +                           sadpb, further_steps, 1,
 +                           &cpi->fn_ptr[bsize],
 +                           &ref_mv, &tmp_mv->as_mv);
    }
    x->mv_col_min = tmp_col_min;
    x->mv_col_max = tmp_col_max;
    tmp_mv->as_mv.col = tmp_mv->as_mv.col * 8;
  
    // calculate the bit cost on motion vector
 -  *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv,
 +  *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
                               x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
    return bestsme;
  }
@@@ -165,7 -160,7 +165,7 @@@ static void sub_pixel_motion_search(VP9
      for (i = 0; i < MAX_MB_PLANE; i++)
        backup_yv12[i] = xd->plane[i].pre[0];
  
-     setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
+     vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
    }
  
    tmp_mv->col >>= 3;
    }
  }
  
 +static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize,
 +                              MACROBLOCK *x, MACROBLOCKD *xd,
 +                              int *out_rate_sum, int64_t *out_dist_sum) {
 +  // Note our transform coeffs are 8 times an orthogonal transform.
 +  // Hence quantizer step is also 8 times. To get effective quantizer
 +  // we need to divide by 8 before sending to modeling function.
 +  unsigned int sse;
 +  int rate;
 +  int64_t dist;
 +
 +
 +  struct macroblock_plane *const p = &x->plane[0];
 +  struct macroblockd_plane *const pd = &xd->plane[0];
 +  const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
 +
 +  (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
 +                            pd->dst.buf, pd->dst.stride, &sse);
 +
 +  vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
 +                               pd->dequant[1] >> 3, &rate, &dist);
 +
 +  *out_rate_sum = rate;
 +  *out_dist_sum = dist << 4;
 +}
 +
  // TODO(jingning) placeholder for inter-frame non-RD mode decision.
  // this needs various further optimizations. to be continued..
  int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
                                      VP9_ALT_FLAG };
    int64_t best_rd = INT64_MAX;
    int64_t this_rd = INT64_MAX;
 -  static const int cost[4]= { 0, 2, 4, 6 };
  
    const int64_t inter_mode_thresh = 300;
    const int64_t intra_mode_cost = 50;
  
 +  int rate = INT_MAX;
 +  int64_t dist = INT64_MAX;
 +
    x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
  
    x->skip = 0;
    }
  
    for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
 -    int rate_mv = 0;
      if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
        continue;
  
      mbmi->ref_frame[0] = ref_frame;
  
      for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
 -      int rate = cost[INTER_OFFSET(this_mode)]
 -          << (num_pels_log2_lookup[bsize] - 4);
 -      int64_t dist;
 +      int rate_mv = 0;
 +
        if (cpi->sf.disable_inter_mode_mask[bsize] &
            (1 << INTER_OFFSET(this_mode)))
          continue;
                                  &frame_mv[NEWMV][ref_frame].as_mv);
        }
  
 -      if (frame_mv[this_mode][ref_frame].as_int == 0) {
 -        dist = x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)];
 -      } else if (this_mode != NEARESTMV &&
 -                 frame_mv[NEARESTMV][ref_frame].as_int ==
 -                     frame_mv[this_mode][ref_frame].as_int) {
 -        dist = x->mode_sad[ref_frame][INTER_OFFSET(NEARESTMV)];
 -      } else {
 -        mbmi->mode = this_mode;
 -        mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
 -        vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
 -        dist = x->mode_sad[ref_frame][INTER_OFFSET(this_mode)] =
 -            cpi->fn_ptr[bsize].sdf(p->src.buf, p->src.stride,
 -                                   pd->dst.buf, pd->dst.stride, INT_MAX);
 -      }
 +      if (this_mode != NEARESTMV)
 +        if (frame_mv[this_mode][ref_frame].as_int ==
 +            frame_mv[NEARESTMV][ref_frame].as_int)
 +          continue;
  
 -      this_rd = rate + dist;
 +      mbmi->mode = this_mode;
 +      mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
 +      vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
 +
 +      model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
 +      rate += rate_mv;
 +      rate += x->inter_mode_cost[mbmi->mode_context[ref_frame]]
 +                                [INTER_OFFSET(this_mode)];
 +      this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
  
        if (this_rd < best_rd) {
          best_rd = this_rd;
                                &p->src.buf[0], p->src.stride,
                                &pd->dst.buf[0], pd->dst.stride, 0, 0, 0);
  
 -      this_rd = cpi->fn_ptr[bsize].sdf(p->src.buf,
 -                                       p->src.stride,
 -                                       pd->dst.buf,
 -                                       pd->dst.stride, INT_MAX);
 +      model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
 +      rate += x->mbmode_cost[this_mode];
 +      this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
  
        if (this_rd + intra_mode_cost < best_rd) {
          best_rd = this_rd;
        }
      }
    }
 +
    return INT64_MAX;
  }
diff --combined vp9/encoder/vp9_rdopt.c
@@@ -30,7 -30,6 +30,7 @@@
  #include "vp9/common/vp9_seg_common.h"
  #include "vp9/common/vp9_systemdependent.h"
  
 +#include "vp9/encoder/vp9_cost.h"
  #include "vp9/encoder/vp9_encodemb.h"
  #include "vp9/encoder/vp9_encodemv.h"
  #include "vp9/encoder/vp9_mcomp.h"
@@@ -39,6 -38,7 +39,6 @@@
  #include "vp9/encoder/vp9_ratectrl.h"
  #include "vp9/encoder/vp9_rdopt.h"
  #include "vp9/encoder/vp9_tokenize.h"
 -#include "vp9/encoder/vp9_treewriter.h"
  #include "vp9/encoder/vp9_variance.h"
  
  /* Factor to weigh the rate for switchable interp filters */
@@@ -157,10 -157,10 +157,10 @@@ static void fill_mode_costs(VP9_COMP *c
  
    // TODO(rbultje) separate tables for superblock costing?
    vp9_cost_tokens(x->mbmode_cost, fc->y_mode_prob[1], vp9_intra_mode_tree);
 -  vp9_cost_tokens(x->intra_uv_mode_cost[1],
 -                  fc->uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree);
 -  vp9_cost_tokens(x->intra_uv_mode_cost[0],
 -                  vp9_kf_uv_mode_prob[INTRA_MODES - 1], vp9_intra_mode_tree);
 +  vp9_cost_tokens(x->intra_uv_mode_cost[KEY_FRAME],
 +                  vp9_kf_uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
 +  vp9_cost_tokens(x->intra_uv_mode_cost[INTER_FRAME],
 +                  fc->uv_mode_prob[TM_PRED], vp9_intra_mode_tree);
  
    for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; ++i)
      vp9_cost_tokens((int *)x->switchable_interp_costs[i],
@@@ -282,12 -282,14 +282,12 @@@ void vp9_initialize_rd_consts(VP9_COMP 
    x->errorperbit = cpi->RDMULT / RD_MULT_EPB_RATIO;
    x->errorperbit += (x->errorperbit == 0);
  
 -  vp9_set_speed_features(cpi);
 -
    x->select_txfm_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
                           cm->frame_type != KEY_FRAME) ? 0 : 1;
  
    set_block_thresholds(cpi);
  
 -  if (!cpi->sf.use_nonrd_pick_mode) {
 +  if (!cpi->sf.use_nonrd_pick_mode || cm->frame_type == KEY_FRAME) {
      fill_token_costs(x->token_costs, cm->fc.coef_probs);
  
      for (i = 0; i < PARTITION_CONTEXTS; i++)
                        vp9_partition_tree);
    }
  
 -  if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1) {
 +  if (!cpi->sf.use_nonrd_pick_mode || (cm->current_video_frame & 0x07) == 1 ||
 +      cm->frame_type == KEY_FRAME) {
      fill_mode_costs(cpi);
  
      if (!frame_is_intra_only(cm)) {
@@@ -395,9 -396,9 +395,9 @@@ static void model_rd_norm(int xsq_q10, 
    *d_q10 = (dist_tab_q10[xq] * b_q10 + dist_tab_q10[xq + 1] * a_q10) >> 10;
  }
  
 -static void model_rd_from_var_lapndz(unsigned int var, unsigned int n,
 -                                     unsigned int qstep, int *rate,
 -                                     int64_t *dist) {
 +void vp9_model_rd_from_var_lapndz(unsigned int var, unsigned int n,
 +                                  unsigned int qstep, int *rate,
 +                                  int64_t *dist) {
    // This function models the rate and distortion for a Laplacian
    // source with given variance when quantized with a uniform quantizer
    // with given stepsize. The closed form expressions are in:
@@@ -459,8 -460,8 +459,8 @@@ static void model_rd_for_sb(VP9_COMP *c
      } else {
        int rate;
        int64_t dist;
 -      model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
 -                               pd->dequant[1] >> 3, &rate, &dist);
 +      vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
 +                                   pd->dequant[1] >> 3, &rate, &dist);
        rate_sum += rate;
        dist_sum += dist;
      }
@@@ -507,8 -508,7 +507,8 @@@ static void model_rd_for_sb_y_tx(VP9_CO
                           &pd->dst.buf[j * pd->dst.stride + k], pd->dst.stride,
                           &sse);
        // sse works better than var, since there is no dc prediction used
 -      model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3, &rate, &dist);
 +      vp9_model_rd_from_var_lapndz(sse, t * t, pd->dequant[1] >> 3,
 +                                   &rate, &dist);
        rate_sum += rate;
        dist_sum += dist;
        *out_skip &= (rate < 1024);
@@@ -1037,7 -1037,7 +1037,7 @@@ static int conditional_skipintra(MB_PRE
  
  static int64_t rd_pick_intra4x4block(VP9_COMP *cpi, MACROBLOCK *x, int ib,
                                       MB_PREDICTION_MODE *best_mode,
 -                                     int *bmode_costs,
 +                                     const int *bmode_costs,
                                       ENTROPY_CONTEXT *a, ENTROPY_CONTEXT *l,
                                       int *bestrate, int *bestratey,
                                       int64_t *bestdistortion,
    return best_rd;
  }
  
 -static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP * const cpi,
 -                                            MACROBLOCK * const mb,
 -                                            int * const rate,
 -                                            int * const rate_y,
 -                                            int64_t * const distortion,
 +static int64_t rd_pick_intra_sub_8x8_y_mode(VP9_COMP *cpi, MACROBLOCK *mb,
 +                                            int *rate, int *rate_y,
 +                                            int64_t *distortion,
                                              int64_t best_rd) {
    int i, j;
 -  MACROBLOCKD *const xd = &mb->e_mbd;
 +  const MACROBLOCKD *const xd = &mb->e_mbd;
    MODE_INFO *const mic = xd->mi_8x8[0];
    const MODE_INFO *above_mi = xd->mi_8x8[-xd->mode_info_stride];
    const MODE_INFO *left_mi = xd->left_available ? xd->mi_8x8[-1] : NULL;
    int tot_rate_y = 0;
    int64_t total_rd = 0;
    ENTROPY_CONTEXT t_above[4], t_left[4];
 -  int *bmode_costs;
 +  const int *bmode_costs = mb->mbmode_cost;
  
    vpx_memcpy(t_above, xd->plane[0].above_context, sizeof(t_above));
    vpx_memcpy(t_left, xd->plane[0].left_context, sizeof(t_left));
  
 -  bmode_costs = mb->mbmode_cost;
 -
    // Pick modes for each sub-block (of size 4x4, 4x8, or 8x4) in an 8x8 block.
    for (idy = 0; idy < 2; idy += num_4x4_blocks_high) {
      for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
@@@ -1459,6 -1463,12 +1459,6 @@@ static int cost_mv_ref(VP9_COMP *cpi, M
    }
  }
  
 -void vp9_set_mbmode_and_mvs(MACROBLOCKD *xd, MB_PREDICTION_MODE mode,
 -                            const MV *mv) {
 -  xd->mi_8x8[0]->mbmi.mode = mode;
 -  xd->mi_8x8[0]->mbmi.mv[0].as_mv = *mv;
 -}
 -
  static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
                                  BLOCK_SIZE bsize,
                                  int_mv *frame_mv,
                                  int_mv single_newmv[MAX_REF_FRAMES],
                                  int *rate_mv);
  
 -static int labels2mode(MACROBLOCK *x, int i,
 +static int labels2mode(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
                         MB_PREDICTION_MODE mode,
 -                       int_mv *this_mv, int_mv *this_second_mv,
 +                       int_mv this_mv[2],
                         int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
                         int_mv seg_mvs[MAX_REF_FRAMES],
 -                       int_mv *best_ref_mv,
 -                       int_mv *second_best_ref_mv,
 -                       int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
 -  MACROBLOCKD *const xd = &x->e_mbd;
 +                       int_mv *best_ref_mv[2],
 +                       const int *mvjcost, int *mvcost[2]) {
    MODE_INFO *const mic = xd->mi_8x8[0];
 -  MB_MODE_INFO *mbmi = &mic->mbmi;
 +  const MB_MODE_INFO *const mbmi = &mic->mbmi;
    int thismvcost = 0;
    int idx, idy;
    const int num_4x4_blocks_wide = num_4x4_blocks_wide_lookup[mbmi->sb_type];
    const int num_4x4_blocks_high = num_4x4_blocks_high_lookup[mbmi->sb_type];
 -  const int has_second_rf = has_second_ref(mbmi);
 +  const int is_compound = has_second_ref(mbmi);
  
    // the only time we should do costing for new motion vector or mode
    // is when we are on a new label  (jbb May 08, 2007)
    switch (mode) {
      case NEWMV:
 -      this_mv->as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
 -      thismvcost += vp9_mv_bit_cost(&this_mv->as_mv, &best_ref_mv->as_mv,
 +      this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
 +      thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
                                      mvjcost, mvcost, MV_COST_WEIGHT_SUB);
 -      if (has_second_rf) {
 -        this_second_mv->as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
 -        thismvcost += vp9_mv_bit_cost(&this_second_mv->as_mv,
 -                                      &second_best_ref_mv->as_mv,
 +      if (is_compound) {
 +        this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
 +        thismvcost += vp9_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
                                        mvjcost, mvcost, MV_COST_WEIGHT_SUB);
        }
        break;
      case NEARESTMV:
 -      this_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
 -      if (has_second_rf)
 -        this_second_mv->as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
 +      this_mv[0].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[0]].as_int;
 +      if (is_compound)
 +        this_mv[1].as_int = frame_mv[NEARESTMV][mbmi->ref_frame[1]].as_int;
        break;
      case NEARMV:
 -      this_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
 -      if (has_second_rf)
 -        this_second_mv->as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
 +      this_mv[0].as_int = frame_mv[NEARMV][mbmi->ref_frame[0]].as_int;
 +      if (is_compound)
 +        this_mv[1].as_int = frame_mv[NEARMV][mbmi->ref_frame[1]].as_int;
        break;
      case ZEROMV:
 -      this_mv->as_int = 0;
 -      if (has_second_rf)
 -        this_second_mv->as_int = 0;
 +      this_mv[0].as_int = 0;
 +      if (is_compound)
 +        this_mv[1].as_int = 0;
        break;
      default:
        break;
    }
  
 -  mic->bmi[i].as_mv[0].as_int = this_mv->as_int;
 -  if (has_second_rf)
 -    mic->bmi[i].as_mv[1].as_int = this_second_mv->as_int;
 +  mic->bmi[i].as_mv[0].as_int = this_mv[0].as_int;
 +  if (is_compound)
 +    mic->bmi[i].as_mv[1].as_int = this_mv[1].as_int;
  
    mic->bmi[i].as_mode = mode;
  
@@@ -1691,7 -1704,6 +1691,7 @@@ static void rd_check_segment_txsize(VP9
    int mode_idx;
    int subpelmv = 1, have_ref = 0;
    const int has_second_rf = has_second_ref(mbmi);
 +  const int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
  
    vpx_memcpy(t_above, pd->above_context, sizeof(t_above));
    vpx_memcpy(t_left, pd->left_context, sizeof(t_left));
      for (idx = 0; idx < 2; idx += num_4x4_blocks_wide) {
        // TODO(jingning,rbultje): rewrite the rate-distortion optimization
        // loop for 4x4/4x8/8x4 block coding. to be replaced with new rd loop
 -      int_mv mode_mv[MB_MODE_COUNT], second_mode_mv[MB_MODE_COUNT];
 +      int_mv mode_mv[MB_MODE_COUNT][2];
        int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
        MB_PREDICTION_MODE mode_selected = ZEROMV;
        int64_t best_rd = INT64_MAX;
  
          mode_idx = INTER_OFFSET(this_mode);
          bsi->rdstat[i][mode_idx].brdcost = INT64_MAX;
 -        if (cpi->sf.disable_inter_mode_mask[bsize] & (1 << mode_idx))
 +        if (disable_inter_mode_mask & (1 << mode_idx))
            continue;
  
          // if we're near/nearest and mv == 0,0, compare to zeromv
 -        if ((this_mode == NEARMV || this_mode == NEARESTMV ||
 +        if (!(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
 +            (this_mode == NEARMV || this_mode == NEARESTMV ||
               this_mode == ZEROMV) &&
              frame_mv[this_mode][mbmi->ref_frame[0]].as_int == 0 &&
              (!has_second_rf ||
          // motion search for newmv (single predictor case only)
          if (!has_second_rf && this_mode == NEWMV &&
              seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV) {
 -          int_mv *const new_mv = &mode_mv[NEWMV];
 +          int_mv *const new_mv = &mode_mv[NEWMV][0];
            int step_param = 0;
            int further_steps;
            int thissme, bestsme = INT_MAX;
                                       sadpb, 1, v_fn_ptr, 1,
                                       &bsi->ref_mv[0]->as_mv,
                                       &new_mv->as_mv);
 +            if (bestsme < INT_MAX)
 +              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
 +                                           &bsi->ref_mv[0]->as_mv,
 +                                           v_fn_ptr, 1);
            } else if (cpi->sf.search_method == SQUARE) {
              bestsme = vp9_square_search(x, &mvp_full,
                                          step_param,
                                          sadpb, 1, v_fn_ptr, 1,
                                          &bsi->ref_mv[0]->as_mv,
                                          &new_mv->as_mv);
 +            if (bestsme < INT_MAX)
 +              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
 +                                           &bsi->ref_mv[0]->as_mv,
 +                                           v_fn_ptr, 1);
            } else if (cpi->sf.search_method == BIGDIA) {
              bestsme = vp9_bigdia_search(x, &mvp_full,
                                          step_param,
                                          sadpb, 1, v_fn_ptr, 1,
                                          &bsi->ref_mv[0]->as_mv,
                                          &new_mv->as_mv);
 +            if (bestsme < INT_MAX)
 +              bestsme = vp9_get_mvpred_var(x, &new_mv->as_mv,
 +                                           &bsi->ref_mv[0]->as_mv,
 +                                           v_fn_ptr, 1);
            } else {
              bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
                                               sadpb, further_steps, 0, v_fn_ptr,
          }
  
          bsi->rdstat[i][mode_idx].brate =
 -            labels2mode(x, i, this_mode, &mode_mv[this_mode],
 -                        &second_mode_mv[this_mode], frame_mv, seg_mvs[i],
 -                        bsi->ref_mv[0], bsi->ref_mv[1], x->nmvjointcost,
 -                        x->mvcost, cpi);
 -
 -
 -        bsi->rdstat[i][mode_idx].mvs[0].as_int = mode_mv[this_mode].as_int;
 -        if (num_4x4_blocks_wide > 1)
 -          bsi->rdstat[i + 1][mode_idx].mvs[0].as_int =
 -              mode_mv[this_mode].as_int;
 -        if (num_4x4_blocks_high > 1)
 -          bsi->rdstat[i + 2][mode_idx].mvs[0].as_int =
 -              mode_mv[this_mode].as_int;
 -        if (has_second_rf) {
 -          bsi->rdstat[i][mode_idx].mvs[1].as_int =
 -              second_mode_mv[this_mode].as_int;
 +            labels2mode(cpi, xd, i, this_mode, mode_mv[this_mode], frame_mv,
 +                        seg_mvs[i], bsi->ref_mv, x->nmvjointcost, x->mvcost);
 +
 +        for (ref = 0; ref < 1 + has_second_rf; ++ref) {
 +          bsi->rdstat[i][mode_idx].mvs[ref].as_int =
 +              mode_mv[this_mode][ref].as_int;
            if (num_4x4_blocks_wide > 1)
 -            bsi->rdstat[i + 1][mode_idx].mvs[1].as_int =
 -                second_mode_mv[this_mode].as_int;
 +            bsi->rdstat[i + 1][mode_idx].mvs[ref].as_int =
 +                mode_mv[this_mode][ref].as_int;
            if (num_4x4_blocks_high > 1)
 -            bsi->rdstat[i + 2][mode_idx].mvs[1].as_int =
 -                second_mode_mv[this_mode].as_int;
 +            bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
 +                mode_mv[this_mode][ref].as_int;
          }
  
          // Trap vectors that reach beyond the UMV borders
 -        if (mv_check_bounds(x, &mode_mv[this_mode].as_mv) ||
 +        if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
              (has_second_rf &&
 -             mv_check_bounds(x, &second_mode_mv[this_mode].as_mv)))
 +             mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
            continue;
  
          if (filter_idx > 0) {
            BEST_SEG_INFO *ref_bsi = bsi_buf;
 -          subpelmv = mv_has_subpel(&mode_mv[this_mode].as_mv);
 -          have_ref = mode_mv[this_mode].as_int ==
 -                         ref_bsi->rdstat[i][mode_idx].mvs[0].as_int;
 -          if (has_second_rf) {
 -            subpelmv |= mv_has_subpel(&second_mode_mv[this_mode].as_mv);
 -            have_ref &= second_mode_mv[this_mode].as_int ==
 -                            ref_bsi->rdstat[i][mode_idx].mvs[1].as_int;
 +          subpelmv = 0;
 +          have_ref = 1;
 +
 +          for (ref = 0; ref < 1 + has_second_rf; ++ref) {
 +            subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
 +            have_ref &= mode_mv[this_mode][ref].as_int ==
 +                ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
            }
  
            if (filter_idx > 1 && !subpelmv && !have_ref) {
              ref_bsi = bsi_buf + 1;
 -            have_ref = mode_mv[this_mode].as_int ==
 -                       ref_bsi->rdstat[i][mode_idx].mvs[0].as_int;
 -            if (has_second_rf) {
 -              have_ref  &= second_mode_mv[this_mode].as_int ==
 -                           ref_bsi->rdstat[i][mode_idx].mvs[1].as_int;
 -            }
 +            have_ref = 1;
 +            for (ref = 0; ref < 1 + has_second_rf; ++ref)
 +              have_ref &= mode_mv[this_mode][ref].as_int ==
 +                  ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
            }
  
            if (!subpelmv && have_ref &&
        vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
        vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
  
 -      labels2mode(x, i, mode_selected, &mode_mv[mode_selected],
 -                  &second_mode_mv[mode_selected], frame_mv, seg_mvs[i],
 -                  bsi->ref_mv[0], bsi->ref_mv[1], x->nmvjointcost,
 -                  x->mvcost, cpi);
 +      labels2mode(cpi, xd, i, mode_selected, mode_mv[mode_selected],
 +                  frame_mv, seg_mvs[i], bsi->ref_mv, x->nmvjointcost,
 +                  x->mvcost);
  
        br += bsi->rdstat[i][mode_idx].brate;
        bd += bsi->rdstat[i][mode_idx].bdist;
@@@ -2401,7 -2413,7 +2401,7 @@@ static void single_motion_search(VP9_CO
      for (i = 0; i < MAX_MB_PLANE; i++)
        backup_yv12[i] = xd->plane[i].pre[0];
  
-     setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
+     vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
    }
  
    vp9_set_mv_search_range(x, &ref_mv);
    further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
  
    if (cpi->sf.search_method == FAST_HEX) {
 -    bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb,
 +    bestsme = vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
                                    &cpi->fn_ptr[bsize], 1,
                                    &ref_mv, &tmp_mv->as_mv);
 +    if (bestsme < INT_MAX)
 +      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
 +                                   &cpi->fn_ptr[bsize], 1);
    } else if (cpi->sf.search_method == HEX) {
      bestsme = vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
                               &cpi->fn_ptr[bsize], 1,
                               &ref_mv, &tmp_mv->as_mv);
 +    if (bestsme < INT_MAX)
 +      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
 +                                   &cpi->fn_ptr[bsize], 1);
    } else if (cpi->sf.search_method == SQUARE) {
      bestsme = vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
                                  &cpi->fn_ptr[bsize], 1,
                                  &ref_mv, &tmp_mv->as_mv);
 +    if (bestsme < INT_MAX)
 +      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
 +                                   &cpi->fn_ptr[bsize], 1);
    } else if (cpi->sf.search_method == BIGDIA) {
      bestsme = vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
                                  &cpi->fn_ptr[bsize], 1,
                                  &ref_mv, &tmp_mv->as_mv);
 +    if (bestsme < INT_MAX)
 +      bestsme = vp9_get_mvpred_var(x, &tmp_mv->as_mv, &ref_mv,
 +                                   &cpi->fn_ptr[bsize], 1);
    } else {
      bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
                                       sadpb, further_steps, 1,
@@@ -2557,7 -2557,8 +2557,8 @@@ static void joint_motion_search(VP9_COM
        // motion search code to be used without additional modifications.
        for (i = 0; i < MAX_MB_PLANE; i++)
          backup_yv12[ref][i] = xd->plane[i].pre[ref];
-       setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col, NULL);
+       vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
+                            NULL);
      }
  
      frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
                                         x->nmvjointcost, x->mvcost,
                                         &ref_mv[id].as_mv, second_pred,
                                         pw, ph);
 +    if (bestsme < INT_MAX)
 +      bestsme = vp9_get_mvpred_av_var(x, &tmp_mv.as_mv, &ref_mv[id].as_mv,
 +                                      second_pred, &cpi->fn_ptr[bsize], 1);
  
      x->mv_col_min = tmp_col_min;
      x->mv_col_max = tmp_col_max;
@@@ -3160,7 -3158,6 +3161,7 @@@ int64_t vp9_rd_pick_inter_mode_sb(VP9_C
    const int mode_search_skip_flags = cpi->sf.mode_search_skip_flags;
    const int intra_y_mode_mask =
        cpi->sf.intra_y_mode_mask[max_txsize_lookup[bsize]];
 +  const int disable_inter_mode_mask = cpi->sf.disable_inter_mode_mask[bsize];
  
    x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
  
      mode_skip_mask |= new_modes_mask;
    }
  
 +  if (bsize > cpi->sf.max_intra_bsize) {
 +    mode_skip_mask |= 0xFF30808;
 +  }
 +
    for (mode_index = 0; mode_index < MAX_MODES; ++mode_index) {
      int mode_excluded = 0;
      int64_t this_rd = INT64_MAX;
      this_mode = vp9_mode_order[mode_index].mode;
      ref_frame = vp9_mode_order[mode_index].ref_frame[0];
      if (ref_frame != INTRA_FRAME &&
 -        cpi->sf.disable_inter_mode_mask[bsize] & (1 << INTER_OFFSET(this_mode)))
 +        disable_inter_mode_mask & (1 << INTER_OFFSET(this_mode)))
        continue;
      second_ref_frame = vp9_mode_order[mode_index].ref_frame[1];
  
        }
      } else {
        // if we're near/nearest and mv == 0,0, compare to zeromv
 -      if ((this_mode == NEARMV || this_mode == NEARESTMV ||
 +      if (!(disable_inter_mode_mask & (1 << INTER_OFFSET(ZEROMV))) &&
 +          (this_mode == NEARMV || this_mode == NEARESTMV ||
            this_mode == ZEROMV) &&
            frame_mv[this_mode][ref_frame].as_int == 0 &&
            !vp9_segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP) &&