vp9_pickmode.c 18.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 *  Copyright (c) 2014 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>
12 13 14
#include <limits.h>
#include <math.h>
#include <stdio.h>
15

16 17 18 19 20 21
#include "./vp9_rtcd.h"

#include "vpx_mem/vpx_mem.h"

#include "vp9/common/vp9_common.h"
#include "vp9/common/vp9_mvref_common.h"
22 23
#include "vp9/common/vp9_reconinter.h"
#include "vp9/common/vp9_reconintra.h"
24

Dmitry Kovalev's avatar
Dmitry Kovalev committed
25
#include "vp9/encoder/vp9_encoder.h"
26
#include "vp9/encoder/vp9_ratectrl.h"
27
#include "vp9/encoder/vp9_rdopt.h"
28

Yunqing Wang's avatar
Yunqing Wang committed
29
static void full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
30
                                    BLOCK_SIZE bsize, int mi_row, int mi_col,
31
                                    int_mv *tmp_mv, int *rate_mv) {
32
  MACROBLOCKD *xd = &x->e_mbd;
33
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
34
  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
Deb Mukherjee's avatar
Deb Mukherjee committed
35
  int step_param;
36 37 38
  int sadpb = x->sadperbit16;
  MV mvp_full;
  int ref = mbmi->ref_frame[0];
39
  const MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
40 41 42 43 44 45 46
  int i;

  int tmp_col_min = x->mv_col_min;
  int tmp_col_max = x->mv_col_max;
  int tmp_row_min = x->mv_row_min;
  int tmp_row_max = x->mv_row_max;

47 48
  const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
                                                                        ref);
49 50 51 52 53 54 55 56
  if (scaled_ref_frame) {
    int i;
    // Swap out the reference frame for a version that's been scaled to
    // match the resolution of the current frame, allowing the existing
    // motion search code to be used without additional modifications.
    for (i = 0; i < MAX_MB_PLANE; i++)
      backup_yv12[i] = xd->plane[i].pre[0];

57
    vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
58 59
  }

60
  vp9_set_mv_search_range(x, &ref_mv);
61 62 63 64 65

  // TODO(jingning) exploiting adaptive motion search control in non-RD
  // mode decision too.
  step_param = 6;

Jim Bankoski's avatar
Jim Bankoski committed
66
  for (i = LAST_FRAME; i <= LAST_FRAME && cpi->common.show_frame; ++i) {
67 68 69 70 71 72 73 74
    if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) {
      tmp_mv->as_int = INVALID_MV;

      if (scaled_ref_frame) {
        int i;
        for (i = 0; i < MAX_MB_PLANE; i++)
          xd->plane[i].pre[0] = backup_yv12[i];
      }
Yunqing Wang's avatar
Yunqing Wang committed
75
      return;
76 77
    }
  }
Yaowu Xu's avatar
Yaowu Xu committed
78 79 80 81
  assert(x->mv_best_ref_index[ref] <= 2);
  if (x->mv_best_ref_index[ref] < 2)
    mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv;
  else
Dmitry Kovalev's avatar
Dmitry Kovalev committed
82
    mvp_full = x->pred_mv[ref];
83 84 85 86

  mvp_full.col >>= 3;
  mvp_full.row >>= 3;

87 88
  vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param, sadpb, &ref_mv,
                        &tmp_mv->as_mv, INT_MAX, 0);
89

90 91 92 93 94 95 96 97 98 99
  x->mv_col_min = tmp_col_min;
  x->mv_col_max = tmp_col_max;
  x->mv_row_min = tmp_row_min;
  x->mv_row_max = tmp_row_max;

  if (scaled_ref_frame) {
    int i;
    for (i = 0; i < MAX_MB_PLANE; i++)
      xd->plane[i].pre[0] = backup_yv12[i];
  }
100 101 102 103 104 105

  // calculate the bit cost on motion vector
  mvp_full.row = tmp_mv->as_mv.row * 8;
  mvp_full.col = tmp_mv->as_mv.col * 8;
  *rate_mv = vp9_mv_bit_cost(&mvp_full, &ref_mv,
                             x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
106
}
107

108 109
static void sub_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
                                    BLOCK_SIZE bsize, int mi_row, int mi_col,
110
                                    MV *tmp_mv) {
111
  MACROBLOCKD *xd = &x->e_mbd;
112
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
113
  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0, 0}};
114
  int ref = mbmi->ref_frame[0];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
115
  MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
116
  int dis;
117

118 119 120 121 122 123 124 125 126 127
  const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
                                                                        ref);
  if (scaled_ref_frame) {
    int i;
    // Swap out the reference frame for a version that's been scaled to
    // match the resolution of the current frame, allowing the existing
    // motion search code to be used without additional modifications.
    for (i = 0; i < MAX_MB_PLANE; i++)
      backup_yv12[i] = xd->plane[i].pre[0];

128
    vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
129 130
  }

Dmitry Kovalev's avatar
Dmitry Kovalev committed
131
  cpi->find_fractional_mv_step(x, tmp_mv, &ref_mv,
132 133 134
                               cpi->common.allow_high_precision_mv,
                               x->errorperbit,
                               &cpi->fn_ptr[bsize],
135 136
                               cpi->sf.mv.subpel_force_stop,
                               cpi->sf.mv.subpel_iters_per_step,
137 138 139 140 141 142 143 144
                               x->nmvjointcost, x->mvcost,
                               &dis, &x->pred_sse[ref]);

  if (scaled_ref_frame) {
    int i;
    for (i = 0; i < MAX_MB_PLANE; i++)
      xd->plane[i].pre[0] = backup_yv12[i];
  }
145

Dmitry Kovalev's avatar
Dmitry Kovalev committed
146
  x->pred_mv[ref] = *tmp_mv;
147 148
}

149 150
static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize,
                              MACROBLOCK *x, MACROBLOCKD *xd,
151 152
                              int *out_rate_sum, int64_t *out_dist_sum,
                              unsigned int *var_y, unsigned int *sse_y) {
153 154 155 156
  // 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;
157 158
  int rate;
  int64_t dist;
159 160
  struct macroblock_plane *const p = &x->plane[0];
  struct macroblockd_plane *const pd = &xd->plane[0];
161 162
  const uint32_t dc_quant = pd->dequant[0];
  const uint32_t ac_quant = pd->dequant[1];
163 164
  unsigned int var = cpi->fn_ptr[bsize].vf(p->src.buf, p->src.stride,
                                           pd->dst.buf, pd->dst.stride, &sse);
165 166 167
  *var_y = var;
  *sse_y = sse;

168
  if (sse < dc_quant * dc_quant >> 6)
169
    x->skip_txfm = 1;
170
  else if (var < ac_quant * ac_quant >> 6)
171 172 173 174
    x->skip_txfm = 2;
  else
    x->skip_txfm = 0;

175 176 177
  vp9_model_rd_from_var_lapndz(sse - var, 1 << num_pels_log2_lookup[bsize],
                               dc_quant >> 3, &rate, &dist);
  *out_rate_sum = rate >> 1;
178
  *out_dist_sum = dist << 3;
179 180 181 182 183

  vp9_model_rd_from_var_lapndz(var, 1 << num_pels_log2_lookup[bsize],
                               ac_quant >> 3, &rate, &dist);
  *out_rate_sum += rate;
  *out_dist_sum += dist << 4;
184 185
}

186 187 188 189 190 191 192
// 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,
                            const TileInfo *const tile,
                            int mi_row, int mi_col,
                            int *returnrate,
                            int64_t *returndistortion,
Jim Bankoski's avatar
Jim Bankoski committed
193
                            BLOCK_SIZE bsize) {
194
  MACROBLOCKD *xd = &x->e_mbd;
195
  MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
196 197
  struct macroblock_plane *const p = &x->plane[0];
  struct macroblockd_plane *const pd = &xd->plane[0];
198
  PREDICTION_MODE this_mode, best_mode = ZEROMV;
199
  MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
200
  INTERP_FILTER best_pred_filter = EIGHTTAP;
201 202 203 204 205
  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
  struct buf_2d yv12_mb[4][MAX_MB_PLANE];
  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
                                    VP9_ALT_FLAG };
  int64_t best_rd = INT64_MAX;
206
  int64_t this_rd = INT64_MAX;
207
  int skip_txfm = 0;
208

209 210
  int rate = INT_MAX;
  int64_t dist = INT64_MAX;
211 212 213
  // 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;
214

215 216 217 218 219 220 221
  VP9_COMMON *cm = &cpi->common;
  int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);

  const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
                                           intra_cost_penalty, 0);
  const int64_t intra_mode_cost = 50;

222
  unsigned char segment_id = mbmi->segment_id;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
223 224
  const int *const rd_threshes = cpi->rd.threshes[segment_id][bsize];
  const int *const rd_thresh_freq_fact = cpi->rd.thresh_freq_fact[bsize];
225
  // Mode index conversion form THR_MODES to PREDICTION_MODE for a ref frame.
226
  int mode_idx[MB_MODE_COUNT] = {0};
227
  INTERP_FILTER filter_ref = SWITCHABLE;
228
  int bsl = mi_width_log2_lookup[bsize];
229 230
  const int pred_filter_search = (((mi_row + mi_col) >> bsl) +
                                      get_chessboard_index(cm)) % 2;
231

232 233 234
  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;

  x->skip = 0;
235

236 237
  // initialize mode decisions
  *returnrate = INT_MAX;
238
  *returndistortion = INT64_MAX;
239 240 241 242 243
  vpx_memset(mbmi, 0, sizeof(MB_MODE_INFO));
  mbmi->sb_type = bsize;
  mbmi->ref_frame[0] = NONE;
  mbmi->ref_frame[1] = NONE;
  mbmi->tx_size = MIN(max_txsize_lookup[bsize],
244 245 246
                      tx_mode_to_biggest_tx_size[cm->tx_mode]);
  mbmi->interp_filter = cm->interp_filter == SWITCHABLE ?
                        EIGHTTAP : cm->interp_filter;
247
  mbmi->skip = 0;
248
  mbmi->segment_id = segment_id;
249

Jim Bankoski's avatar
Jim Bankoski committed
250
  for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
251 252
    x->pred_mv_sad[ref_frame] = INT_MAX;
    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
253
      vp9_setup_buffer_inter(cpi, x, tile,
254
                             ref_frame, bsize, mi_row, mi_col,
255 256 257 258 259 260
                             frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
    }
    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
    frame_mv[ZEROMV][ref_frame].as_int = 0;
  }

261 262 263 264 265
  if (xd->up_available)
    filter_ref = xd->mi[-xd->mi_stride]->mbmi.interp_filter;
  else if (xd->left_available)
    filter_ref = xd->mi[-1]->mbmi.interp_filter;

Jim Bankoski's avatar
Jim Bankoski committed
266
  for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
267 268 269 270 271 272 273 274 275
    if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
      continue;

    // Select prediction reference frames.
    xd->plane[0].pre[0] = yv12_mb[ref_frame][0];

    clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd);
    clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd);

276 277
    mbmi->ref_frame[0] = ref_frame;

278 279 280 281 282 283 284 285
    // Set conversion index for LAST_FRAME.
    if (ref_frame == LAST_FRAME) {
      mode_idx[NEARESTMV] = THR_NEARESTMV;   // LAST_FRAME, NEARESTMV
      mode_idx[NEARMV] = THR_NEARMV;         // LAST_FRAME, NEARMV
      mode_idx[ZEROMV] = THR_ZEROMV;         // LAST_FRAME, ZEROMV
      mode_idx[NEWMV] = THR_NEWMV;           // LAST_FRAME, NEWMV
    }

286
    for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
287 288
      int rate_mv = 0;

289
      if (!(cpi->sf.inter_mode_mask[bsize] & (1 << this_mode)))
290
        continue;
Jim Bankoski's avatar
Jim Bankoski committed
291

292 293
      if (rd_less_than_thresh(best_rd, rd_threshes[mode_idx[this_mode]],
                              rd_thresh_freq_fact[this_mode]))
294 295
        continue;

Jim Bankoski's avatar
Jim Bankoski committed
296
      if (this_mode == NEWMV) {
297
        int rate_mode = 0;
298
        if (this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize]))
299 300
          continue;

301
        full_pixel_motion_search(cpi, x, bsize, mi_row, mi_col,
302
                                 &frame_mv[NEWMV][ref_frame], &rate_mv);
Jim Bankoski's avatar
Jim Bankoski committed
303 304 305

        if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV)
          continue;
306

307 308
        rate_mode = cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
                                        [INTER_OFFSET(this_mode)];
309 310 311
        if (RDCOST(x->rdmult, x->rddiv, rate_mv + rate_mode, 0) > best_rd)
          continue;

312
        sub_pixel_motion_search(cpi, x, bsize, mi_row, mi_col,
313
                                &frame_mv[NEWMV][ref_frame].as_mv);
Jim Bankoski's avatar
Jim Bankoski committed
314 315
      }

316 317 318 319 320
      if (this_mode != NEARESTMV)
        if (frame_mv[this_mode][ref_frame].as_int ==
            frame_mv[NEARESTMV][ref_frame].as_int)
          continue;

321 322
      mbmi->mode = this_mode;
      mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
323

324 325 326 327
      // 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 ((this_mode == NEWMV || filter_ref == SWITCHABLE) &&
328
          pred_filter_search &&
329 330 331 332
          ((mbmi->mv[0].as_mv.row & 0x07) != 0 ||
           (mbmi->mv[0].as_mv.col & 0x07) != 0)) {
        int pf_rate[3];
        int64_t pf_dist[3];
333 334
        unsigned int pf_var[3];
        unsigned int pf_sse[3];
335 336 337 338 339 340 341 342
        int64_t best_cost = INT64_MAX;
        INTERP_FILTER best_filter = SWITCHABLE, filter;

        for (filter = EIGHTTAP; filter <= EIGHTTAP_SHARP; ++filter) {
          int64_t cost;
          mbmi->interp_filter = filter;
          vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
          model_rd_for_sb_y(cpi, bsize, x, xd, &pf_rate[filter],
343
                            &pf_dist[filter], &pf_var[filter], &pf_sse[filter]);
344 345 346 347 348 349
          cost = RDCOST(x->rdmult, x->rddiv,
                        vp9_get_switchable_rate(cpi) + pf_rate[filter],
                        pf_dist[filter]);
          if (cost < best_cost) {
              best_filter = filter;
              best_cost = cost;
350
              skip_txfm = x->skip_txfm;
351
          }
352 353
        }

354
        mbmi->interp_filter = best_filter;
355 356
        rate = pf_rate[mbmi->interp_filter];
        dist = pf_dist[mbmi->interp_filter];
357 358
        var_y = pf_var[mbmi->interp_filter];
        sse_y = pf_sse[mbmi->interp_filter];
359
        x->skip_txfm = skip_txfm;
360 361 362
      } else {
        mbmi->interp_filter = (filter_ref == SWITCHABLE) ? EIGHTTAP: filter_ref;
        vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
363
        model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist, &var_y, &sse_y);
364 365
      }

366
      rate += rate_mv;
367
      rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
368 369
                                [INTER_OFFSET(this_mode)];
      this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
370

371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
      // Skipping checking: test to see if this block can be reconstructed by
      // prediction only.
      if (!x->in_active_map) {
        x->skip = 1;
      } else if (cpi->allow_encode_breakout && x->encode_breakout) {
        const BLOCK_SIZE uv_size = get_plane_block_size(bsize, &xd->plane[1]);
        unsigned int var = var_y, sse = sse_y;
        // Skipping threshold for ac.
        unsigned int thresh_ac;
        // Skipping threshold for dc.
        unsigned int thresh_dc;
        // Set a maximum for threshold to avoid big PSNR loss in low bit rate
        // case. Use extreme low threshold for static frames to limit skipping.
        const unsigned int max_thresh = 36000;
        // The encode_breakout input
        const unsigned int min_thresh =
            MIN(((unsigned int)x->encode_breakout << 4), max_thresh);

        // Calculate threshold according to dequant value.
        thresh_ac = (xd->plane[0].dequant[1] * xd->plane[0].dequant[1]) / 9;
        thresh_ac = clamp(thresh_ac, min_thresh, max_thresh);

        // Adjust ac threshold according to partition size.
        thresh_ac >>= 8 - (b_width_log2_lookup[bsize] +
            b_height_log2_lookup[bsize]);

        thresh_dc = (xd->plane[0].dequant[0] * xd->plane[0].dequant[0] >> 6);

        // Y skipping condition checking for ac and dc.
        if (var <= thresh_ac && (sse - var) <= thresh_dc) {
          unsigned int sse_u, sse_v;
          unsigned int var_u, var_v;

          // Skip u v prediction for less calculation, that won't affect
          // result much.
          var_u = cpi->fn_ptr[uv_size].vf(x->plane[1].src.buf,
                                          x->plane[1].src.stride,
                                          xd->plane[1].dst.buf,
                                          xd->plane[1].dst.stride, &sse_u);

          // U skipping condition checking
          if ((var_u * 4 <= thresh_ac) && (sse_u - var_u <= thresh_dc)) {
            var_v = cpi->fn_ptr[uv_size].vf(x->plane[2].src.buf,
                                            x->plane[2].src.stride,
                                            xd->plane[2].dst.buf,
                                            xd->plane[2].dst.stride, &sse_v);

            // V skipping condition checking
            if ((var_v * 4 <= thresh_ac) && (sse_v - var_v <= thresh_dc)) {
              x->skip = 1;

              // The cost of skip bit needs to be added.
              rate = rate_mv;
              rate += cpi->inter_mode_cost[mbmi->mode_context[ref_frame]]
                                           [INTER_OFFSET(this_mode)];

              // More on this part of rate
              // rate += vp9_cost_bit(vp9_get_skip_prob(cm, xd), 1);

              // Scaling factor for SSE from spatial domain to frequency
              // domain is 16. Adjust distortion accordingly.
              // TODO(yunqingwang): In this function, only y-plane dist is
              // calculated.
              dist = (sse << 4);  // + ((sse_u + sse_v) << 4);
              this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
              // *disable_skip = 1;
            }
          }
        }
      }

Tim Kopp's avatar
Tim Kopp committed
442 443 444 445
#if CONFIG_DENOISING
    vp9_denoiser_update_frame_stats();
#endif

446
      if (this_rd < best_rd || x->skip) {
447
        best_rd = this_rd;
448 449
        *returnrate = rate;
        *returndistortion = dist;
450
        best_mode = this_mode;
451
        best_pred_filter = mbmi->interp_filter;
452
        best_ref_frame = ref_frame;
453
        skip_txfm = x->skip_txfm;
454
      }
455 456 457

      if (x->skip)
        break;
458 459 460
    }
  }

Tim Kopp's avatar
Tim Kopp committed
461

462
  mbmi->mode = best_mode;
463
  mbmi->interp_filter = best_pred_filter;
464 465
  mbmi->ref_frame[0] = best_ref_frame;
  mbmi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
466
  xd->mi[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;
467
  x->skip_txfm = skip_txfm;
468

469 470
  // Perform intra prediction search, if the best SAD is above a certain
  // threshold.
471
  if (!x->skip && best_rd > inter_mode_thresh &&
472
      bsize <= cpi->sf.max_intra_bsize) {
473
    for (this_mode = DC_PRED; this_mode <= DC_PRED; ++this_mode) {
474 475 476 477 478
      vp9_predict_intra_block(xd, 0, b_width_log2(bsize),
                              mbmi->tx_size, this_mode,
                              &p->src.buf[0], p->src.stride,
                              &pd->dst.buf[0], pd->dst.stride, 0, 0, 0);

479
      model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist, &var_y, &sse_y);
480
      rate += cpi->mbmode_cost[this_mode];
481
      rate += intra_cost_penalty;
482
      this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
483 484 485

      if (this_rd + intra_mode_cost < best_rd) {
        best_rd = this_rd;
486 487
        *returnrate = rate;
        *returndistortion = dist;
488 489 490
        mbmi->mode = this_mode;
        mbmi->ref_frame[0] = INTRA_FRAME;
        mbmi->uv_mode = this_mode;
491
        mbmi->mv[0].as_int = INVALID_MV;
492 493
      } else {
        x->skip_txfm = skip_txfm;
494 495 496
      }
    }
  }
Tim Kopp's avatar
Tim Kopp committed
497
#if CONFIG_DENOISING
498
  vp9_denoiser_denoise(&cpi->denoiser, x, mi_row, mi_col, bsize);
Tim Kopp's avatar
Tim Kopp committed
499
#endif
500

501 502
  return INT64_MAX;
}