vp9_pickmode.c 12.6 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 25

#include "vp9/encoder/vp9_onyx_int.h"
26
#include "vp9/encoder/vp9_ratectrl.h"
27
#include "vp9/encoder/vp9_rdopt.h"
28 29

static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
30 31 32
                                    const TileInfo *const tile,
                                    BLOCK_SIZE bsize, int mi_row, int mi_col,
                                    int_mv *tmp_mv, int *rate_mv) {
33 34 35 36
  MACROBLOCKD *xd = &x->e_mbd;
  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
  int bestsme = INT_MAX;
Deb Mukherjee's avatar
Deb Mukherjee committed
37
  int step_param;
38 39 40
  int sadpb = x->sadperbit16;
  MV mvp_full;
  int ref = mbmi->ref_frame[0];
41
  const MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
42 43 44 45 46 47 48 49 50 51
  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;

  int buf_offset;
  int stride = xd->plane[0].pre[0].stride;

52 53
  const YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi,
                                                                        ref);
54 55 56 57 58 59 60 61 62 63 64
  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];

    setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
  }

65
  vp9_set_mv_search_range(x, &ref_mv);
66 67 68 69 70

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

Jim Bankoski's avatar
Jim Bankoski committed
71
  for (i = LAST_FRAME; i <= LAST_FRAME && cpi->common.show_frame; ++i) {
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
    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];
      }
      return INT_MAX;
    }
  }

  mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv;

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

89
  if (cpi->sf.search_method == FAST_HEX) {
Deb Mukherjee's avatar
Deb Mukherjee committed
90
    // NOTE: this returns SAD
Deb Mukherjee's avatar
Deb Mukherjee committed
91 92 93
    vp9_fast_hex_search(x, &mvp_full, step_param, sadpb, 0,
                        &cpi->fn_ptr[bsize], 1,
                        &ref_mv, &tmp_mv->as_mv);
94
  } else if (cpi->sf.search_method == HEX) {
Deb Mukherjee's avatar
Deb Mukherjee committed
95
    // NOTE: this returns SAD
Deb Mukherjee's avatar
Deb Mukherjee committed
96 97 98
    vp9_hex_search(x, &mvp_full, step_param, sadpb, 1,
                   &cpi->fn_ptr[bsize], 1,
                   &ref_mv, &tmp_mv->as_mv);
99
  } else if (cpi->sf.search_method == SQUARE) {
Deb Mukherjee's avatar
Deb Mukherjee committed
100
    // NOTE: this returns SAD
Deb Mukherjee's avatar
Deb Mukherjee committed
101 102 103
    vp9_square_search(x, &mvp_full, step_param, sadpb, 1,
                      &cpi->fn_ptr[bsize], 1,
                      &ref_mv, &tmp_mv->as_mv);
104
  } else if (cpi->sf.search_method == BIGDIA) {
Deb Mukherjee's avatar
Deb Mukherjee committed
105
    // NOTE: this returns SAD
Deb Mukherjee's avatar
Deb Mukherjee committed
106 107 108
    vp9_bigdia_search(x, &mvp_full, step_param, sadpb, 1,
                      &cpi->fn_ptr[bsize], 1,
                      &ref_mv, &tmp_mv->as_mv);
109
  } else {
Deb Mukherjee's avatar
Deb Mukherjee committed
110 111
    int further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
    // NOTE: this returns variance
Deb Mukherjee's avatar
Deb Mukherjee committed
112 113 114 115
    vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
                           sadpb, further_steps, 1,
                           &cpi->fn_ptr[bsize],
                           &ref_mv, &tmp_mv->as_mv);
116
  }
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
  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];
  }

  // TODO(jingning) This step can be merged into full pixel search step in the
  // re-designed log-diamond search
  buf_offset = tmp_mv->as_mv.row * stride + tmp_mv->as_mv.col;

  // Find sad for current vector.
  bestsme = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, x->plane[0].src.stride,
                                   xd->plane[0].pre[0].buf + buf_offset,
                                   stride, 0x7fffffff);

  // scale to 1/8 pixel resolution
Yaowu Xu's avatar
Yaowu Xu committed
138 139
  tmp_mv->as_mv.row = tmp_mv->as_mv.row * 8;
  tmp_mv->as_mv.col = tmp_mv->as_mv.col * 8;
140 141

  // calculate the bit cost on motion vector
142
  *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv,
143
                             x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
144 145
  return bestsme;
}
146

147 148 149
static void sub_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
                                    const TileInfo *const tile,
                                    BLOCK_SIZE bsize, int mi_row, int mi_col,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
150
                                    MV *tmp_mv) {
151 152 153 154
  MACROBLOCKD *xd = &x->e_mbd;
  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
  struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}};
  int ref = mbmi->ref_frame[0];
Dmitry Kovalev's avatar
Dmitry Kovalev committed
155
  MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
156
  int dis;
157

158 159 160 161 162 163 164 165 166 167 168 169 170
  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];

    setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
  }

Dmitry Kovalev's avatar
Dmitry Kovalev committed
171 172
  tmp_mv->col >>= 3;
  tmp_mv->row >>= 3;
173

Dmitry Kovalev's avatar
Dmitry Kovalev committed
174
  cpi->find_fractional_mv_step(x, tmp_mv, &ref_mv,
175 176 177 178 179 180 181 182 183 184 185 186 187
                               cpi->common.allow_high_precision_mv,
                               x->errorperbit,
                               &cpi->fn_ptr[bsize],
                               cpi->sf.subpel_force_stop,
                               cpi->sf.subpel_iters_per_step,
                               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];
  }
188 189
}

190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
static void model_rd_for_sb_y(VP9_COMP *cpi, BLOCK_SIZE bsize,
                              MACROBLOCK *x, MACROBLOCKD *xd,
                              int *out_rate_sum, int64_t *out_dist_sum) {
  // Note our transform coeffs are 8 times an orthogonal transform.
  // Hence quantizer step is also 8 times. To get effective quantizer
  // we need to divide by 8 before sending to modeling function.
  int64_t rate_sum = 0;
  int64_t dist_sum = 0;
  unsigned int sse;


  struct macroblock_plane *const p = &x->plane[0];
  struct macroblockd_plane *const pd = &xd->plane[0];
  const BLOCK_SIZE bs = get_plane_block_size(bsize, pd);

  (void) cpi->fn_ptr[bs].vf(p->src.buf, p->src.stride,
                            pd->dst.buf, pd->dst.stride, &sse);

  {
    int rate;
    int64_t dist;
    vp9_model_rd_from_var_lapndz(sse, 1 << num_pels_log2_lookup[bs],
                                 pd->dequant[1] >> 3, &rate, &dist);
    rate_sum += rate;
    dist_sum += dist;
  }


  *out_rate_sum = (int)rate_sum;
  *out_dist_sum = dist_sum << 4;
}

222 223 224 225 226 227 228
// 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
229
                            BLOCK_SIZE bsize) {
230 231
  MACROBLOCKD *xd = &x->e_mbd;
  MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi;
232 233
  struct macroblock_plane *const p = &x->plane[0];
  struct macroblockd_plane *const pd = &xd->plane[0];
234
  const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]);
235 236
  MB_PREDICTION_MODE this_mode, best_mode = ZEROMV;
  MV_REFERENCE_FRAME ref_frame, best_ref_frame = LAST_FRAME;
237 238 239 240 241
  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;
242
  int64_t this_rd = INT64_MAX;
243

244 245 246
  const int64_t inter_mode_thresh = 300;
  const int64_t intra_mode_cost = 50;

247 248 249
  int rate = INT_MAX;
  int64_t dist = INT64_MAX;

250 251 252 253 254 255 256 257
  x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;

  x->skip = 0;
  if (cpi->active_map_enabled && x->active_ptr[0] == 0)
    x->skip = 1;

  // initialize mode decisions
  *returnrate = INT_MAX;
258
  *returndistortion = INT64_MAX;
259 260 261 262 263 264
  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],
                      tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
265 266
  mbmi->interp_filter = cpi->common.interp_filter == SWITCHABLE ?
                        EIGHTTAP : cpi->common.interp_filter;
267
  mbmi->skip = 0;
268
  mbmi->segment_id = 0;
269

Jim Bankoski's avatar
Jim Bankoski committed
270
  for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
271 272
    x->pred_mv_sad[ref_frame] = INT_MAX;
    if (cpi->ref_frame_flags & flag_list[ref_frame]) {
273
      vp9_setup_buffer_inter(cpi, x, tile,
274 275 276 277 278 279 280
                             ref_frame, block_size, mi_row, mi_col,
                             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;
  }

Jim Bankoski's avatar
Jim Bankoski committed
281
  for (ref_frame = LAST_FRAME; ref_frame <= LAST_FRAME ; ++ref_frame) {
282 283 284 285 286 287 288 289 290
    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);

291 292
    mbmi->ref_frame[0] = ref_frame;

293
    for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
294 295
      int rate_mv = 0;

296 297 298
      if (cpi->sf.disable_inter_mode_mask[bsize] &
          (1 << INTER_OFFSET(this_mode)))
        continue;
Jim Bankoski's avatar
Jim Bankoski committed
299 300

      if (this_mode == NEWMV) {
301
        if (this_rd < (int64_t)(1 << num_pels_log2_lookup[bsize]))
302 303
          continue;

Jim Bankoski's avatar
Jim Bankoski committed
304 305 306 307 308 309
        x->mode_sad[ref_frame][INTER_OFFSET(NEWMV)] =
            full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col,
                                     &frame_mv[NEWMV][ref_frame], &rate_mv);

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

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

315 316 317
      mbmi->mode = this_mode;
      mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int;
      vp9_build_inter_predictors_sby(xd, mi_row, mi_col, bsize);
318

319 320 321 322 323
      model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
      rate += rate_mv;
      rate += x->inter_mode_cost[mbmi->mode_context[ref_frame]]
                                [INTER_OFFSET(this_mode)];
      this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
324 325 326

      if (this_rd < best_rd) {
        best_rd = this_rd;
327 328
        best_mode = this_mode;
        best_ref_frame = ref_frame;
329 330 331 332
      }
    }
  }

333 334 335 336 337
  mbmi->mode = best_mode;
  mbmi->ref_frame[0] = best_ref_frame;
  mbmi->mv[0].as_int = frame_mv[best_mode][best_ref_frame].as_int;
  xd->mi_8x8[0]->bmi[0].as_mv[0].as_int = mbmi->mv[0].as_int;

338 339 340
  // Perform intra prediction search, if the best SAD is above a certain
  // threshold.
  if (best_rd > inter_mode_thresh) {
341
    for (this_mode = DC_PRED; this_mode <= DC_PRED; ++this_mode) {
342 343 344 345 346
      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);

347 348 349
      model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
      rate += x->mbmode_cost[this_mode];
      this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
350 351 352 353 354 355

      if (this_rd + intra_mode_cost < best_rd) {
        best_rd = this_rd;
        mbmi->mode = this_mode;
        mbmi->ref_frame[0] = INTRA_FRAME;
        mbmi->uv_mode = this_mode;
356
        mbmi->mv[0].as_int = INVALID_MV;
357 358 359
      }
    }
  }
360 361
  return INT64_MAX;
}