void vp9_pick_inter_mode()

in media/libvpx/libvpx/vp9/encoder/vp9_pickmode.c [1695:2752]


void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
                         int mi_row, int mi_col, RD_COST *rd_cost,
                         BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
  VP9_COMMON *const cm = &cpi->common;
  SPEED_FEATURES *const sf = &cpi->sf;
  SVC *const svc = &cpi->svc;
  MACROBLOCKD *const xd = &x->e_mbd;
  MODE_INFO *const mi = xd->mi[0];
  struct macroblockd_plane *const pd = &xd->plane[0];

  BEST_PICKMODE best_pickmode;

  MV_REFERENCE_FRAME ref_frame;
  MV_REFERENCE_FRAME usable_ref_frame, second_ref_frame;
  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
  uint8_t mode_checked[MB_MODE_COUNT][MAX_REF_FRAMES];
  struct buf_2d yv12_mb[4][MAX_MB_PLANE] = { 0 };
  RD_COST this_rdc, best_rdc;
  // var_y and sse_y are saved to be used in skipping checking
  unsigned int var_y = UINT_MAX;
  unsigned int sse_y = UINT_MAX;
  const int intra_cost_penalty =
      vp9_get_intra_cost_penalty(cpi, bsize, cm->base_qindex, cm->y_dc_delta_q);
  int64_t inter_mode_thresh =
      RDCOST(x->rdmult, x->rddiv, intra_cost_penalty, 0);
  const int *const rd_threshes = cpi->rd.threshes[mi->segment_id][bsize];
  const int sb_row = mi_row >> MI_BLOCK_SIZE_LOG2;
  int thresh_freq_fact_idx = (sb_row * BLOCK_SIZES + bsize) * MAX_MODES;
  const int *const rd_thresh_freq_fact =
      (cpi->sf.adaptive_rd_thresh_row_mt)
          ? &(tile_data->row_base_thresh_freq_fact[thresh_freq_fact_idx])
          : tile_data->thresh_freq_fact[bsize];
#if CONFIG_VP9_TEMPORAL_DENOISING
  const int denoise_recheck_zeromv = 1;
#endif
  INTERP_FILTER filter_ref;
  int pred_filter_search = cm->interp_filter == SWITCHABLE;
  int const_motion[MAX_REF_FRAMES] = { 0 };
  const int bh = num_4x4_blocks_high_lookup[bsize] << 2;
  const int bw = num_4x4_blocks_wide_lookup[bsize] << 2;
  // For speed 6, the result of interp filter is reused later in actual encoding
  // process.
  // tmp[3] points to dst buffer, and the other 3 point to allocated buffers.
  PRED_BUFFER tmp[4];
  DECLARE_ALIGNED(16, uint8_t, pred_buf[3 * 64 * 64] VPX_UNINITIALIZED);
#if CONFIG_VP9_HIGHBITDEPTH
  DECLARE_ALIGNED(16, uint16_t, pred_buf_16[3 * 64 * 64] VPX_UNINITIALIZED);
#endif
  struct buf_2d orig_dst = pd->dst;
  PRED_BUFFER *this_mode_pred = NULL;
  const int pixels_in_block = bh * bw;
  int reuse_inter_pred = cpi->sf.reuse_inter_pred_sby && ctx->pred_pixel_ready;
  int ref_frame_skip_mask = 0;
  int idx;
  int best_pred_sad = INT_MAX;
  int best_early_term = 0;
  int ref_frame_cost[MAX_REF_FRAMES];
  int svc_force_zero_mode[3] = { 0 };
  int perform_intra_pred = 1;
  int use_golden_nonzeromv = 1;
  int force_skip_low_temp_var = 0;
  int skip_ref_find_pred[4] = { 0 };
  unsigned int sse_zeromv_normalized = UINT_MAX;
  unsigned int best_sse_sofar = UINT_MAX;
  int gf_temporal_ref = 0;
  int force_test_gf_zeromv = 0;
#if CONFIG_VP9_TEMPORAL_DENOISING
  VP9_PICKMODE_CTX_DEN ctx_den;
  int64_t zero_last_cost_orig = INT64_MAX;
  int denoise_svc_pickmode = 1;
#endif
  INTERP_FILTER filter_gf_svc = EIGHTTAP;
  MV_REFERENCE_FRAME inter_layer_ref = GOLDEN_FRAME;
  const struct segmentation *const seg = &cm->seg;
  int comp_modes = 0;
  int num_inter_modes = (cpi->use_svc) ? RT_INTER_MODES_SVC : RT_INTER_MODES;
  int flag_svc_subpel = 0;
  int svc_mv_col = 0;
  int svc_mv_row = 0;
  int no_scaling = 0;
  int large_block = 0;
  int use_model_yrd_large = 0;
  unsigned int thresh_svc_skip_golden = 500;
  unsigned int thresh_skip_golden = 500;
  int force_smooth_filter = cpi->sf.force_smooth_interpol;
  int scene_change_detected =
      cpi->rc.high_source_sad ||
      (cpi->use_svc && cpi->svc.high_source_sad_superframe);

  init_best_pickmode(&best_pickmode);

  x->encode_breakout = seg->enabled
                           ? cpi->segment_encode_breakout[mi->segment_id]
                           : cpi->encode_breakout;

  x->source_variance = UINT_MAX;
  if (cpi->sf.default_interp_filter == BILINEAR) {
    best_pickmode.best_pred_filter = BILINEAR;
    filter_gf_svc = BILINEAR;
  }
  if (cpi->use_svc && svc->spatial_layer_id > 0) {
    int layer =
        LAYER_IDS_TO_IDX(svc->spatial_layer_id - 1, svc->temporal_layer_id,
                         svc->number_temporal_layers);
    LAYER_CONTEXT *const lc = &svc->layer_context[layer];
    if (lc->scaling_factor_num == lc->scaling_factor_den) no_scaling = 1;
  }
  if (svc->spatial_layer_id > 0 &&
      (svc->high_source_sad_superframe || no_scaling))
    thresh_svc_skip_golden = 0;
  // Lower the skip threshold if lower spatial layer is better quality relative
  // to current layer.
  else if (svc->spatial_layer_id > 0 && cm->base_qindex > 150 &&
           cm->base_qindex > svc->lower_layer_qindex + 15)
    thresh_svc_skip_golden = 100;
  // Increase skip threshold if lower spatial layer is lower quality relative
  // to current layer.
  else if (svc->spatial_layer_id > 0 && cm->base_qindex < 140 &&
           cm->base_qindex < svc->lower_layer_qindex - 20)
    thresh_svc_skip_golden = 1000;

  if (!cpi->use_svc ||
      (svc->use_gf_temporal_ref_current_layer &&
       !svc->layer_context[svc->temporal_layer_id].is_key_frame)) {
    struct scale_factors *const sf_last = &cm->frame_refs[LAST_FRAME - 1].sf;
    struct scale_factors *const sf_golden =
        &cm->frame_refs[GOLDEN_FRAME - 1].sf;
    gf_temporal_ref = 1;
    // For temporal long term prediction, check that the golden reference
    // is same scale as last reference, otherwise disable.
    if ((sf_last->x_scale_fp != sf_golden->x_scale_fp) ||
        (sf_last->y_scale_fp != sf_golden->y_scale_fp)) {
      gf_temporal_ref = 0;
    } else {
      if (cpi->rc.avg_frame_low_motion > 70)
        thresh_svc_skip_golden = 500;
      else
        thresh_svc_skip_golden = 0;
    }
  }

  init_ref_frame_cost(cm, xd, ref_frame_cost);
  memset(&mode_checked[0][0], 0, MB_MODE_COUNT * MAX_REF_FRAMES);

  if (reuse_inter_pred) {
    int i;
    for (i = 0; i < 3; i++) {
#if CONFIG_VP9_HIGHBITDEPTH
      if (cm->use_highbitdepth)
        tmp[i].data = CONVERT_TO_BYTEPTR(&pred_buf_16[pixels_in_block * i]);
      else
        tmp[i].data = &pred_buf[pixels_in_block * i];
#else
      tmp[i].data = &pred_buf[pixels_in_block * i];
#endif  // CONFIG_VP9_HIGHBITDEPTH
      tmp[i].stride = bw;
      tmp[i].in_use = 0;
    }
    tmp[3].data = pd->dst.buf;
    tmp[3].stride = pd->dst.stride;
    tmp[3].in_use = 0;
  }

  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
  x->skip = 0;

  if (cpi->sf.cb_pred_filter_search) {
    const int bsl = mi_width_log2_lookup[bsize];
    pred_filter_search = cm->interp_filter == SWITCHABLE
                             ? (((mi_row + mi_col) >> bsl) +
                                get_chessboard_index(cm->current_video_frame)) &
                                   0x1
                             : 0;
  }
  // Instead of using vp9_get_pred_context_switchable_interp(xd) to assign
  // filter_ref, we use a less strict condition on assigning filter_ref.
  // This is to reduce the probabily of entering the flow of not assigning
  // filter_ref and then skip filter search.
  filter_ref = cm->interp_filter;
  if (cpi->sf.default_interp_filter != BILINEAR) {
    if (xd->above_mi && is_inter_block(xd->above_mi))
      filter_ref = xd->above_mi->interp_filter;
    else if (xd->left_mi && is_inter_block(xd->left_mi))
      filter_ref = xd->left_mi->interp_filter;
  }

  // initialize mode decisions
  vp9_rd_cost_reset(&best_rdc);
  vp9_rd_cost_reset(rd_cost);
  mi->sb_type = bsize;
  mi->ref_frame[0] = NO_REF_FRAME;
  mi->ref_frame[1] = NO_REF_FRAME;

  mi->tx_size =
      VPXMIN(max_txsize_lookup[bsize], tx_mode_to_biggest_tx_size[cm->tx_mode]);

  if (sf->short_circuit_flat_blocks || sf->limit_newmv_early_exit) {
#if CONFIG_VP9_HIGHBITDEPTH
    if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
      x->source_variance = vp9_high_get_sby_perpixel_variance(
          cpi, &x->plane[0].src, bsize, xd->bd);
    else
#endif  // CONFIG_VP9_HIGHBITDEPTH
      x->source_variance =
          vp9_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);

    if (cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
        cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && mi->segment_id > 0 &&
        x->zero_temp_sad_source && x->source_variance == 0) {
      mi->segment_id = 0;
      vp9_init_plane_quantizers(cpi, x);
    }
  }

#if CONFIG_VP9_TEMPORAL_DENOISING
  if (cpi->oxcf.noise_sensitivity > 0) {
    if (cpi->use_svc) denoise_svc_pickmode = vp9_denoise_svc_non_key(cpi);
    if (cpi->denoiser.denoising_level > kDenLowLow && denoise_svc_pickmode)
      vp9_denoiser_reset_frame_stats(ctx);
  }
#endif

  if (cpi->rc.frames_since_golden == 0 && gf_temporal_ref &&
      !cpi->rc.alt_ref_gf_group && !cpi->rc.last_frame_is_src_altref) {
    usable_ref_frame = LAST_FRAME;
  } else {
    usable_ref_frame = GOLDEN_FRAME;
  }

  if (cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR) {
    if (cpi->rc.alt_ref_gf_group || cpi->rc.is_src_frame_alt_ref)
      usable_ref_frame = ALTREF_FRAME;

    if (cpi->rc.is_src_frame_alt_ref) {
      skip_ref_find_pred[LAST_FRAME] = 1;
      skip_ref_find_pred[GOLDEN_FRAME] = 1;
    }
    if (!cm->show_frame) {
      if (cpi->rc.frames_since_key == 1) {
        usable_ref_frame = LAST_FRAME;
        skip_ref_find_pred[GOLDEN_FRAME] = 1;
        skip_ref_find_pred[ALTREF_FRAME] = 1;
      }
    }
  }

  // For svc mode, on spatial_layer_id > 0: if the reference has different scale
  // constrain the inter mode to only test zero motion.
  if (cpi->use_svc && svc->force_zero_mode_spatial_ref &&
      svc->spatial_layer_id > 0 && !gf_temporal_ref) {
    if (cpi->ref_frame_flags & VP9_LAST_FLAG) {
      struct scale_factors *const ref_sf = &cm->frame_refs[LAST_FRAME - 1].sf;
      if (vp9_is_scaled(ref_sf)) {
        svc_force_zero_mode[LAST_FRAME - 1] = 1;
        inter_layer_ref = LAST_FRAME;
      }
    }
    if (cpi->ref_frame_flags & VP9_GOLD_FLAG) {
      struct scale_factors *const ref_sf = &cm->frame_refs[GOLDEN_FRAME - 1].sf;
      if (vp9_is_scaled(ref_sf)) {
        svc_force_zero_mode[GOLDEN_FRAME - 1] = 1;
        inter_layer_ref = GOLDEN_FRAME;
      }
    }
  }

  if (cpi->sf.short_circuit_low_temp_var) {
    force_skip_low_temp_var =
        get_force_skip_low_temp_var(&x->variance_low[0], mi_row, mi_col, bsize);
    // If force_skip_low_temp_var is set, and for short circuit mode = 1 and 3,
    // skip golden reference.
    if ((cpi->sf.short_circuit_low_temp_var == 1 ||
         cpi->sf.short_circuit_low_temp_var == 3) &&
        force_skip_low_temp_var) {
      usable_ref_frame = LAST_FRAME;
    }
  }

  if (sf->disable_golden_ref && (x->content_state_sb != kVeryHighSad ||
                                 cpi->rc.avg_frame_low_motion < 60))
    usable_ref_frame = LAST_FRAME;

  if (!((cpi->ref_frame_flags & VP9_GOLD_FLAG) &&
        !svc_force_zero_mode[GOLDEN_FRAME - 1] && !force_skip_low_temp_var))
    use_golden_nonzeromv = 0;

  if (cpi->oxcf.speed >= 8 && !cpi->use_svc &&
      ((cpi->rc.frames_since_golden + 1) < x->last_sb_high_content ||
       x->last_sb_high_content > 40 || cpi->rc.frames_since_golden > 120))
    usable_ref_frame = LAST_FRAME;

  // Compound prediction modes: (0,0) on LAST/GOLDEN and ARF.
  if (cm->reference_mode == REFERENCE_MODE_SELECT &&
      cpi->sf.use_compound_nonrd_pickmode && usable_ref_frame == ALTREF_FRAME)
    comp_modes = 2;

  // If the segment reference frame feature is enabled and it's set to GOLDEN
  // reference, then make sure we don't skip checking GOLDEN, this is to
  // prevent possibility of not picking any mode.
  if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME) &&
      get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) == GOLDEN_FRAME) {
    usable_ref_frame = GOLDEN_FRAME;
    skip_ref_find_pred[GOLDEN_FRAME] = 0;
    thresh_svc_skip_golden = 0;
  }

  for (ref_frame = LAST_FRAME; ref_frame <= usable_ref_frame; ++ref_frame) {
    // Skip find_predictor if the reference frame is not in the
    // ref_frame_flags (i.e., not used as a reference for this frame).
    skip_ref_find_pred[ref_frame] =
        !(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame));
    if (!skip_ref_find_pred[ref_frame]) {
      find_predictors(cpi, x, ref_frame, frame_mv, const_motion,
                      &ref_frame_skip_mask, tile_data, mi_row, mi_col, yv12_mb,
                      bsize, force_skip_low_temp_var, comp_modes > 0);
    }
  }

  if (cpi->use_svc || cpi->oxcf.speed <= 7 || bsize < BLOCK_32X32)
    x->sb_use_mv_part = 0;

  // Set the flag_svc_subpel to 1 for SVC if the lower spatial layer used
  // an averaging filter for downsampling (phase = 8). If so, we will test
  // a nonzero motion mode on the spatial reference.
  // The nonzero motion is half pixel shifted to left and top (-4, -4).
  if (cpi->use_svc && svc->spatial_layer_id > 0 &&
      svc_force_zero_mode[inter_layer_ref - 1] &&
      svc->downsample_filter_phase[svc->spatial_layer_id - 1] == 8 &&
      !gf_temporal_ref) {
    svc_mv_col = -4;
    svc_mv_row = -4;
    flag_svc_subpel = 1;
  }

  // For SVC with quality layers, when QP of lower layer is lower
  // than current layer: force check of GF-ZEROMV before early exit
  // due to skip flag.
  if (svc->spatial_layer_id > 0 && no_scaling &&
      (cpi->ref_frame_flags & VP9_GOLD_FLAG) &&
      cm->base_qindex > svc->lower_layer_qindex + 10)
    force_test_gf_zeromv = 1;

  // For low motion content use x->sb_is_skin in addition to VeryHighSad
  // for setting large_block.
  large_block = (x->content_state_sb == kVeryHighSad ||
                 (x->sb_is_skin && cpi->rc.avg_frame_low_motion > 70) ||
                 cpi->oxcf.speed < 7)
                    ? bsize > BLOCK_32X32
                    : bsize >= BLOCK_32X32;
  use_model_yrd_large =
      cpi->oxcf.rc_mode == VPX_CBR && large_block &&
      !cyclic_refresh_segment_id_boosted(xd->mi[0]->segment_id) &&
      cm->base_qindex;

  for (idx = 0; idx < num_inter_modes + comp_modes; ++idx) {
    int rate_mv = 0;
    int mode_rd_thresh;
    int mode_index;
    int i;
    int64_t this_sse;
    int is_skippable;
    int this_early_term = 0;
    int rd_computed = 0;
    int flag_preduv_computed[2] = { 0 };
    int inter_mv_mode = 0;
    int skip_this_mv = 0;
    int comp_pred = 0;
    int force_mv_inter_layer = 0;
    PREDICTION_MODE this_mode;
    second_ref_frame = NO_REF_FRAME;

    if (idx < num_inter_modes) {
      this_mode = ref_mode_set[idx].pred_mode;
      ref_frame = ref_mode_set[idx].ref_frame;

      if (cpi->use_svc) {
        this_mode = ref_mode_set_svc[idx].pred_mode;
        ref_frame = ref_mode_set_svc[idx].ref_frame;
      }
    } else {
      // Add (0,0) compound modes.
      this_mode = ZEROMV;
      ref_frame = LAST_FRAME;
      if (idx == num_inter_modes + comp_modes - 1) ref_frame = GOLDEN_FRAME;
      second_ref_frame = ALTREF_FRAME;
      comp_pred = 1;
    }

    if (ref_frame > usable_ref_frame) continue;
    if (skip_ref_find_pred[ref_frame]) continue;

    if (svc->previous_frame_is_intra_only) {
      if (ref_frame != LAST_FRAME || frame_mv[this_mode][ref_frame].as_int != 0)
        continue;
    }

    // If the segment reference frame feature is enabled then do nothing if the
    // current ref frame is not allowed.
    if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME) &&
        get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) != (int)ref_frame)
      continue;

    if (flag_svc_subpel && ref_frame == inter_layer_ref) {
      force_mv_inter_layer = 1;
      // Only test mode if NEARESTMV/NEARMV is (svc_mv_col, svc_mv_row),
      // otherwise set NEWMV to (svc_mv_col, svc_mv_row).
      if (this_mode == NEWMV) {
        frame_mv[this_mode][ref_frame].as_mv.col = svc_mv_col;
        frame_mv[this_mode][ref_frame].as_mv.row = svc_mv_row;
      } else if (frame_mv[this_mode][ref_frame].as_mv.col != svc_mv_col ||
                 frame_mv[this_mode][ref_frame].as_mv.row != svc_mv_row) {
        continue;
      }
    }

    if (comp_pred) {
      if (!cpi->allow_comp_inter_inter) continue;
      // Skip compound inter modes if ARF is not available.
      if (!(cpi->ref_frame_flags & ref_frame_to_flag(second_ref_frame)))
        continue;
      // Do not allow compound prediction if the segment level reference frame
      // feature is in use as in this case there can only be one reference.
      if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME)) continue;
    }

    // For CBR mode: skip the golden reference search if sse of zeromv_last is
    // below threshold.
    if (ref_frame == GOLDEN_FRAME && cpi->oxcf.rc_mode == VPX_CBR &&
        ((cpi->use_svc && sse_zeromv_normalized < thresh_svc_skip_golden) ||
         (!cpi->use_svc && sse_zeromv_normalized < thresh_skip_golden)))
      continue;

    if (!(cpi->ref_frame_flags & ref_frame_to_flag(ref_frame))) continue;

    // For screen content. If zero_temp_sad source is computed: skip
    // non-zero motion check for stationary blocks. If the superblock is
    // non-stationary then for flat blocks skip the zero last check (keep golden
    // as it may be inter-layer reference). Otherwise (if zero_temp_sad_source
    // is not computed) skip non-zero motion check for flat blocks.
    // TODO(marpan): Compute zero_temp_sad_source per coding block.
    if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) {
      if (cpi->compute_source_sad_onepass && cpi->sf.use_source_sad) {
        if ((frame_mv[this_mode][ref_frame].as_int != 0 &&
             x->zero_temp_sad_source) ||
            (frame_mv[this_mode][ref_frame].as_int == 0 &&
             x->source_variance == 0 && ref_frame == LAST_FRAME &&
             !x->zero_temp_sad_source))
          continue;
      } else if (frame_mv[this_mode][ref_frame].as_int != 0 &&
                 x->source_variance == 0) {
        continue;
      }
    }

    if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode))) continue;

    if (cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR) {
      if (cpi->rc.is_src_frame_alt_ref &&
          (ref_frame != ALTREF_FRAME ||
           frame_mv[this_mode][ref_frame].as_int != 0))
        continue;

      if (!cm->show_frame && ref_frame == ALTREF_FRAME &&
          frame_mv[this_mode][ref_frame].as_int != 0)
        continue;

      if (cpi->rc.alt_ref_gf_group && cm->show_frame &&
          cpi->rc.frames_since_golden > (cpi->rc.baseline_gf_interval >> 1) &&
          ref_frame == GOLDEN_FRAME &&
          frame_mv[this_mode][ref_frame].as_int != 0)
        continue;

      if (cpi->rc.alt_ref_gf_group && cm->show_frame &&
          cpi->rc.frames_since_golden > 0 &&
          cpi->rc.frames_since_golden < (cpi->rc.baseline_gf_interval >> 1) &&
          ref_frame == ALTREF_FRAME &&
          frame_mv[this_mode][ref_frame].as_int != 0)
        continue;
    }

    if (const_motion[ref_frame] && this_mode == NEARMV) continue;

    // Skip non-zeromv mode search for golden frame if force_skip_low_temp_var
    // is set. If nearestmv for golden frame is 0, zeromv mode will be skipped
    // later.
    if (!force_mv_inter_layer && force_skip_low_temp_var &&
        ref_frame == GOLDEN_FRAME &&
        frame_mv[this_mode][ref_frame].as_int != 0) {
      continue;
    }

    if (x->content_state_sb != kVeryHighSad &&
        (cpi->sf.short_circuit_low_temp_var >= 2 ||
         (cpi->sf.short_circuit_low_temp_var == 1 && bsize == BLOCK_64X64)) &&
        force_skip_low_temp_var && ref_frame == LAST_FRAME &&
        this_mode == NEWMV) {
      continue;
    }

    if (cpi->use_svc) {
      if (!force_mv_inter_layer && svc_force_zero_mode[ref_frame - 1] &&
          frame_mv[this_mode][ref_frame].as_int != 0)
        continue;
    }

    // Disable this drop out case if the ref frame segment level feature is
    // enabled for this segment. This is to prevent the possibility that we end
    // up unable to pick any mode.
    if (!segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME)) {
      if (sf->reference_masking &&
          !(frame_mv[this_mode][ref_frame].as_int == 0 &&
            ref_frame == LAST_FRAME)) {
        if (usable_ref_frame < ALTREF_FRAME) {
          if (!force_skip_low_temp_var && usable_ref_frame > LAST_FRAME) {
            i = (ref_frame == LAST_FRAME) ? GOLDEN_FRAME : LAST_FRAME;
            if ((cpi->ref_frame_flags & ref_frame_to_flag(i)))
              if (x->pred_mv_sad[ref_frame] > (x->pred_mv_sad[i] << 1))
                ref_frame_skip_mask |= (1 << ref_frame);
          }
        } else if (!cpi->rc.is_src_frame_alt_ref &&
                   !(frame_mv[this_mode][ref_frame].as_int == 0 &&
                     ref_frame == ALTREF_FRAME)) {
          int ref1 = (ref_frame == GOLDEN_FRAME) ? LAST_FRAME : GOLDEN_FRAME;
          int ref2 = (ref_frame == ALTREF_FRAME) ? LAST_FRAME : ALTREF_FRAME;
          if (((cpi->ref_frame_flags & ref_frame_to_flag(ref1)) &&
               (x->pred_mv_sad[ref_frame] > (x->pred_mv_sad[ref1] << 1))) ||
              ((cpi->ref_frame_flags & ref_frame_to_flag(ref2)) &&
               (x->pred_mv_sad[ref_frame] > (x->pred_mv_sad[ref2] << 1))))
            ref_frame_skip_mask |= (1 << ref_frame);
        }
      }
      if (ref_frame_skip_mask & (1 << ref_frame)) continue;
    }

    // Select prediction reference frames.
    for (i = 0; i < MAX_MB_PLANE; i++) {
      xd->plane[i].pre[0] = yv12_mb[ref_frame][i];
      if (comp_pred) xd->plane[i].pre[1] = yv12_mb[second_ref_frame][i];
    }

    mi->ref_frame[0] = ref_frame;
    mi->ref_frame[1] = second_ref_frame;
    set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);

    mode_index = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
    mode_rd_thresh = best_pickmode.best_mode_skip_txfm
                         ? rd_threshes[mode_index] << 1
                         : rd_threshes[mode_index];

    // Increase mode_rd_thresh value for GOLDEN_FRAME for improved encoding
    // speed with little/no subjective quality loss.
    if (cpi->sf.bias_golden && ref_frame == GOLDEN_FRAME &&
        cpi->rc.frames_since_golden > 4)
      mode_rd_thresh = mode_rd_thresh << 3;

    if ((cpi->sf.adaptive_rd_thresh_row_mt &&
         rd_less_than_thresh_row_mt(best_rdc.rdcost, mode_rd_thresh,
                                    &rd_thresh_freq_fact[mode_index])) ||
        (!cpi->sf.adaptive_rd_thresh_row_mt &&
         rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
                             &rd_thresh_freq_fact[mode_index])))
      if (frame_mv[this_mode][ref_frame].as_int != 0) continue;

    if (this_mode == NEWMV && !force_mv_inter_layer) {
      if (search_new_mv(cpi, x, frame_mv, ref_frame, gf_temporal_ref, bsize,
                        mi_row, mi_col, best_pred_sad, &rate_mv, best_sse_sofar,
                        &best_rdc))
        continue;
    }

    // TODO(jianj): Skipping the testing of (duplicate) non-zero motion vector
    // causes some regression, leave it for duplicate zero-mv for now, until
    // regression issue is resolved.
    for (inter_mv_mode = NEARESTMV; inter_mv_mode <= NEWMV; inter_mv_mode++) {
      if (inter_mv_mode == this_mode || comp_pred) continue;
      if (mode_checked[inter_mv_mode][ref_frame] &&
          frame_mv[this_mode][ref_frame].as_int ==
              frame_mv[inter_mv_mode][ref_frame].as_int &&
          frame_mv[inter_mv_mode][ref_frame].as_int == 0) {
        skip_this_mv = 1;
        break;
      }
    }

    if (skip_this_mv) continue;

    // If use_golden_nonzeromv is false, NEWMV mode is skipped for golden, no
    // need to compute best_pred_sad which is only used to skip golden NEWMV.
    if (use_golden_nonzeromv && this_mode == NEWMV && ref_frame == LAST_FRAME &&
        frame_mv[NEWMV][LAST_FRAME].as_int != INVALID_MV) {
      const int pre_stride = xd->plane[0].pre[0].stride;
      const uint8_t *const pre_buf =
          xd->plane[0].pre[0].buf +
          (frame_mv[NEWMV][LAST_FRAME].as_mv.row >> 3) * pre_stride +
          (frame_mv[NEWMV][LAST_FRAME].as_mv.col >> 3);
      best_pred_sad = cpi->fn_ptr[bsize].sdf(
          x->plane[0].src.buf, x->plane[0].src.stride, pre_buf, pre_stride);
      x->pred_mv_sad[LAST_FRAME] = best_pred_sad;
    }

    if (this_mode != NEARESTMV && !comp_pred &&
        frame_mv[this_mode][ref_frame].as_int ==
            frame_mv[NEARESTMV][ref_frame].as_int)
      continue;

    mi->mode = this_mode;
    mi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
    mi->mv[1].as_int = 0;

    // Search for the best prediction filter type, when the resulting
    // motion vector is at sub-pixel accuracy level for luma component, i.e.,
    // the last three bits are all zeros.
    if (reuse_inter_pred) {
      if (!this_mode_pred) {
        this_mode_pred = &tmp[3];
      } else {
        this_mode_pred = &tmp[get_pred_buffer(tmp, 3)];
        pd->dst.buf = this_mode_pred->data;
        pd->dst.stride = bw;
      }
    }

    if ((this_mode == NEWMV || filter_ref == SWITCHABLE) &&
        pred_filter_search &&
        (ref_frame == LAST_FRAME ||
         (ref_frame == GOLDEN_FRAME && !force_mv_inter_layer &&
          (cpi->use_svc || cpi->oxcf.rc_mode == VPX_VBR))) &&
        (((mi->mv[0].as_mv.row | mi->mv[0].as_mv.col) & 0x07) != 0)) {
      rd_computed = 1;
      search_filter_ref(cpi, x, &this_rdc, mi_row, mi_col, tmp, bsize,
                        reuse_inter_pred, &this_mode_pred, &var_y, &sse_y,
                        force_smooth_filter, &this_early_term,
                        flag_preduv_computed, use_model_yrd_large);
    } else {
      mi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP : filter_ref;

      if (cpi->use_svc && ref_frame == GOLDEN_FRAME &&
          svc_force_zero_mode[ref_frame - 1])
        mi->interp_filter = filter_gf_svc;

      vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);

      // For large partition blocks, extra testing is done.
      if (use_model_yrd_large) {
        rd_computed = 1;
        model_rd_for_sb_y_large(cpi, bsize, x, xd, &this_rdc.rate,
                                &this_rdc.dist, &var_y, &sse_y, mi_row, mi_col,
                                &this_early_term, flag_preduv_computed);
      } else {
        rd_computed = 1;
        model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
                          &var_y, &sse_y, 0);
      }
      // Save normalized sse (between current and last frame) for (0, 0) motion.
      if (ref_frame == LAST_FRAME &&
          frame_mv[this_mode][ref_frame].as_int == 0) {
        sse_zeromv_normalized =
            sse_y >> (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
      }
      if (sse_y < best_sse_sofar) best_sse_sofar = sse_y;
    }

    if (!this_early_term) {
      this_sse = (int64_t)sse_y;
      block_yrd(cpi, x, &this_rdc, &is_skippable, &this_sse, bsize,
                VPXMIN(mi->tx_size, TX_16X16), rd_computed, 0);
      x->skip_txfm[0] = is_skippable;
      if (is_skippable) {
        this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
      } else {
        if (RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist) <
            RDCOST(x->rdmult, x->rddiv, 0, this_sse)) {
          this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 0);
        } else {
          this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
          this_rdc.dist = this_sse;
          x->skip_txfm[0] = SKIP_TXFM_AC_DC;
        }
      }

      if (cm->interp_filter == SWITCHABLE) {
        if ((mi->mv[0].as_mv.row | mi->mv[0].as_mv.col) & 0x07)
          this_rdc.rate += vp9_get_switchable_rate(cpi, xd);
      }
    } else {
      if (cm->interp_filter == SWITCHABLE) {
        if ((mi->mv[0].as_mv.row | mi->mv[0].as_mv.col) & 0x07)
          this_rdc.rate += vp9_get_switchable_rate(cpi, xd);
      }
      this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);
    }

    if (!this_early_term &&
        (x->color_sensitivity[0] || x->color_sensitivity[1])) {
      RD_COST rdc_uv;
      const BLOCK_SIZE uv_bsize = get_plane_block_size(bsize, &xd->plane[1]);
      if (x->color_sensitivity[0] && !flag_preduv_computed[0]) {
        vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 1);
        flag_preduv_computed[0] = 1;
      }
      if (x->color_sensitivity[1] && !flag_preduv_computed[1]) {
        vp9_build_inter_predictors_sbp(xd, mi_row, mi_col, bsize, 2);
        flag_preduv_computed[1] = 1;
      }
      model_rd_for_sb_uv(cpi, uv_bsize, x, xd, &rdc_uv, &var_y, &sse_y, 1, 2);
      this_rdc.rate += rdc_uv.rate;
      this_rdc.dist += rdc_uv.dist;
    }

    this_rdc.rate += rate_mv;
    this_rdc.rate += cpi->inter_mode_cost[x->mbmi_ext->mode_context[ref_frame]]
                                         [INTER_OFFSET(this_mode)];
    // TODO(marpan): Add costing for compound mode.
    this_rdc.rate += ref_frame_cost[ref_frame];
    this_rdc.rdcost = RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);

    // Bias against NEWMV that is very different from its neighbors, and bias
    // to small motion-lastref for noisy input.
    if (cpi->oxcf.rc_mode == VPX_CBR && cpi->oxcf.speed >= 5 &&
        cpi->oxcf.content != VP9E_CONTENT_SCREEN) {
      vp9_NEWMV_diff_bias(&cpi->noise_estimate, xd, this_mode, &this_rdc, bsize,
                          frame_mv[this_mode][ref_frame].as_mv.row,
                          frame_mv[this_mode][ref_frame].as_mv.col,
                          ref_frame == LAST_FRAME, x->lowvar_highsumdiff,
                          x->sb_is_skin);
    }

    // Skipping checking: test to see if this block can be reconstructed by
    // prediction only.
    if (cpi->allow_encode_breakout && !xd->lossless && !scene_change_detected &&
        !svc->high_num_blocks_with_motion) {
      encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame, this_mode,
                           var_y, sse_y, yv12_mb, &this_rdc.rate,
                           &this_rdc.dist, flag_preduv_computed);
      if (x->skip) {
        this_rdc.rate += rate_mv;
        this_rdc.rdcost =
            RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);
      }
    }

    // On spatially flat blocks for screne content: bias against zero-last
    // if the sse_y is non-zero. Only on scene change or high motion frames.
    if (cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
        (scene_change_detected || svc->high_num_blocks_with_motion) &&
        ref_frame == LAST_FRAME && frame_mv[this_mode][ref_frame].as_int == 0 &&
        svc->spatial_layer_id == 0 && x->source_variance == 0 && sse_y > 0) {
      this_rdc.rdcost = this_rdc.rdcost << 2;
    }

#if CONFIG_VP9_TEMPORAL_DENOISING
    if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc_pickmode &&
        cpi->denoiser.denoising_level > kDenLowLow) {
      vp9_denoiser_update_frame_stats(mi, sse_y, this_mode, ctx);
      // Keep track of zero_last cost.
      if (ref_frame == LAST_FRAME && frame_mv[this_mode][ref_frame].as_int == 0)
        zero_last_cost_orig = this_rdc.rdcost;
    }
#else
    (void)ctx;
#endif

    mode_checked[this_mode][ref_frame] = 1;

    if (this_rdc.rdcost < best_rdc.rdcost || x->skip) {
      best_rdc = this_rdc;
      best_early_term = this_early_term;
      best_pickmode.best_mode = this_mode;
      best_pickmode.best_pred_filter = mi->interp_filter;
      best_pickmode.best_tx_size = mi->tx_size;
      best_pickmode.best_ref_frame = ref_frame;
      best_pickmode.best_mode_skip_txfm = x->skip_txfm[0];
      best_pickmode.best_second_ref_frame = second_ref_frame;

      if (reuse_inter_pred) {
        free_pred_buffer(best_pickmode.best_pred);
        best_pickmode.best_pred = this_mode_pred;
      }
    } else {
      if (reuse_inter_pred) free_pred_buffer(this_mode_pred);
    }

    if (x->skip &&
        (!force_test_gf_zeromv || mode_checked[ZEROMV][GOLDEN_FRAME]))
      break;

    // If early termination flag is 1 and at least 2 modes are checked,
    // the mode search is terminated.
    if (best_early_term && idx > 0 && !scene_change_detected &&
        (!force_test_gf_zeromv || mode_checked[ZEROMV][GOLDEN_FRAME])) {
      x->skip = 1;
      break;
    }
  }

  mi->mode = best_pickmode.best_mode;
  mi->interp_filter = best_pickmode.best_pred_filter;
  mi->tx_size = best_pickmode.best_tx_size;
  mi->ref_frame[0] = best_pickmode.best_ref_frame;
  mi->mv[0].as_int =
      frame_mv[best_pickmode.best_mode][best_pickmode.best_ref_frame].as_int;
  xd->mi[0]->bmi[0].as_mv[0].as_int = mi->mv[0].as_int;
  x->skip_txfm[0] = best_pickmode.best_mode_skip_txfm;
  mi->ref_frame[1] = best_pickmode.best_second_ref_frame;

  // For spatial enhancemanent layer: perform intra prediction only if base
  // layer is chosen as the reference. Always perform intra prediction if
  // LAST is the only reference, or is_key_frame is set, or on base
  // temporal layer.
  if (svc->spatial_layer_id && !gf_temporal_ref) {
    perform_intra_pred =
        svc->temporal_layer_id == 0 ||
        svc->layer_context[svc->temporal_layer_id].is_key_frame ||
        !(cpi->ref_frame_flags & VP9_GOLD_FLAG) ||
        (!svc->layer_context[svc->temporal_layer_id].is_key_frame &&
         svc_force_zero_mode[best_pickmode.best_ref_frame - 1]);
    inter_mode_thresh = (inter_mode_thresh << 1) + inter_mode_thresh;
  }
  if ((cpi->oxcf.lag_in_frames > 0 && cpi->oxcf.rc_mode == VPX_VBR &&
       cpi->rc.is_src_frame_alt_ref) ||
      svc->previous_frame_is_intra_only)
    perform_intra_pred = 0;

  // If the segment reference frame feature is enabled and set then
  // skip the intra prediction.
  if (segfeature_active(seg, mi->segment_id, SEG_LVL_REF_FRAME) &&
      get_segdata(seg, mi->segment_id, SEG_LVL_REF_FRAME) > 0)
    perform_intra_pred = 0;

  // Perform intra prediction search, if the best SAD is above a certain
  // threshold.
  if (best_rdc.rdcost == INT64_MAX ||
      (cpi->oxcf.content == VP9E_CONTENT_SCREEN && x->source_variance == 0) ||
      (scene_change_detected && perform_intra_pred) ||
      ((!force_skip_low_temp_var || bsize < BLOCK_32X32 ||
        x->content_state_sb == kVeryHighSad) &&
       perform_intra_pred && !x->skip && best_rdc.rdcost > inter_mode_thresh &&
       bsize <= cpi->sf.max_intra_bsize && !x->skip_low_source_sad &&
       !x->lowvar_highsumdiff)) {
    struct estimate_block_intra_args args = { cpi, x, DC_PRED, 1, 0 };
    int64_t this_sse = INT64_MAX;
    int i;
    PRED_BUFFER *const best_pred = best_pickmode.best_pred;
    TX_SIZE intra_tx_size =
        VPXMIN(max_txsize_lookup[bsize],
               tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);

    if (reuse_inter_pred && best_pred != NULL) {
      if (best_pred->data == orig_dst.buf) {
        this_mode_pred = &tmp[get_pred_buffer(tmp, 3)];
#if CONFIG_VP9_HIGHBITDEPTH
        if (cm->use_highbitdepth)
          vpx_highbd_convolve_copy(
              CONVERT_TO_SHORTPTR(best_pred->data), best_pred->stride,
              CONVERT_TO_SHORTPTR(this_mode_pred->data), this_mode_pred->stride,
              NULL, 0, 0, 0, 0, bw, bh, xd->bd);
        else
          vpx_convolve_copy(best_pred->data, best_pred->stride,
                            this_mode_pred->data, this_mode_pred->stride, NULL,
                            0, 0, 0, 0, bw, bh);
#else
        vpx_convolve_copy(best_pred->data, best_pred->stride,
                          this_mode_pred->data, this_mode_pred->stride, NULL, 0,
                          0, 0, 0, bw, bh);
#endif  // CONFIG_VP9_HIGHBITDEPTH
        best_pickmode.best_pred = this_mode_pred;
      }
    }
    pd->dst = orig_dst;

    for (i = 0; i < 4; ++i) {
      const PREDICTION_MODE this_mode = intra_mode_list[i];
      THR_MODES mode_index = mode_idx[INTRA_FRAME][mode_offset(this_mode)];
      int mode_rd_thresh = rd_threshes[mode_index];
      // For spatially flat blocks, under short_circuit_flat_blocks flag:
      // only check DC mode for stationary blocks, otherwise also check
      // H and V mode.
      if (sf->short_circuit_flat_blocks && x->source_variance == 0 &&
          ((x->zero_temp_sad_source && this_mode != DC_PRED) || i > 2)) {
        continue;
      }

      if (!((1 << this_mode) & cpi->sf.intra_y_mode_bsize_mask[bsize]))
        continue;

      if (cpi->sf.rt_intra_dc_only_low_content && this_mode != DC_PRED &&
          x->content_state_sb != kVeryHighSad)
        continue;

      if ((cpi->sf.adaptive_rd_thresh_row_mt &&
           rd_less_than_thresh_row_mt(best_rdc.rdcost, mode_rd_thresh,
                                      &rd_thresh_freq_fact[mode_index])) ||
          (!cpi->sf.adaptive_rd_thresh_row_mt &&
           rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
                               &rd_thresh_freq_fact[mode_index]))) {
        // Avoid this early exit for screen on base layer, for scene
        // changes or high motion frames.
        if (cpi->oxcf.content != VP9E_CONTENT_SCREEN ||
            svc->spatial_layer_id > 0 ||
            (!scene_change_detected && !svc->high_num_blocks_with_motion))
          continue;
      }

      mi->mode = this_mode;
      mi->ref_frame[0] = INTRA_FRAME;
      this_rdc.dist = this_rdc.rate = 0;
      args.mode = this_mode;
      args.skippable = 1;
      args.rdc = &this_rdc;
      mi->tx_size = intra_tx_size;

      compute_intra_yprediction(this_mode, bsize, x, xd);
      model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
                        &var_y, &sse_y, 1);
      block_yrd(cpi, x, &this_rdc, &args.skippable, &this_sse, bsize,
                VPXMIN(mi->tx_size, TX_16X16), 1, 1);

      // Check skip cost here since skippable is not set for for uv, this
      // mirrors the behavior used by inter
      if (args.skippable) {
        x->skip_txfm[0] = SKIP_TXFM_AC_DC;
        this_rdc.rate = vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), 1);
      } else {
        x->skip_txfm[0] = SKIP_TXFM_NONE;
        this_rdc.rate += vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), 0);
      }
      // Inter and intra RD will mismatch in scale for non-screen content.
      if (cpi->oxcf.content == VP9E_CONTENT_SCREEN) {
        if (x->color_sensitivity[0])
          vp9_foreach_transformed_block_in_plane(xd, bsize, 1,
                                                 estimate_block_intra, &args);
        if (x->color_sensitivity[1])
          vp9_foreach_transformed_block_in_plane(xd, bsize, 2,
                                                 estimate_block_intra, &args);
      }
      this_rdc.rate += cpi->mbmode_cost[this_mode];
      this_rdc.rate += ref_frame_cost[INTRA_FRAME];
      this_rdc.rate += intra_cost_penalty;
      this_rdc.rdcost =
          RDCOST(x->rdmult, x->rddiv, this_rdc.rate, this_rdc.dist);

      if (this_rdc.rdcost < best_rdc.rdcost) {
        best_rdc = this_rdc;
        best_pickmode.best_mode = this_mode;
        best_pickmode.best_intra_tx_size = mi->tx_size;
        best_pickmode.best_ref_frame = INTRA_FRAME;
        best_pickmode.best_second_ref_frame = NO_REF_FRAME;
        mi->uv_mode = this_mode;
        mi->mv[0].as_int = INVALID_MV;
        mi->mv[1].as_int = INVALID_MV;
        best_pickmode.best_mode_skip_txfm = x->skip_txfm[0];
      }
    }

    // Reset mb_mode_info to the best inter mode.
    if (best_pickmode.best_ref_frame != INTRA_FRAME) {
      mi->tx_size = best_pickmode.best_tx_size;
    } else {
      mi->tx_size = best_pickmode.best_intra_tx_size;
    }
  }

  pd->dst = orig_dst;
  mi->mode = best_pickmode.best_mode;
  mi->ref_frame[0] = best_pickmode.best_ref_frame;
  mi->ref_frame[1] = best_pickmode.best_second_ref_frame;
  x->skip_txfm[0] = best_pickmode.best_mode_skip_txfm;

  if (!is_inter_block(mi)) {
    mi->interp_filter = SWITCHABLE_FILTERS;
  }

  if (reuse_inter_pred && best_pickmode.best_pred != NULL) {
    PRED_BUFFER *const best_pred = best_pickmode.best_pred;
    if (best_pred->data != orig_dst.buf && is_inter_mode(mi->mode)) {
#if CONFIG_VP9_HIGHBITDEPTH
      if (cm->use_highbitdepth)
        vpx_highbd_convolve_copy(
            CONVERT_TO_SHORTPTR(best_pred->data), best_pred->stride,
            CONVERT_TO_SHORTPTR(pd->dst.buf), pd->dst.stride, NULL, 0, 0, 0, 0,
            bw, bh, xd->bd);
      else
        vpx_convolve_copy(best_pred->data, best_pred->stride, pd->dst.buf,
                          pd->dst.stride, NULL, 0, 0, 0, 0, bw, bh);
#else
      vpx_convolve_copy(best_pred->data, best_pred->stride, pd->dst.buf,
                        pd->dst.stride, NULL, 0, 0, 0, 0, bw, bh);
#endif  // CONFIG_VP9_HIGHBITDEPTH
    }
  }

#if CONFIG_VP9_TEMPORAL_DENOISING
  if (cpi->oxcf.noise_sensitivity > 0 && cpi->resize_pending == 0 &&
      denoise_svc_pickmode && cpi->denoiser.denoising_level > kDenLowLow &&
      cpi->denoiser.reset == 0) {
    VP9_DENOISER_DECISION decision = COPY_BLOCK;
    ctx->sb_skip_denoising = 0;
    // TODO(marpan): There is an issue with denoising when the
    // superblock partitioning scheme is based on the pickmode.
    // Remove this condition when the issue is resolved.
    if (x->sb_pickmode_part) ctx->sb_skip_denoising = 1;
    vp9_pickmode_ctx_den_update(&ctx_den, zero_last_cost_orig, ref_frame_cost,
                                frame_mv, reuse_inter_pred, &best_pickmode);
    vp9_denoiser_denoise(cpi, x, mi_row, mi_col, bsize, ctx, &decision,
                         gf_temporal_ref);
    if (denoise_recheck_zeromv)
      recheck_zeromv_after_denoising(cpi, mi, x, xd, decision, &ctx_den,
                                     yv12_mb, &best_rdc, bsize, mi_row, mi_col);
    best_pickmode.best_ref_frame = ctx_den.best_ref_frame;
  }
#endif

  if (best_pickmode.best_ref_frame == ALTREF_FRAME ||
      best_pickmode.best_second_ref_frame == ALTREF_FRAME)
    x->arf_frame_usage++;
  else if (best_pickmode.best_ref_frame != INTRA_FRAME)
    x->lastgolden_frame_usage++;

  if (cpi->sf.adaptive_rd_thresh) {
    THR_MODES best_mode_idx =
        mode_idx[best_pickmode.best_ref_frame][mode_offset(mi->mode)];

    if (best_pickmode.best_ref_frame == INTRA_FRAME) {
      // Only consider the modes that are included in the intra_mode_list.
      int intra_modes = sizeof(intra_mode_list) / sizeof(PREDICTION_MODE);
      int i;

      // TODO(yunqingwang): Check intra mode mask and only update freq_fact
      // for those valid modes.
      for (i = 0; i < intra_modes; i++) {
        if (cpi->sf.adaptive_rd_thresh_row_mt)
          update_thresh_freq_fact_row_mt(cpi, tile_data, x->source_variance,
                                         thresh_freq_fact_idx, INTRA_FRAME,
                                         best_mode_idx, intra_mode_list[i]);
        else
          update_thresh_freq_fact(cpi, tile_data, x->source_variance, bsize,
                                  INTRA_FRAME, best_mode_idx,
                                  intra_mode_list[i]);
      }
    } else {
      for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) {
        PREDICTION_MODE this_mode;
        if (best_pickmode.best_ref_frame != ref_frame) continue;
        for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
          if (cpi->sf.adaptive_rd_thresh_row_mt)
            update_thresh_freq_fact_row_mt(cpi, tile_data, x->source_variance,
                                           thresh_freq_fact_idx, ref_frame,
                                           best_mode_idx, this_mode);
          else
            update_thresh_freq_fact(cpi, tile_data, x->source_variance, bsize,
                                    ref_frame, best_mode_idx, this_mode);
        }
      }
    }
  }

  *rd_cost = best_rdc;
}