| Index: source/libvpx/vp9/encoder/vp9_rdopt.c
 | 
| ===================================================================
 | 
| --- source/libvpx/vp9/encoder/vp9_rdopt.c	(revision 291857)
 | 
| +++ source/libvpx/vp9/encoder/vp9_rdopt.c	(working copy)
 | 
| @@ -171,30 +171,53 @@
 | 
|    int64_t dist_sum = 0;
 | 
|    const int ref = xd->mi[0]->mbmi.ref_frame[0];
 | 
|    unsigned int sse;
 | 
| +  unsigned int var = 0;
 | 
| +  unsigned int sum_sse = 0;
 | 
|    const int shift = 8;
 | 
| +  int rate;
 | 
| +  int64_t dist;
 | 
|  
 | 
| +  x->pred_sse[ref] = 0;
 | 
| +
 | 
|    for (i = 0; i < MAX_MB_PLANE; ++i) {
 | 
|      struct macroblock_plane *const p = &x->plane[i];
 | 
|      struct macroblockd_plane *const pd = &xd->plane[i];
 | 
|      const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);
 | 
| +    const TX_SIZE max_tx_size = max_txsize_lookup[bs];
 | 
| +    const BLOCK_SIZE unit_size = txsize_to_bsize[max_tx_size];
 | 
| +    int bw = 1 << (b_width_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
 | 
| +    int bh = 1 << (b_height_log2_lookup[bs] - b_width_log2_lookup[unit_size]);
 | 
| +    int idx, idy;
 | 
| +    int lw = b_width_log2_lookup[unit_size] + 2;
 | 
| +    int lh = b_height_log2_lookup[unit_size] + 2;
 | 
|  
 | 
| -    const unsigned int var = cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
 | 
| -                                                pd->dst.buf, pd->dst.stride,
 | 
| -                                                &sse);
 | 
| +    sum_sse = 0;
 | 
|  
 | 
| -    if (!x->select_tx_size) {
 | 
| -      if (sse < p->quant_thred[0] >> shift)
 | 
| -        x->skip_txfm[i] = 1;
 | 
| -      else if (var < p->quant_thred[1] >> shift)
 | 
| -        x->skip_txfm[i] = 2;
 | 
| -      else
 | 
| -        x->skip_txfm[i] = 0;
 | 
| +    for (idy = 0; idy < bh; ++idy) {
 | 
| +      for (idx = 0; idx < bw; ++idx) {
 | 
| +        uint8_t *src = p->src.buf + (idy * p->src.stride << lh) + (idx << lw);
 | 
| +        uint8_t *dst = pd->dst.buf + (idy * pd->dst.stride << lh) + (idx << lh);
 | 
| +        int block_idx = (idy << 1) + idx;
 | 
| +
 | 
| +        var = cpi->fn_ptr[unit_size].vf(src, p->src.stride,
 | 
| +                                        dst, pd->dst.stride, &sse);
 | 
| +        x->bsse[(i << 2) + block_idx] = sse;
 | 
| +        sum_sse += sse;
 | 
| +
 | 
| +        if (!x->select_tx_size) {
 | 
| +          if (x->bsse[(i << 2) + block_idx] < p->quant_thred[0] >> shift)
 | 
| +            x->skip_txfm[(i << 2) + block_idx] = 1;
 | 
| +          else if (var < p->quant_thred[1] >> shift)
 | 
| +            x->skip_txfm[(i << 2) + block_idx] = 2;
 | 
| +          else
 | 
| +            x->skip_txfm[(i << 2) + block_idx] = 0;
 | 
| +        }
 | 
| +
 | 
| +        if (i == 0)
 | 
| +          x->pred_sse[ref] += sse;
 | 
| +      }
 | 
|      }
 | 
|  
 | 
| -    x->bsse[i] = sse;
 | 
| -    if (i == 0)
 | 
| -      x->pred_sse[ref] = sse;
 | 
| -
 | 
|      // Fast approximate the modelling function.
 | 
|      if (cpi->oxcf.speed > 4) {
 | 
|        int64_t rate;
 | 
| @@ -210,9 +233,7 @@
 | 
|        rate_sum += rate;
 | 
|        dist_sum += dist;
 | 
|      } else {
 | 
| -      int rate;
 | 
| -      int64_t dist;
 | 
| -      vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
 | 
| +      vp9_model_rd_from_var_lapndz(sum_sse, 1 << num_pels_log2_lookup[bs],
 | 
|                                     pd->dequant[1] >> 3, &rate, &dist);
 | 
|        rate_sum += rate;
 | 
|        dist_sum += dist;
 | 
| @@ -372,17 +393,17 @@
 | 
|    if (!is_inter_block(mbmi)) {
 | 
|      vp9_encode_block_intra(x, plane, block, plane_bsize, tx_size, &mbmi->skip);
 | 
|      dist_block(plane, block, tx_size, args);
 | 
| -  } else {
 | 
| -    if (x->skip_txfm[plane] == 0) {
 | 
| +  } else if (max_txsize_lookup[plane_bsize] == tx_size) {
 | 
| +    if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 0) {
 | 
|        // full forward transform and quantization
 | 
|        vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
 | 
|        dist_block(plane, block, tx_size, args);
 | 
| -    } else if (x->skip_txfm[plane] == 2) {
 | 
| +    } else if (x->skip_txfm[(plane << 2) + (block >> (tx_size << 1))] == 2) {
 | 
|        // compute DC coefficient
 | 
|        int16_t *const coeff   = BLOCK_OFFSET(x->plane[plane].coeff, block);
 | 
|        int16_t *const dqcoeff = BLOCK_OFFSET(xd->plane[plane].dqcoeff, block);
 | 
|        vp9_xform_quant_dc(x, plane, block, plane_bsize, tx_size);
 | 
| -      args->sse  = x->bsse[plane] << 4;
 | 
| +      args->sse  = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
 | 
|        args->dist = args->sse;
 | 
|        if (!x->plane[plane].eobs[block])
 | 
|          args->dist = args->sse - ((coeff[0] * coeff[0] -
 | 
| @@ -390,9 +411,13 @@
 | 
|      } else {
 | 
|        // skip forward transform
 | 
|        x->plane[plane].eobs[block] = 0;
 | 
| -      args->sse  = x->bsse[plane] << 4;
 | 
| +      args->sse  = x->bsse[(plane << 2) + (block >> (tx_size << 1))] << 4;
 | 
|        args->dist = args->sse;
 | 
|      }
 | 
| +  } else {
 | 
| +    // full forward transform and quantization
 | 
| +    vp9_xform_quant(x, plane, block, plane_bsize, tx_size);
 | 
| +    dist_block(plane, block, tx_size, args);
 | 
|    }
 | 
|  
 | 
|    rate_block(plane, block, plane_bsize, tx_size, args);
 | 
| @@ -468,7 +493,6 @@
 | 
|    txfm_rd_in_plane(x, rate, distortion, skip,
 | 
|                     sse, ref_best_rd, 0, bs,
 | 
|                     mbmi->tx_size, cpi->sf.use_fast_coef_costing);
 | 
| -  cpi->tx_stepdown_count[0]++;
 | 
|  }
 | 
|  
 | 
|  static void choose_tx_size_from_rd(VP9_COMP *cpi, MACROBLOCK *x,
 | 
| @@ -551,60 +575,36 @@
 | 
|  
 | 
|    if (max_tx_size == TX_32X32 && best_tx == TX_32X32) {
 | 
|      tx_cache[TX_MODE_SELECT] = rd[TX_32X32][1];
 | 
| -    cpi->tx_stepdown_count[0]++;
 | 
|    } else if (max_tx_size >= TX_16X16 && best_tx == TX_16X16) {
 | 
|      tx_cache[TX_MODE_SELECT] = rd[TX_16X16][1];
 | 
| -    cpi->tx_stepdown_count[max_tx_size - TX_16X16]++;
 | 
|    } else if (rd[TX_8X8][1] < rd[TX_4X4][1]) {
 | 
|      tx_cache[TX_MODE_SELECT] = rd[TX_8X8][1];
 | 
| -    cpi->tx_stepdown_count[max_tx_size - TX_8X8]++;
 | 
|    } else {
 | 
|      tx_cache[TX_MODE_SELECT] = rd[TX_4X4][1];
 | 
| -    cpi->tx_stepdown_count[max_tx_size - TX_4X4]++;
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -static void inter_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
 | 
| -                                  int64_t *distortion, int *skip,
 | 
| -                                  int64_t *psse, BLOCK_SIZE bs,
 | 
| -                                  int64_t txfm_cache[TX_MODES],
 | 
| -                                  int64_t ref_best_rd) {
 | 
| +static void super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
 | 
| +                            int64_t *distortion, int *skip,
 | 
| +                            int64_t *psse, BLOCK_SIZE bs,
 | 
| +                            int64_t txfm_cache[TX_MODES],
 | 
| +                            int64_t ref_best_rd) {
 | 
|    MACROBLOCKD *xd = &x->e_mbd;
 | 
| +  int64_t sse;
 | 
| +  int64_t *ret_sse = psse ? psse : &sse;
 | 
|  
 | 
|    assert(bs == xd->mi[0]->mbmi.sb_type);
 | 
|  
 | 
| -  vp9_subtract_plane(x, bs, 0);
 | 
| -
 | 
|    if (cpi->sf.tx_size_search_method == USE_LARGESTALL || xd->lossless) {
 | 
|      vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
 | 
| -    choose_largest_tx_size(cpi, x, rate, distortion, skip, psse, ref_best_rd,
 | 
| +    choose_largest_tx_size(cpi, x, rate, distortion, skip, ret_sse, ref_best_rd,
 | 
|                             bs);
 | 
|    } else {
 | 
| -    choose_tx_size_from_rd(cpi, x, rate, distortion, skip, psse,
 | 
| +    choose_tx_size_from_rd(cpi, x, rate, distortion, skip, ret_sse,
 | 
|                             txfm_cache, ref_best_rd, bs);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -static void intra_super_block_yrd(VP9_COMP *cpi, MACROBLOCK *x, int *rate,
 | 
| -                                  int64_t *distortion, int *skip,
 | 
| -                                  BLOCK_SIZE bs,
 | 
| -                                  int64_t txfm_cache[TX_MODES],
 | 
| -                                  int64_t ref_best_rd) {
 | 
| -  MACROBLOCKD *xd = &x->e_mbd;
 | 
| -  int64_t sse;
 | 
| -
 | 
| -  assert(bs == xd->mi[0]->mbmi.sb_type);
 | 
| -  if (cpi->sf.tx_size_search_method != USE_FULL_RD || xd->lossless) {
 | 
| -    vpx_memset(txfm_cache, 0, TX_MODES * sizeof(int64_t));
 | 
| -    choose_largest_tx_size(cpi, x, rate, distortion, skip, &sse, ref_best_rd,
 | 
| -                           bs);
 | 
| -  } else {
 | 
| -    choose_tx_size_from_rd(cpi, x, rate, distortion, skip, &sse,
 | 
| -                           txfm_cache, ref_best_rd, bs);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
|  static int conditional_skipintra(PREDICTION_MODE mode,
 | 
|                                   PREDICTION_MODE best_intra_mode) {
 | 
|    if (mode == D117_PRED &&
 | 
| @@ -854,8 +854,8 @@
 | 
|      }
 | 
|      mic->mbmi.mode = mode;
 | 
|  
 | 
| -    intra_super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
 | 
| -        &s, bsize, local_tx_cache, best_rd);
 | 
| +    super_block_yrd(cpi, x, &this_rate_tokenonly, &this_distortion,
 | 
| +        &s, NULL, bsize, local_tx_cache, best_rd);
 | 
|  
 | 
|      if (this_rate_tokenonly == INT_MAX)
 | 
|        continue;
 | 
| @@ -1365,13 +1365,14 @@
 | 
|            int sadpb = x->sadperbit4;
 | 
|            MV mvp_full;
 | 
|            int max_mv;
 | 
| +          int sad_list[5];
 | 
|  
 | 
|            /* Is the best so far sufficiently good that we cant justify doing
 | 
|             * and new motion search. */
 | 
|            if (best_rd < label_mv_thresh)
 | 
|              break;
 | 
|  
 | 
| -          if (!is_best_mode(cpi->oxcf.mode)) {
 | 
| +          if (cpi->oxcf.mode != BEST) {
 | 
|              // use previous block's result as next block's MV predictor.
 | 
|              if (i > 0) {
 | 
|                bsi->mvp.as_int = mi->bmi[i - 1].as_mv[0].as_int;
 | 
| @@ -1397,7 +1398,7 @@
 | 
|            mvp_full.row = bsi->mvp.as_mv.row >> 3;
 | 
|            mvp_full.col = bsi->mvp.as_mv.col >> 3;
 | 
|  
 | 
| -          if (cpi->sf.adaptive_motion_search && cm->show_frame) {
 | 
| +          if (cpi->sf.adaptive_motion_search) {
 | 
|              mvp_full.row = x->pred_mv[mbmi->ref_frame[0]].row >> 3;
 | 
|              mvp_full.col = x->pred_mv[mbmi->ref_frame[0]].col >> 3;
 | 
|              step_param = MAX(step_param, 8);
 | 
| @@ -1408,12 +1409,14 @@
 | 
|  
 | 
|            vp9_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
 | 
|  
 | 
| -          bestsme = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
 | 
| -                                          sadpb, &bsi->ref_mv[0]->as_mv, new_mv,
 | 
| -                                          INT_MAX, 1);
 | 
| +          bestsme = vp9_full_pixel_search(
 | 
| +              cpi, x, bsize, &mvp_full, step_param, sadpb,
 | 
| +              cpi->sf.mv.subpel_search_method != SUBPEL_TREE ? sad_list : NULL,
 | 
| +              &bsi->ref_mv[0]->as_mv, new_mv,
 | 
| +              INT_MAX, 1);
 | 
|  
 | 
|            // Should we do a full search (best quality only)
 | 
| -          if (is_best_mode(cpi->oxcf.mode)) {
 | 
| +          if (cpi->oxcf.mode == BEST) {
 | 
|              int_mv *const best_mv = &mi->bmi[i].as_mv[0];
 | 
|              /* Check if mvp_full is within the range. */
 | 
|              clamp_mv(&mvp_full, x->mv_col_min, x->mv_col_max,
 | 
| @@ -1422,6 +1425,7 @@
 | 
|                                             sadpb, 16, &cpi->fn_ptr[bsize],
 | 
|                                             &bsi->ref_mv[0]->as_mv,
 | 
|                                             &best_mv->as_mv);
 | 
| +            sad_list[1] = sad_list[2] = sad_list[3] = sad_list[4] = INT_MAX;
 | 
|              if (thissme < bestsme) {
 | 
|                bestsme = thissme;
 | 
|                *new_mv = best_mv->as_mv;
 | 
| @@ -1434,17 +1438,19 @@
 | 
|  
 | 
|            if (bestsme < INT_MAX) {
 | 
|              int distortion;
 | 
| -            cpi->find_fractional_mv_step(x,
 | 
| -                                         new_mv,
 | 
| -                                         &bsi->ref_mv[0]->as_mv,
 | 
| -                                         cm->allow_high_precision_mv,
 | 
| -                                         x->errorperbit, &cpi->fn_ptr[bsize],
 | 
| -                                         cpi->sf.mv.subpel_force_stop,
 | 
| -                                         cpi->sf.mv.subpel_iters_per_step,
 | 
| -                                         x->nmvjointcost, x->mvcost,
 | 
| -                                         &distortion,
 | 
| -                                         &x->pred_sse[mbmi->ref_frame[0]],
 | 
| -                                         NULL, 0, 0);
 | 
| +            cpi->find_fractional_mv_step(
 | 
| +                x,
 | 
| +                new_mv,
 | 
| +                &bsi->ref_mv[0]->as_mv,
 | 
| +                cm->allow_high_precision_mv,
 | 
| +                x->errorperbit, &cpi->fn_ptr[bsize],
 | 
| +                cpi->sf.mv.subpel_force_stop,
 | 
| +                cpi->sf.mv.subpel_iters_per_step,
 | 
| +                cond_sad_list(cpi, sad_list),
 | 
| +                x->nmvjointcost, x->mvcost,
 | 
| +                &distortion,
 | 
| +                &x->pred_sse[mbmi->ref_frame[0]],
 | 
| +                NULL, 0, 0);
 | 
|  
 | 
|              // save motion search result for use in compound prediction
 | 
|              seg_mvs[i][mbmi->ref_frame[0]].as_mv = *new_mv;
 | 
| @@ -1701,12 +1707,14 @@
 | 
|                           int mode_index,
 | 
|                           int64_t comp_pred_diff[REFERENCE_MODES],
 | 
|                           const int64_t tx_size_diff[TX_MODES],
 | 
| -                         int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS]) {
 | 
| +                         int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS],
 | 
| +                         int skippable) {
 | 
|    MACROBLOCKD *const xd = &x->e_mbd;
 | 
|  
 | 
|    // Take a snapshot of the coding context so it can be
 | 
|    // restored if we decide to encode this way
 | 
|    ctx->skip = x->skip;
 | 
| +  ctx->skippable = skippable;
 | 
|    ctx->best_mode_index = mode_index;
 | 
|    ctx->mic = *xd->mi[0];
 | 
|    ctx->single_pred_diff = (int)comp_pred_diff[SINGLE_REFERENCE];
 | 
| @@ -1772,6 +1780,7 @@
 | 
|    int tmp_col_max = x->mv_col_max;
 | 
|    int tmp_row_min = x->mv_row_min;
 | 
|    int tmp_row_max = x->mv_row_max;
 | 
| +  int sad_list[5];
 | 
|  
 | 
|    const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
 | 
|                                                                          ref);
 | 
| @@ -1806,8 +1815,7 @@
 | 
|      step_param = cpi->mv_step_param;
 | 
|    }
 | 
|  
 | 
| -  if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64 &&
 | 
| -      cm->show_frame) {
 | 
| +  if (cpi->sf.adaptive_motion_search && bsize < BLOCK_64X64) {
 | 
|      int boffset = 2 * (b_width_log2(BLOCK_64X64) - MIN(b_height_log2(bsize),
 | 
|                                                         b_width_log2(bsize)));
 | 
|      step_param = MAX(step_param, boffset);
 | 
| @@ -1844,6 +1852,7 @@
 | 
|    mvp_full.row >>= 3;
 | 
|  
 | 
|    bestsme = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb,
 | 
| +                                  cond_sad_list(cpi, sad_list),
 | 
|                                    &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
 | 
|  
 | 
|    x->mv_col_min = tmp_col_min;
 | 
| @@ -1859,13 +1868,14 @@
 | 
|                                   &cpi->fn_ptr[bsize],
 | 
|                                   cpi->sf.mv.subpel_force_stop,
 | 
|                                   cpi->sf.mv.subpel_iters_per_step,
 | 
| +                                 cond_sad_list(cpi, sad_list),
 | 
|                                   x->nmvjointcost, x->mvcost,
 | 
|                                   &dis, &x->pred_sse[ref], NULL, 0, 0);
 | 
|    }
 | 
|    *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
 | 
|                               x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
 | 
|  
 | 
| -  if (cpi->sf.adaptive_motion_search && cm->show_frame)
 | 
| +  if (cpi->sf.adaptive_motion_search)
 | 
|      x->pred_mv[ref] = tmp_mv->as_mv;
 | 
|  
 | 
|    if (scaled_ref_frame) {
 | 
| @@ -1983,6 +1993,7 @@
 | 
|            x->errorperbit,
 | 
|            &cpi->fn_ptr[bsize],
 | 
|            0, cpi->sf.mv.subpel_iters_per_step,
 | 
| +          NULL,
 | 
|            x->nmvjointcost, x->mvcost,
 | 
|            &dis, &sse, second_pred,
 | 
|            pw, ph);
 | 
| @@ -2118,6 +2129,8 @@
 | 
|                                   int_mv (*mode_mv)[MAX_REF_FRAMES],
 | 
|                                   int mi_row, int mi_col,
 | 
|                                   int_mv single_newmv[MAX_REF_FRAMES],
 | 
| +                                 INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
 | 
| +                                 int (*single_skippable)[MAX_REF_FRAMES],
 | 
|                                   int64_t *psse,
 | 
|                                   const int64_t ref_best_rd) {
 | 
|    VP9_COMMON *cm = &cpi->common;
 | 
| @@ -2135,14 +2148,14 @@
 | 
|    DECLARE_ALIGNED_ARRAY(16, uint8_t, tmp_buf, MAX_MB_PLANE * 64 * 64);
 | 
|    int pred_exists = 0;
 | 
|    int intpel_mv;
 | 
| -  int64_t rd, best_rd = INT64_MAX;
 | 
| +  int64_t rd, tmp_rd, best_rd = INT64_MAX;
 | 
|    int best_needs_copy = 0;
 | 
|    uint8_t *orig_dst[MAX_MB_PLANE];
 | 
|    int orig_dst_stride[MAX_MB_PLANE];
 | 
|    int rs = 0;
 | 
|    INTERP_FILTER best_filter = SWITCHABLE;
 | 
| -  int skip_txfm[MAX_MB_PLANE] = {0};
 | 
| -  int64_t bsse[MAX_MB_PLANE] = {0};
 | 
| +  uint8_t skip_txfm[MAX_MB_PLANE << 2] = {0};
 | 
| +  int64_t bsse[MAX_MB_PLANE << 2] = {0};
 | 
|  
 | 
|    int bsl = mi_width_log2_lookup[bsize];
 | 
|    int pred_filter_search = cpi->sf.cb_pred_filter_search ?
 | 
| @@ -2164,6 +2177,12 @@
 | 
|      if (frame_mv[refs[0]].as_int == INVALID_MV ||
 | 
|          frame_mv[refs[1]].as_int == INVALID_MV)
 | 
|        return INT64_MAX;
 | 
| +
 | 
| +    if (cpi->sf.adaptive_mode_search) {
 | 
| +      if (single_filter[this_mode][refs[0]] ==
 | 
| +          single_filter[this_mode][refs[1]])
 | 
| +        best_filter = single_filter[this_mode][refs[0]];
 | 
| +    }
 | 
|    }
 | 
|  
 | 
|    if (this_mode == NEWMV) {
 | 
| @@ -2225,6 +2244,10 @@
 | 
|     * if the first is known */
 | 
|    *rate2 += cost_mv_ref(cpi, this_mode, mbmi->mode_context[refs[0]]);
 | 
|  
 | 
| +  if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
 | 
| +      mbmi->mode != NEARESTMV)
 | 
| +    return INT64_MAX;
 | 
| +
 | 
|    pred_exists = 0;
 | 
|    // Are all MVs integer pel for Y and UV
 | 
|    intpel_mv = !mv_has_subpel(&mbmi->mv[0].as_mv);
 | 
| @@ -2263,6 +2286,13 @@
 | 
|          } else {
 | 
|            int rate_sum = 0;
 | 
|            int64_t dist_sum = 0;
 | 
| +          if (i > 0 && cpi->sf.adaptive_interp_filter_search &&
 | 
| +              (cpi->sf.interp_filter_search_mask & (1 << i))) {
 | 
| +            rate_sum = INT_MAX;
 | 
| +            dist_sum = INT64_MAX;
 | 
| +            continue;
 | 
| +          }
 | 
| +
 | 
|            if ((cm->interp_filter == SWITCHABLE &&
 | 
|                 (!i || best_needs_copy)) ||
 | 
|                (cm->interp_filter != SWITCHABLE &&
 | 
| @@ -2313,6 +2343,7 @@
 | 
|              (cm->interp_filter != SWITCHABLE &&
 | 
|               cm->interp_filter == mbmi->interp_filter)) {
 | 
|            pred_exists = 1;
 | 
| +          tmp_rd = best_rd;
 | 
|          }
 | 
|        }
 | 
|        restore_dst_buf(xd, orig_dst, orig_dst_stride);
 | 
| @@ -2331,17 +2362,30 @@
 | 
|          xd->plane[i].dst.stride = 64;
 | 
|        }
 | 
|      }
 | 
| +    rd = tmp_rd + RDCOST(x->rdmult, x->rddiv, rs, 0);
 | 
|    } else {
 | 
| +    int tmp_rate;
 | 
| +    int64_t tmp_dist;
 | 
|      // Handles the special case when a filter that is not in the
 | 
| -    // switchable list (ex. bilinear, 6-tap) is indicated at the frame level
 | 
| +    // switchable list (ex. bilinear) is indicated at the frame level, or
 | 
| +    // skip condition holds.
 | 
|      vp9_build_inter_predictors_sb(xd, mi_row, mi_col, bsize);
 | 
| +    model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
 | 
| +    rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
 | 
| +    vpx_memcpy(skip_txfm, x->skip_txfm, sizeof(skip_txfm));
 | 
| +    vpx_memcpy(bsse, x->bsse, sizeof(bsse));
 | 
|    }
 | 
|  
 | 
| +  if (!is_comp_pred)
 | 
| +    single_filter[this_mode][refs[0]] = mbmi->interp_filter;
 | 
| +
 | 
| +  if (cpi->sf.adaptive_mode_search)
 | 
| +    if (is_comp_pred)
 | 
| +      if (single_skippable[this_mode][refs[0]] &&
 | 
| +          single_skippable[this_mode][refs[1]])
 | 
| +        vpx_memset(skip_txfm, 1, sizeof(skip_txfm));
 | 
| +
 | 
|    if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
 | 
| -    int tmp_rate;
 | 
| -    int64_t tmp_dist;
 | 
| -    model_rd_for_sb(cpi, bsize, x, xd, &tmp_rate, &tmp_dist);
 | 
| -    rd = RDCOST(x->rdmult, x->rddiv, rs + tmp_rate, tmp_dist);
 | 
|      // if current pred_error modeled rd is substantially more than the best
 | 
|      // so far, do not bother doing full rd
 | 
|      if (rd / 2 > ref_best_rd) {
 | 
| @@ -2351,7 +2395,7 @@
 | 
|    }
 | 
|  
 | 
|    if (cm->interp_filter == SWITCHABLE)
 | 
| -    *rate2 += vp9_get_switchable_rate(cpi);
 | 
| +    *rate2 += rs;
 | 
|  
 | 
|    if (!is_comp_pred) {
 | 
|      if (cpi->allow_encode_breakout)
 | 
| @@ -2368,8 +2412,9 @@
 | 
|      int64_t rdcosty = INT64_MAX;
 | 
|  
 | 
|      // Y cost and distortion
 | 
| -    inter_super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
 | 
| -                          bsize, txfm_cache, ref_best_rd);
 | 
| +    vp9_subtract_plane(x, bsize, 0);
 | 
| +    super_block_yrd(cpi, x, rate_y, distortion_y, &skippable_y, psse,
 | 
| +                    bsize, txfm_cache, ref_best_rd);
 | 
|  
 | 
|      if (*rate_y == INT_MAX) {
 | 
|        *rate2 = INT_MAX;
 | 
| @@ -2399,6 +2444,9 @@
 | 
|      *skippable = skippable_y && skippable_uv;
 | 
|    }
 | 
|  
 | 
| +  if (!is_comp_pred)
 | 
| +    single_skippable[this_mode][refs[0]] = *skippable;
 | 
| +
 | 
|    restore_dst_buf(xd, orig_dst, orig_dst_stride);
 | 
|    return this_rd;  // if 0, this will be re-calculated by caller
 | 
|  }
 | 
| @@ -2505,10 +2553,12 @@
 | 
|    PREDICTION_MODE this_mode;
 | 
|    MV_REFERENCE_FRAME ref_frame, second_ref_frame;
 | 
|    unsigned char segment_id = mbmi->segment_id;
 | 
| -  int comp_pred, i;
 | 
| +  int comp_pred, i, k;
 | 
|    int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
 | 
|    struct buf_2d yv12_mb[4][MAX_MB_PLANE];
 | 
|    int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
 | 
| +  INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
 | 
| +  int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
 | 
|    static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
 | 
|                                      VP9_ALT_FLAG };
 | 
|    int64_t best_rd = best_rd_so_far;
 | 
| @@ -2519,6 +2569,7 @@
 | 
|    int64_t best_filter_rd[SWITCHABLE_FILTER_CONTEXTS];
 | 
|    int64_t best_filter_diff[SWITCHABLE_FILTER_CONTEXTS];
 | 
|    MB_MODE_INFO best_mbmode;
 | 
| +  int best_mode_skippable = 0;
 | 
|    int mode_index, best_mode_index = -1;
 | 
|    unsigned int ref_costs_single[MAX_REF_FRAMES], ref_costs_comp[MAX_REF_FRAMES];
 | 
|    vp9_prob comp_mode_p;
 | 
| @@ -2556,6 +2607,12 @@
 | 
|      rate_uv_intra[i] = INT_MAX;
 | 
|    for (i = 0; i < MAX_REF_FRAMES; ++i)
 | 
|      x->pred_sse[i] = INT_MAX;
 | 
| +  for (i = 0; i < MB_MODE_COUNT; ++i) {
 | 
| +    for (k = 0; k < MAX_REF_FRAMES; ++k) {
 | 
| +      single_inter_filter[i][k] = SWITCHABLE;
 | 
| +      single_skippable[i][k] = 0;
 | 
| +    }
 | 
| +  }
 | 
|  
 | 
|    *returnrate = INT_MAX;
 | 
|  
 | 
| @@ -2732,6 +2789,9 @@
 | 
|  
 | 
|      comp_pred = second_ref_frame > INTRA_FRAME;
 | 
|      if (comp_pred) {
 | 
| +      if (!cm->allow_comp_inter_inter)
 | 
| +        continue;
 | 
| +
 | 
|        if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
 | 
|            best_mode_index >=0 &&
 | 
|            vp9_mode_order[best_mode_index].ref_frame[0] == INTRA_FRAME)
 | 
| @@ -2747,6 +2807,10 @@
 | 
|      }
 | 
|  
 | 
|      if (ref_frame == INTRA_FRAME) {
 | 
| +      if (cpi->sf.adaptive_mode_search)
 | 
| +        if ((x->source_variance << num_pels_log2_lookup[bsize]) > best_intra_rd)
 | 
| +          continue;
 | 
| +
 | 
|        if (!(intra_y_mode_mask & (1 << this_mode)))
 | 
|          continue;
 | 
|        if (this_mode != DC_PRED) {
 | 
| @@ -2785,6 +2849,8 @@
 | 
|      // them for this frame.
 | 
|      mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP
 | 
|                                                            : cm->interp_filter;
 | 
| +    mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0;
 | 
| +
 | 
|      x->skip = 0;
 | 
|      set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
 | 
|  
 | 
| @@ -2800,8 +2866,8 @@
 | 
|  
 | 
|      if (ref_frame == INTRA_FRAME) {
 | 
|        TX_SIZE uv_tx;
 | 
| -      intra_super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
 | 
| -                            bsize, tx_cache, best_rd);
 | 
| +      super_block_yrd(cpi, x, &rate_y, &distortion_y, &skippable,
 | 
| +                      NULL, bsize, tx_cache, best_rd);
 | 
|  
 | 
|        if (rate_y == INT_MAX)
 | 
|          continue;
 | 
| @@ -2831,7 +2897,8 @@
 | 
|                                    &rate_uv, &distortion_uv,
 | 
|                                    &disable_skip, frame_mv,
 | 
|                                    mi_row, mi_col,
 | 
| -                                  single_newmv, &total_sse, best_rd);
 | 
| +                                  single_newmv, single_inter_filter,
 | 
| +                                  single_skippable, &total_sse, best_rd);
 | 
|        if (this_rd == INT64_MAX)
 | 
|          continue;
 | 
|  
 | 
| @@ -2919,6 +2986,8 @@
 | 
|            /* required for left and above block mv */
 | 
|            mbmi->mv[0].as_int = 0;
 | 
|            max_plane = 1;
 | 
| +        } else {
 | 
| +          best_intra_rd = x->pred_sse[ref_frame];
 | 
|          }
 | 
|  
 | 
|          *returnrate = rate2;
 | 
| @@ -2926,6 +2995,8 @@
 | 
|          best_rd = this_rd;
 | 
|          best_mbmode = *mbmi;
 | 
|          best_skip2 = this_skip2;
 | 
| +        best_mode_skippable = skippable;
 | 
| +
 | 
|          if (!x->select_tx_size)
 | 
|            swap_block_ptr(x, ctx, 1, 0, 0, max_plane);
 | 
|          vpx_memcpy(ctx->zcoeff_blk, x->zcoeff_blk[mbmi->tx_size],
 | 
| @@ -3025,6 +3096,28 @@
 | 
|        break;
 | 
|    }
 | 
|  
 | 
| +  // The inter modes' rate costs are not calculated precisely in some cases.
 | 
| +  // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
 | 
| +  // ZEROMV. Here, checks are added for those cases, and the mode decisions
 | 
| +  // are corrected.
 | 
| +  if (best_mbmode.mode == NEWMV) {
 | 
| +    const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
 | 
| +        best_mbmode.ref_frame[1]};
 | 
| +    int comp_pred_mode = refs[1] > INTRA_FRAME;
 | 
| +
 | 
| +    if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
 | 
| +        ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
 | 
| +            best_mbmode.mv[1].as_int) || !comp_pred_mode))
 | 
| +      best_mbmode.mode = NEARESTMV;
 | 
| +    else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
 | 
| +        ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int ==
 | 
| +            best_mbmode.mv[1].as_int) || !comp_pred_mode))
 | 
| +      best_mbmode.mode = NEARMV;
 | 
| +    else if (best_mbmode.mv[0].as_int == 0 &&
 | 
| +        ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
 | 
| +      best_mbmode.mode = ZEROMV;
 | 
| +  }
 | 
| +
 | 
|    if (best_mode_index < 0 || best_rd >= best_rd_so_far)
 | 
|      return INT64_MAX;
 | 
|  
 | 
| @@ -3082,8 +3175,8 @@
 | 
|    }
 | 
|  
 | 
|    set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
 | 
| -  store_coding_context(x, ctx, best_mode_index,
 | 
| -                       best_pred_diff, best_tx_diff, best_filter_diff);
 | 
| +  store_coding_context(x, ctx, best_mode_index, best_pred_diff,
 | 
| +                       best_tx_diff, best_filter_diff, best_mode_skippable);
 | 
|  
 | 
|    return best_rd;
 | 
|  }
 | 
| @@ -3188,7 +3281,7 @@
 | 
|    if (!x->select_tx_size)
 | 
|      swap_block_ptr(x, ctx, 1, 0, 0, MAX_MB_PLANE);
 | 
|    store_coding_context(x, ctx, THR_ZEROMV,
 | 
| -                       best_pred_diff, best_tx_diff, best_filter_diff);
 | 
| +                       best_pred_diff, best_tx_diff, best_filter_diff, 0);
 | 
|  
 | 
|    return this_rd;
 | 
|  }
 | 
| @@ -3325,6 +3418,9 @@
 | 
|  
 | 
|      comp_pred = second_ref_frame > INTRA_FRAME;
 | 
|      if (comp_pred) {
 | 
| +      if (!cm->allow_comp_inter_inter)
 | 
| +        continue;
 | 
| +
 | 
|        if (!(cpi->ref_frame_flags & flag_list[second_ref_frame]))
 | 
|          continue;
 | 
|        // Do not allow compound prediction if the segment level reference frame
 | 
| @@ -3793,7 +3889,7 @@
 | 
|  
 | 
|    set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
 | 
|    store_coding_context(x, ctx, best_ref_index,
 | 
| -                       best_pred_diff, best_tx_diff, best_filter_diff);
 | 
| +                       best_pred_diff, best_tx_diff, best_filter_diff, 0);
 | 
|  
 | 
|    return best_rd;
 | 
|  }
 | 
| 
 |