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

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

Johann's avatar
Johann committed
15
#include "./vpx_dsp_rtcd.h"
16 17
#include "./vpx_scale_rtcd.h"

18
#include "vpx_dsp/vpx_dsp_common.h"
19
#include "vpx_mem/vpx_mem.h"
20
#include "vpx_ports/mem.h"
21
#include "vpx_ports/system_state.h"
22 23 24 25 26
#include "vpx_scale/vpx_scale.h"
#include "vpx_scale/yv12config.h"

#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_quant_common.h"
27
#include "vp9/common/vp9_reconinter.h"  // vp9_setup_dst_planes()
Marco Paniconi's avatar
Marco Paniconi committed
28
#include "vp9/encoder/vp9_aq_variance.h"
29
#include "vp9/encoder/vp9_block.h"
30 31
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
32
#include "vp9/encoder/vp9_encodemv.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
33
#include "vp9/encoder/vp9_encoder.h"
34 35 36
#include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
37
#include "vp9/encoder/vp9_quantize.h"
38
#include "vp9/encoder/vp9_rd.h"
Johann's avatar
Johann committed
39
#include "vpx_dsp/variance.h"
John Koleszar's avatar
John Koleszar committed
40

41 42 43
#define OUTPUT_FPF          0
#define ARF_STATS_OUTPUT    0

Paul Wilkins's avatar
Paul Wilkins committed
44
#define BOOST_BREAKOUT      12.5
45
#define BOOST_FACTOR        12.5
Paul Wilkins's avatar
Paul Wilkins committed
46 47
#define FACTOR_PT_LOW       0.70
#define FACTOR_PT_HIGH      0.90
48 49 50 51
#define FIRST_PASS_Q        10.0
#define GF_MAX_BOOST        96.0
#define INTRA_MODE_PENALTY  1024
#define KF_MAX_BOOST        128.0
Paul Wilkins's avatar
Paul Wilkins committed
52
#define MIN_ARF_GF_BOOST    240
53 54 55 56
#define MIN_DECAY_FACTOR    0.01
#define MIN_KF_BOOST        300
#define NEW_MV_MODE_PENALTY 32
#define SVC_FACTOR_PT_LOW   0.45
57
#define DARK_THRESH         64
58
#define DEFAULT_GRP_WEIGHT  1.0
59 60
#define RC_FACTOR_MIN       0.75
#define RC_FACTOR_MAX       1.75
Paul Wilkins's avatar
CQ Mode  
Paul Wilkins committed
61

62 63 64

#define NCOUNT_INTRA_THRESH 8192
#define NCOUNT_INTRA_FACTOR 3
Paul Wilkins's avatar
Paul Wilkins committed
65

66

67
#define DOUBLE_DIVIDE_CHECK(x) ((x) < 0 ? (x) - 0.000001 : (x) + 0.000001)
John Koleszar's avatar
John Koleszar committed
68

69 70 71
#if ARF_STATS_OUTPUT
unsigned int arf_count = 0;
#endif
72

73 74
// Resets the first pass file to the given position using a relative seek from
// the current position.
Paul Wilkins's avatar
Paul Wilkins committed
75
static void reset_fpf_position(TWO_PASS *p,
76
                               const FIRSTPASS_STATS *position) {
77
  p->stats_in = position;
John Koleszar's avatar
John Koleszar committed
78 79
}

Adrian Grange's avatar
Adrian Grange committed
80
// Read frame stats at an offset from the current position.
81 82 83 84
static const FIRSTPASS_STATS *read_frame_stats(const TWO_PASS *p, int offset) {
  if ((offset >= 0 && p->stats_in + offset >= p->stats_in_end) ||
      (offset < 0 && p->stats_in + offset < p->stats_in_start)) {
    return NULL;
John Koleszar's avatar
John Koleszar committed
85 86
  }

87
  return &p->stats_in[offset];
88 89
}

Paul Wilkins's avatar
Paul Wilkins committed
90
static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
91
  if (p->stats_in >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
92
    return EOF;
93

94 95
  *fps = *p->stats_in;
  ++p->stats_in;
John Koleszar's avatar
John Koleszar committed
96
  return 1;
97 98
}

99 100
static void output_stats(FIRSTPASS_STATS *stats,
                         struct vpx_codec_pkt_list *pktlist) {
John Koleszar's avatar
John Koleszar committed
101 102 103 104 105
  struct vpx_codec_cx_pkt pkt;
  pkt.kind = VPX_CODEC_STATS_PKT;
  pkt.data.twopass_stats.buf = stats;
  pkt.data.twopass_stats.sz = sizeof(FIRSTPASS_STATS);
  vpx_codec_pkt_list_add(pktlist, &pkt);
106 107 108

// TEMP debug code
#if OUTPUT_FPF
John Koleszar's avatar
John Koleszar committed
109 110 111 112
  {
    FILE *fpfile;
    fpfile = fopen("firstpass.stt", "a");

113
    fprintf(fpfile, "%12.0lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf %12.4lf"
114
            "%12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf %12.4lf"
115
            "%12.4lf %12.4lf %12.4lf %12.0lf %12.0lf %12.0lf %12.4lf\n",
John Koleszar's avatar
John Koleszar committed
116
            stats->frame,
117
            stats->weight,
John Koleszar's avatar
John Koleszar committed
118 119 120 121 122 123 124
            stats->intra_error,
            stats->coded_error,
            stats->sr_coded_error,
            stats->pcnt_inter,
            stats->pcnt_motion,
            stats->pcnt_second_ref,
            stats->pcnt_neutral,
125
            stats->intra_skip_pct,
126
            stats->intra_smooth_pct,
127
            stats->inactive_zone_rows,
128
            stats->inactive_zone_cols,
John Koleszar's avatar
John Koleszar committed
129 130 131 132 133 134 135 136 137 138 139 140
            stats->MVr,
            stats->mvr_abs,
            stats->MVc,
            stats->mvc_abs,
            stats->MVrv,
            stats->MVcv,
            stats->mv_in_out_count,
            stats->new_mv_count,
            stats->count,
            stats->duration);
    fclose(fpfile);
  }
141 142 143
#endif
}

144 145 146 147 148 149
#if CONFIG_FP_MB_STATS
static void output_fpmb_stats(uint8_t *this_frame_mb_stats, VP9_COMMON *cm,
                         struct vpx_codec_pkt_list *pktlist) {
  struct vpx_codec_cx_pkt pkt;
  pkt.kind = VPX_CODEC_FPMB_STATS_PKT;
  pkt.data.firstpass_mb_stats.buf = this_frame_mb_stats;
150
  pkt.data.firstpass_mb_stats.sz = cm->initial_mbs * sizeof(uint8_t);
151 152 153 154
  vpx_codec_pkt_list_add(pktlist, &pkt);
}
#endif

John Koleszar's avatar
John Koleszar committed
155
static void zero_stats(FIRSTPASS_STATS *section) {
156 157
  section->frame = 0.0;
  section->weight = 0.0;
John Koleszar's avatar
John Koleszar committed
158 159 160 161 162 163 164
  section->intra_error = 0.0;
  section->coded_error = 0.0;
  section->sr_coded_error = 0.0;
  section->pcnt_inter  = 0.0;
  section->pcnt_motion  = 0.0;
  section->pcnt_second_ref = 0.0;
  section->pcnt_neutral = 0.0;
165
  section->intra_skip_pct = 0.0;
166
  section->intra_smooth_pct = 0.0;
167
  section->inactive_zone_rows = 0.0;
168
  section->inactive_zone_cols = 0.0;
169
  section->MVr = 0.0;
John Koleszar's avatar
John Koleszar committed
170 171 172 173 174 175 176 177 178
  section->mvr_abs     = 0.0;
  section->MVc        = 0.0;
  section->mvc_abs     = 0.0;
  section->MVrv       = 0.0;
  section->MVcv       = 0.0;
  section->mv_in_out_count  = 0.0;
  section->new_mv_count = 0.0;
  section->count      = 0.0;
  section->duration   = 1.0;
179
  section->spatial_layer_id = 0;
180 181
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
182 183
static void accumulate_stats(FIRSTPASS_STATS *section,
                             const FIRSTPASS_STATS *frame) {
John Koleszar's avatar
John Koleszar committed
184
  section->frame += frame->frame;
185
  section->weight += frame->weight;
186
  section->spatial_layer_id = frame->spatial_layer_id;
John Koleszar's avatar
John Koleszar committed
187 188 189 190 191 192 193
  section->intra_error += frame->intra_error;
  section->coded_error += frame->coded_error;
  section->sr_coded_error += frame->sr_coded_error;
  section->pcnt_inter  += frame->pcnt_inter;
  section->pcnt_motion += frame->pcnt_motion;
  section->pcnt_second_ref += frame->pcnt_second_ref;
  section->pcnt_neutral += frame->pcnt_neutral;
194
  section->intra_skip_pct += frame->intra_skip_pct;
195
  section->intra_smooth_pct += frame->intra_smooth_pct;
196
  section->inactive_zone_rows += frame->inactive_zone_rows;
197
  section->inactive_zone_cols += frame->inactive_zone_cols;
198
  section->MVr += frame->MVr;
John Koleszar's avatar
John Koleszar committed
199 200 201 202 203 204 205 206 207
  section->mvr_abs     += frame->mvr_abs;
  section->MVc        += frame->MVc;
  section->mvc_abs     += frame->mvc_abs;
  section->MVrv       += frame->MVrv;
  section->MVcv       += frame->MVcv;
  section->mv_in_out_count  += frame->mv_in_out_count;
  section->new_mv_count += frame->new_mv_count;
  section->count      += frame->count;
  section->duration   += frame->duration;
208 209
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
210 211
static void subtract_stats(FIRSTPASS_STATS *section,
                           const FIRSTPASS_STATS *frame) {
John Koleszar's avatar
John Koleszar committed
212
  section->frame -= frame->frame;
213
  section->weight -= frame->weight;
John Koleszar's avatar
John Koleszar committed
214 215 216 217 218 219 220
  section->intra_error -= frame->intra_error;
  section->coded_error -= frame->coded_error;
  section->sr_coded_error -= frame->sr_coded_error;
  section->pcnt_inter  -= frame->pcnt_inter;
  section->pcnt_motion -= frame->pcnt_motion;
  section->pcnt_second_ref -= frame->pcnt_second_ref;
  section->pcnt_neutral -= frame->pcnt_neutral;
221
  section->intra_skip_pct -= frame->intra_skip_pct;
222
  section->intra_smooth_pct -= frame->intra_smooth_pct;
223
  section->inactive_zone_rows -= frame->inactive_zone_rows;
224
  section->inactive_zone_cols -= frame->inactive_zone_cols;
225
  section->MVr -= frame->MVr;
John Koleszar's avatar
John Koleszar committed
226 227 228 229 230 231 232 233 234
  section->mvr_abs     -= frame->mvr_abs;
  section->MVc        -= frame->MVc;
  section->mvc_abs     -= frame->mvc_abs;
  section->MVrv       -= frame->MVrv;
  section->MVcv       -= frame->MVcv;
  section->mv_in_out_count  -= frame->mv_in_out_count;
  section->new_mv_count -= frame->new_mv_count;
  section->count      -= frame->count;
  section->duration   -= frame->duration;
235 236
}

237 238 239 240 241
// Calculate an active area of the image that discounts formatting
// bars and partially discounts other 0 energy areas.
#define MIN_ACTIVE_AREA 0.5
#define MAX_ACTIVE_AREA 1.0
static double calculate_active_area(const VP9_COMP *cpi,
Jingning Han's avatar
Jingning Han committed
242
                                    const FIRSTPASS_STATS *this_frame) {
243 244 245 246 247 248 249
  double active_pct;

  active_pct = 1.0 -
    ((this_frame->intra_skip_pct / 2) +
     ((this_frame->inactive_zone_rows * 2) / (double)cpi->common.mb_rows));
  return fclamp(active_pct, MIN_ACTIVE_AREA, MAX_ACTIVE_AREA);
}
250

251 252
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
253 254 255
#define ACT_AREA_CORRECTION 0.5
static double calculate_modified_err(const VP9_COMP *cpi,
                                     const TWO_PASS *twopass,
256
                                     const VP9EncoderConfig *oxcf,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
257
                                     const FIRSTPASS_STATS *this_frame) {
258
  const FIRSTPASS_STATS *const stats = &twopass->total_stats;
259 260
  const double av_weight = stats->weight / stats->count;
  const double av_err = (stats->coded_error * av_weight) / stats->count;
261
  double modified_error =
262 263
    av_err * pow(this_frame->coded_error * this_frame->weight /
                 DOUBLE_DIVIDE_CHECK(av_err), oxcf->two_pass_vbrbias / 100.0);
264 265 266 267 268 269 270 271 272

  // Correction for active area. Frames with a reduced active area
  // (eg due to formatting bars) have a higher error per mb for the
  // remaining active MBs. The correction here assumes that coding
  // 0.5N blocks of complexity 2X is a little easier than coding N
  // blocks of complexity X.
  modified_error *=
    pow(calculate_active_area(cpi, this_frame), ACT_AREA_CORRECTION);

273 274
  return fclamp(modified_error,
                twopass->modified_error_min, twopass->modified_error_max);
John Koleszar's avatar
John Koleszar committed
275 276
}

277
// This function returns the maximum target rate per frame.
278 279
static int frame_max_bits(const RATE_CONTROL *rc,
                          const VP9EncoderConfig *oxcf) {
280
  int64_t max_bits = ((int64_t)rc->avg_frame_bandwidth *
Dmitry Kovalev's avatar
Dmitry Kovalev committed
281
                          (int64_t)oxcf->two_pass_vbrmax_section) / 100;
Yaowu Xu's avatar
Yaowu Xu committed
282
  if (max_bits < 0)
Paul Wilkins's avatar
Paul Wilkins committed
283
    max_bits = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
284 285
  else if (max_bits > rc->max_frame_bandwidth)
    max_bits = rc->max_frame_bandwidth;
Paul Wilkins's avatar
Paul Wilkins committed
286

Yaowu Xu's avatar
Yaowu Xu committed
287
  return (int)max_bits;
John Koleszar's avatar
John Koleszar committed
288 289
}

290
void vp9_init_first_pass(VP9_COMP *cpi) {
291
  zero_stats(&cpi->twopass.total_stats);
John Koleszar's avatar
John Koleszar committed
292 293
}

294
void vp9_end_first_pass(VP9_COMP *cpi) {
295
  if (is_two_pass_svc(cpi)) {
296 297 298 299 300 301 302 303
    int i;
    for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
      output_stats(&cpi->svc.layer_context[i].twopass.total_stats,
                   cpi->output_pkt_list);
    }
  } else {
    output_stats(&cpi->twopass.total_stats, cpi->output_pkt_list);
  }
304
}
John Koleszar's avatar
John Koleszar committed
305

Johann's avatar
Johann committed
306
static vpx_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
307 308
  switch (bsize) {
    case BLOCK_8X8:
Johann's avatar
Johann committed
309
      return vpx_mse8x8;
310
    case BLOCK_16X8:
Johann's avatar
Johann committed
311
      return vpx_mse16x8;
312
    case BLOCK_8X16:
Johann's avatar
Johann committed
313
      return vpx_mse8x16;
314
    default:
Johann's avatar
Johann committed
315
      return vpx_mse16x16;
316 317 318
  }
}

319 320 321
static unsigned int get_prediction_error(BLOCK_SIZE bsize,
                                         const struct buf_2d *src,
                                         const struct buf_2d *ref) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
322
  unsigned int sse;
Johann's avatar
Johann committed
323
  const vpx_variance_fn_t fn = get_block_variance_fn(bsize);
324
  fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
325
  return sse;
326 327
}

328
#if CONFIG_VP9_HIGHBITDEPTH
Johann's avatar
Johann committed
329
static vpx_variance_fn_t highbd_get_block_variance_fn(BLOCK_SIZE bsize,
330 331 332 333 334
                                                      int bd) {
  switch (bd) {
    default:
      switch (bsize) {
        case BLOCK_8X8:
Johann's avatar
Johann committed
335
          return vpx_highbd_8_mse8x8;
336
        case BLOCK_16X8:
Johann's avatar
Johann committed
337
          return vpx_highbd_8_mse16x8;
338
        case BLOCK_8X16:
Johann's avatar
Johann committed
339
          return vpx_highbd_8_mse8x16;
340
        default:
Johann's avatar
Johann committed
341
          return vpx_highbd_8_mse16x16;
342 343 344 345 346
      }
      break;
    case 10:
      switch (bsize) {
        case BLOCK_8X8:
Johann's avatar
Johann committed
347
          return vpx_highbd_10_mse8x8;
348
        case BLOCK_16X8:
Johann's avatar
Johann committed
349
          return vpx_highbd_10_mse16x8;
350
        case BLOCK_8X16:
Johann's avatar
Johann committed
351
          return vpx_highbd_10_mse8x16;
352
        default:
Johann's avatar
Johann committed
353
          return vpx_highbd_10_mse16x16;
354 355 356 357 358
      }
      break;
    case 12:
      switch (bsize) {
        case BLOCK_8X8:
Johann's avatar
Johann committed
359
          return vpx_highbd_12_mse8x8;
360
        case BLOCK_16X8:
Johann's avatar
Johann committed
361
          return vpx_highbd_12_mse16x8;
362
        case BLOCK_8X16:
Johann's avatar
Johann committed
363
          return vpx_highbd_12_mse8x16;
364
        default:
Johann's avatar
Johann committed
365
          return vpx_highbd_12_mse16x16;
366 367 368 369 370 371 372 373 374 375
      }
      break;
  }
}

static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize,
                                                const struct buf_2d *src,
                                                const struct buf_2d *ref,
                                                int bd) {
  unsigned int sse;
Johann's avatar
Johann committed
376
  const vpx_variance_fn_t fn = highbd_get_block_variance_fn(bsize, bd);
377 378 379 380 381
  fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
  return sse;
}
#endif  // CONFIG_VP9_HIGHBITDEPTH

382 383
// Refine the motion search range according to the frame dimension
// for first pass test.
384
static int get_search_range(const VP9_COMP *cpi) {
385
  int sr = 0;
386
  const int dim = VPXMIN(cpi->initial_width, cpi->initial_height);
387 388 389 390 391 392

  while ((dim << sr) < MAX_FULL_PEL_VAL)
    ++sr;
  return sr;
}

393
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
394
                                     const MV *ref_mv, MV *best_mv,
395
                                     int *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
396
  MACROBLOCKD *const xd = &x->e_mbd;
397
  MV tmp_mv = {0, 0};
398
  MV ref_mv_full = {ref_mv->row >> 3, ref_mv->col >> 3};
399
  int num00, tmp_err, n;
Scott LaVarnway's avatar
Scott LaVarnway committed
400
  const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
401
  vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
402
  const int new_mv_mode_penalty = NEW_MV_MODE_PENALTY;
403

404 405
  int step_param = 3;
  int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
406
  const int sr = get_search_range(cpi);
407
  step_param += sr;
408 409
  further_steps -= sr;

Adrian Grange's avatar
Adrian Grange committed
410
  // Override the default variance function to use MSE.
411
  v_fn_ptr.vf = get_block_variance_fn(bsize);
412 413 414 415 416
#if CONFIG_VP9_HIGHBITDEPTH
  if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
    v_fn_ptr.vf = highbd_get_block_variance_fn(bsize, xd->bd);
  }
#endif  // CONFIG_VP9_HIGHBITDEPTH
John Koleszar's avatar
John Koleszar committed
417

Adrian Grange's avatar
Adrian Grange committed
418
  // Center the initial step/diamond search on best mv.
419
  tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
420
                                    step_param,
421
                                    x->sadperbit16, &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
422 423
  if (tmp_err < INT_MAX)
    tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
John Koleszar's avatar
John Koleszar committed
424 425 426 427 428
  if (tmp_err < INT_MAX - new_mv_mode_penalty)
    tmp_err += new_mv_mode_penalty;

  if (tmp_err < *best_motion_err) {
    *best_motion_err = tmp_err;
429
    *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
430 431
  }

Adrian Grange's avatar
Adrian Grange committed
432
  // Carry out further step/diamond searches as necessary.
John Koleszar's avatar
John Koleszar committed
433 434 435 436
  n = num00;
  num00 = 0;

  while (n < further_steps) {
Adrian Grange's avatar
Adrian Grange committed
437
    ++n;
John Koleszar's avatar
John Koleszar committed
438

439
    if (num00) {
Adrian Grange's avatar
Adrian Grange committed
440
      --num00;
441
    } else {
442
      tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
John Koleszar's avatar
John Koleszar committed
443
                                        step_param + n, x->sadperbit16,
444
                                        &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
445 446
      if (tmp_err < INT_MAX)
        tmp_err = vp9_get_mvpred_var(x, &tmp_mv, ref_mv, &v_fn_ptr, 1);
John Koleszar's avatar
John Koleszar committed
447
      if (tmp_err < INT_MAX - new_mv_mode_penalty)
John Koleszar's avatar
John Koleszar committed
448 449
        tmp_err += new_mv_mode_penalty;

John Koleszar's avatar
John Koleszar committed
450
      if (tmp_err < *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
451
        *best_motion_err = tmp_err;
452
        *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
453
      }
John Koleszar's avatar
John Koleszar committed
454
    }
John Koleszar's avatar
John Koleszar committed
455
  }
John Koleszar's avatar
John Koleszar committed
456 457
}

458 459 460 461 462 463 464 465 466 467
static BLOCK_SIZE get_bsize(const VP9_COMMON *cm, int mb_row, int mb_col) {
  if (2 * mb_col + 1 < cm->mi_cols) {
    return 2 * mb_row + 1 < cm->mi_rows ? BLOCK_16X16
                                        : BLOCK_16X8;
  } else {
    return 2 * mb_row + 1 < cm->mi_rows ? BLOCK_8X16
                                        : BLOCK_8X8;
  }
}

468
static int find_fp_qindex(vpx_bit_depth_t bit_depth) {
469 470 471
  int i;

  for (i = 0; i < QINDEX_RANGE; ++i)
472
    if (vp9_convert_qindex_to_q(i, bit_depth) >= FIRST_PASS_Q)
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
      break;

  if (i == QINDEX_RANGE)
    i--;

  return i;
}

static void set_first_pass_params(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  if (!cpi->refresh_alt_ref_frame &&
      (cm->current_video_frame == 0 ||
       (cpi->frame_flags & FRAMEFLAGS_KEY))) {
    cm->frame_type = KEY_FRAME;
  } else {
    cm->frame_type = INTER_FRAME;
  }
  // Do not use periodic key frames.
  cpi->rc.frames_to_key = INT_MAX;
}

Paul Wilkins's avatar
Paul Wilkins committed
494 495 496
// This threshold is used to track blocks where to all intents and purposes
// the intra prediction error 0. Though the metric we test against
// is technically a sse we are mainly interested in blocks where all the pixels
497
// in the 8 bit domain have an error of <= 1 (where error = sse) so a
Paul Wilkins's avatar
Paul Wilkins committed
498
// linear scaling for 10 and 12 bit gives similar results.
499
#define UL_INTRA_THRESH 50
Paul Wilkins's avatar
Paul Wilkins committed
500 501
static int get_ul_intra_threshold(VP9_COMMON *cm) {
  int ret_val = UL_INTRA_THRESH;
502
#if CONFIG_VP9_HIGHBITDEPTH
Paul Wilkins's avatar
Paul Wilkins committed
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518
  if (cm->use_highbitdepth) {
    switch (cm->bit_depth) {
      case VPX_BITS_8:
        ret_val = UL_INTRA_THRESH;
        break;
      case VPX_BITS_10:
        ret_val = UL_INTRA_THRESH >> 2;
        break;
      case VPX_BITS_12:
        ret_val = UL_INTRA_THRESH >> 4;
        break;
      default:
        assert(0 && "cm->bit_depth should be VPX_BITS_8, "
                    "VPX_BITS_10 or VPX_BITS_12");
    }
  }
519 520 521
#else
  (void) cm;
#endif  // CONFIG_VP9_HIGHBITDEPTH
Paul Wilkins's avatar
Paul Wilkins committed
522 523
  return ret_val;
}
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546

#define SMOOTH_INTRA_THRESH 4000
static int get_smooth_intra_threshold(VP9_COMMON *cm) {
  int ret_val = SMOOTH_INTRA_THRESH;
#if CONFIG_VP9_HIGHBITDEPTH
  if (cm->use_highbitdepth) {
    switch (cm->bit_depth) {
      case VPX_BITS_8:
        ret_val = SMOOTH_INTRA_THRESH;
        break;
      case VPX_BITS_10:
        ret_val = SMOOTH_INTRA_THRESH >> 2;
        break;
      case VPX_BITS_12:
        ret_val = SMOOTH_INTRA_THRESH >> 4;
        break;
      default:
        assert(0 && "cm->bit_depth should be VPX_BITS_8, "
                    "VPX_BITS_10 or VPX_BITS_12");
    }
  }
#else
  (void) cm;
Paul Wilkins's avatar
Paul Wilkins committed
547
#endif  // CONFIG_VP9_HIGHBITDEPTH
548 549
  return ret_val;
}
Paul Wilkins's avatar
Paul Wilkins committed
550

551
#define INVALID_ROW -1
552
void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
John Koleszar's avatar
John Koleszar committed
553
  int mb_row, mb_col;
554
  MACROBLOCK *const x = &cpi->td.mb;
555
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
556
  MACROBLOCKD *const xd = &x->e_mbd;
James Zern's avatar
James Zern committed
557
  TileInfo tile;
558 559
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
560
  const PICK_MODE_CONTEXT *ctx = &cpi->td.pc_root->none;
561
  int i;
John Koleszar's avatar
John Koleszar committed
562 563 564 565 566 567 568 569

  int recon_yoffset, recon_uvoffset;
  int64_t intra_error = 0;
  int64_t coded_error = 0;
  int64_t sr_coded_error = 0;

  int sum_mvr = 0, sum_mvc = 0;
  int sum_mvr_abs = 0, sum_mvc_abs = 0;
570
  int64_t sum_mvrs = 0, sum_mvcs = 0;
John Koleszar's avatar
John Koleszar committed
571 572 573
  int mvcount = 0;
  int intercount = 0;
  int second_ref_count = 0;
574
  const int intrapenalty = INTRA_MODE_PENALTY;
575
  double neutral_count;
576
  int intra_skip_count = 0;
577
  int intra_smooth_count = 0;
578
  int image_data_start_row = INVALID_ROW;
John Koleszar's avatar
John Koleszar committed
579 580
  int new_mv_count = 0;
  int sum_in_vectors = 0;
581
  MV lastmv = {0, 0};
Paul Wilkins's avatar
Paul Wilkins committed
582
  TWO_PASS *twopass = &cpi->twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
583
  const MV zero_mv = {0, 0};
584 585 586 587 588
  int recon_y_stride, recon_uv_stride, uv_mb_height;

  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
  YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
589
  const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
590

591 592
  LAYER_CONTEXT *const lc = is_two_pass_svc(cpi) ?
        &cpi->svc.layer_context[cpi->svc.spatial_layer_id] : NULL;
Paul Wilkins's avatar
Paul Wilkins committed
593 594
  double intra_factor;
  double brightness_factor;
595
  BufferPool *const pool = cm->buffer_pool;
596
  MODE_INFO mi_above, mi_left;
597 598 599 600 601

  // First pass code requires valid last and new frame buffers.
  assert(new_yv12 != NULL);
  assert((lc != NULL) || frame_is_intra_only(cm) || (lst_yv12 != NULL));

602
#if CONFIG_FP_MB_STATS
603
  if (cpi->use_fp_mb_stats) {
604
    vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cm->initial_mbs);
605
  }
606 607
#endif

608
  vpx_clear_system_state();
John Koleszar's avatar
John Koleszar committed
609

Paul Wilkins's avatar
Paul Wilkins committed
610 611
  intra_factor = 0.0;
  brightness_factor = 0.0;
612
  neutral_count = 0.0;
Paul Wilkins's avatar
Paul Wilkins committed
613

614
  set_first_pass_params(cpi);
615
  vp9_set_quantizer(cm, find_fp_qindex(cm->bit_depth));
616

617 618
  if (lc != NULL) {
    twopass = &lc->twopass;
619

620 621 622 623 624 625 626 627 628
    cpi->lst_fb_idx = cpi->svc.spatial_layer_id;
    cpi->ref_frame_flags = VP9_LAST_FLAG;

    if (cpi->svc.number_spatial_layers + cpi->svc.spatial_layer_id <
        REF_FRAMES) {
      cpi->gld_fb_idx =
          cpi->svc.number_spatial_layers + cpi->svc.spatial_layer_id;
      cpi->ref_frame_flags |= VP9_GOLD_FLAG;
      cpi->refresh_golden_frame = (lc->current_video_frame_in_layer == 0);
629
    } else {
630
      cpi->refresh_golden_frame = 0;
631 632
    }

633 634 635
    if (lc->current_video_frame_in_layer == 0)
      cpi->ref_frame_flags = 0;

636 637 638 639
    vp9_scale_references(cpi);

    // Use either last frame or alt frame for motion search.
    if (cpi->ref_frame_flags & VP9_LAST_FLAG) {
640 641 642
      first_ref_buf = vp9_get_scaled_ref_frame(cpi, LAST_FRAME);
      if (first_ref_buf == NULL)
        first_ref_buf = get_ref_frame_buffer(cpi, LAST_FRAME);
643 644 645
    }

    if (cpi->ref_frame_flags & VP9_GOLD_FLAG) {
646 647 648 649
      gld_yv12 = vp9_get_scaled_ref_frame(cpi, GOLDEN_FRAME);
      if (gld_yv12 == NULL) {
        gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
      }
650 651
    } else {
      gld_yv12 = NULL;
652 653
    }

654 655 656
    set_ref_ptrs(cm, xd,
                 (cpi->ref_frame_flags & VP9_LAST_FLAG) ? LAST_FRAME: NONE,
                 (cpi->ref_frame_flags & VP9_GOLD_FLAG) ? GOLDEN_FRAME : NONE);
657 658

    cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
659
                                        &cpi->scaled_source, 0);
660 661
  }

662 663
  vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);

John Koleszar's avatar
John Koleszar committed
664
  vp9_setup_src_planes(x, cpi->Source, 0, 0);
665
  vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
John Koleszar's avatar
John Koleszar committed
666

667 668 669 670
  if (!frame_is_intra_only(cm)) {
    vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
  }

671 672
  xd->mi = cm->mi_grid_visible;
  xd->mi[0] = cm->mi;
John Koleszar's avatar
John Koleszar committed
673

674
  vp9_frame_init_quantizer(cpi);
John Koleszar's avatar
John Koleszar committed
675

676 677
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][1];
678
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
679
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
680
    p[i].eobs = ctx->eobs_pbuf[i][1];
681
  }
682
  x->skip_recode = 0;
683

Dmitry Kovalev's avatar
Dmitry Kovalev committed
684 685
  vp9_init_mv_probs(cm);
  vp9_initialize_rd_consts(cpi);
John Koleszar's avatar
John Koleszar committed
686

Adrian Grange's avatar
Adrian Grange committed
687
  // Tiling is ignored in the first pass.
James Zern's avatar
James Zern committed
688 689
  vp9_tile_init(&tile, cm, 0, 0);

690 691 692 693
  recon_y_stride = new_yv12->y_stride;
  recon_uv_stride = new_yv12->uv_stride;
  uv_mb_height = 16 >> (new_yv12->y_height > new_yv12->uv_height);

Adrian Grange's avatar
Adrian Grange committed
694
  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
695
    MV best_ref_mv = {0, 0};
John Koleszar's avatar
John Koleszar committed
696

Adrian Grange's avatar
Adrian Grange committed
697
    // Reset above block coeffs.
John Koleszar's avatar
John Koleszar committed
698
    recon_yoffset = (mb_row * recon_y_stride * 16);
Alex Converse's avatar
Alex Converse committed
699
    recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
John Koleszar's avatar
John Koleszar committed
700

701
    // Set up limit values for motion vectors to prevent them extending
Adrian Grange's avatar
Adrian Grange committed
702
    // outside the UMV borders.
703
    x->mv_row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
John Koleszar's avatar
John Koleszar committed
704
    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
705
                    + BORDER_MV_PIXELS_B16;
John Koleszar's avatar
John Koleszar committed
706

Adrian Grange's avatar
Adrian Grange committed
707
    for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
John Koleszar's avatar
John Koleszar committed
708
      int this_error;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
709
      const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
710
      const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
711 712 713
      double log_intra;
      int level_sample;

714 715 716
#if CONFIG_FP_MB_STATS
      const int mb_index = mb_row * cm->mb_cols + mb_col;
#endif
717

718
      vpx_clear_system_state();
John Koleszar's avatar
John Koleszar committed
719

720 721 722
      xd->plane[0].dst.buf = new_yv12->y_buffer + recon_yoffset;
      xd->plane[1].dst.buf = new_yv12->u_buffer + recon_uvoffset;
      xd->plane[2].dst.buf = new_yv12->v_buffer + recon_uvoffset;
Scott LaVarnway's avatar
Scott LaVarnway committed
723 724
      xd->mi[0]->sb_type = bsize;
      xd->mi[0]->ref_frame[0] = INTRA_FRAME;
James Zern's avatar
James Zern committed
725
      set_mi_row_col(xd, &tile,
726 727
                     mb_row << 1, num_8x8_blocks_high_lookup[bsize],
                     mb_col << 1, num_8x8_blocks_wide_lookup[bsize],
James Zern's avatar
James Zern committed
728
                     cm->mi_rows, cm->mi_cols);
729 730 731 732 733 734
      // Are edges available for intra prediction?
      // Since the firstpass does not populate the mi_grid_visible,
      // above_mi/left_mi must be overwritten with a nonzero value when edges
      // are available.  Required by vp9_predict_intra_block().
      xd->above_mi = (mb_row != 0) ? &mi_above : NULL;
      xd->left_mi  = (mb_col > tile.mi_col_start) ? &mi_left : NULL;
Jingning Han's avatar
Jingning Han committed
735

Adrian Grange's avatar
Adrian Grange committed
736
      // Do intra 16x16 prediction.
737
      x->skip_encode = 0;
Scott LaVarnway's avatar
Scott LaVarnway committed
738 739
      xd->mi[0]->mode = DC_PRED;
      xd->mi[0]->tx_size = use_dc_pred ?
740
         (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
741
      vp9_encode_intra_block_plane(x, bsize, 0, 0);
Johann's avatar
Johann committed
742
      this_error = vpx_get_mb_ss(x->plane[0].src_diff);
743 744 745 746 747 748

      // Keep a record of blocks that have almost no intra error residual
      // (i.e. are in effect completely flat and untextured in the intra
      // domain). In natural videos this is uncommon, but it is much more
      // common in animations, graphics and screen content, so may be used
      // as a signal to detect these types of content.
Paul Wilkins's avatar
Paul Wilkins committed
749
      if (this_error < get_ul_intra_threshold(cm)) {
750
        ++intra_skip_count;
751 752 753
      } else if ((mb_col > 0) && (image_data_start_row == INVALID_ROW)) {
        image_data_start_row = mb_row;
      }
754 755 756
      if (this_error < get_smooth_intra_threshold(cm)) {
        ++intra_smooth_count;
      }
757

758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
#if CONFIG_VP9_HIGHBITDEPTH
      if (cm->use_highbitdepth) {
        switch (cm->bit_depth) {
          case VPX_BITS_8:
            break;
          case VPX_BITS_10:
            this_error >>= 4;
            break;
          case VPX_BITS_12:
            this_error >>= 8;
            break;
          default:
            assert(0 && "cm->bit_depth should be VPX_BITS_8, "
                        "VPX_BITS_10 or VPX_BITS_12");
            return;
        }
      }
#endif  // CONFIG_VP9_HIGHBITDEPTH
776

777
      vpx_clear_system_state();
778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796
      log_intra = log(this_error + 1.0);
      if (log_intra < 10.0)
        intra_factor += 1.0 + ((10.0 - log_intra) * 0.05);
      else
        intra_factor += 1.0;

#if CONFIG_VP9_HIGHBITDEPTH
      if (cm->use_highbitdepth)
        level_sample = CONVERT_TO_SHORTPTR(x->plane[0].src.buf)[0];
      else
        level_sample = x->plane[0].src.buf[0];
#else
      level_sample = x->plane[0].src.buf[0];
#endif
      if ((level_sample < DARK_THRESH) && (log_intra < 9.0))
        brightness_factor += 1.0 + (0.01 * (DARK_THRESH - level_sample));
      else
        brightness_factor += 1.0;

Adrian Grange's avatar
Adrian Grange committed
797 798
      // Intrapenalty below deals with situations where the intra and inter
      // error scores are very low (e.g. a plain black frame).
799 800 801 802
      // We do not have special cases in first pass for 0,0 and nearest etc so
      // all inter modes carry an overhead cost estimate for the mv.
      // When the error score is very low this causes us to pick all or lots of
      // INTRA modes and throw lots of key frames.
John Koleszar's avatar
John Koleszar committed
803 804 805
      // This penalty adds a cost matching that of a 0,0 mv to the intra case.
      this_error += intrapenalty;

Adrian Grange's avatar
Adrian Grange committed
806
      // Accumulate the intra error.
John Koleszar's avatar
John Koleszar committed
807 808
      intra_error += (int64_t)this_error;

809 810
#if CONFIG_FP_MB_STATS
      if (cpi->use_fp_mb_stats) {
811
        // initialization
812
        cpi->twopass.frame_mb_stats_buf[mb_index] = 0;
813 814 815
      }
#endif

816 817
      // Set up limit values for motion vectors to prevent them extending
      // outside the UMV borders.
818
      x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
819
      x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16;
John Koleszar's avatar
John Koleszar committed
820

Adrian Grange's avatar
Adrian Grange committed
821
      // Other than for the first frame do a motion search.
822 823
      if ((lc == NULL && cm->current_video_frame > 0) ||
          (lc != NULL && lc->current_video_frame_in_layer > 0)) {
824
        int tmp_err, motion_error, raw_motion_error;
825 826
        // Assume 0,0 motion with no mv overhead.
        MV mv = {0, 0} , tmp_mv = {0, 0};
827
        struct buf_2d unscaled_last_source_buf_2d;
828

829
        xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
830 831 832 833 834 835 836 837 838 839 840 841
#if CONFIG_VP9_HIGHBITDEPTH
        if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
          motion_error = highbd_get_prediction_error(
              bsize, &x->plane[0].src, &xd->plane[0].pre[0], xd->bd);
        } else {
          motion_error = get_prediction_error(
              bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
        }
#else
        motion_error = get_prediction_error(
            bsize, &x->plane[0].src, &xd->plane[0].pre[0]);
#endif  // CONFIG_VP9_HIGHBITDEPTH
842

843 844 845 846 847 848 849
        // Compute the motion error of the 0,0 motion using the last source
        // frame as the reference. Skip the further motion search on
        // reconstructed frame if this error is small.
        unscaled_last_source_buf_2d.buf =
            cpi->unscaled_last_source->y_buffer + recon_yoffset;
        unscaled_last_source_buf_2d.stride =
            cpi->unscaled_last_source->y_stride;
850 851 852 853 854 855 856 857 858 859 860 861
#if CONFIG_VP9_HIGHBITDEPTH
        if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
          raw_motion_error = highbd_get_prediction_error(
              bsize, &x->plane[0].src, &unscaled_last_source_buf_2d, xd->bd);
        } else {
          raw_motion_error = get_prediction_error(
              bsize, &x->plane[0].src, &unscaled_last_source_buf_2d);
        }
#else
        raw_motion_error = get_prediction_error(
            bsize, &x->plane[0].src, &unscaled_last_source_buf_2d);
#endif  // CONFIG_VP9_HIGHBITDEPTH
862 863

        // TODO(pengchong): Replace the hard-coded threshold
864
        if (raw_motion_error > 25 || lc != NULL) {
865 866
          // Test last reference frame using the previous best mv as the
          // starting point (best reference) for the search.
867
          first_pass_motion_search(cpi, x, &best_ref_mv, &mv, &motion_error);
John Koleszar's avatar
John Koleszar committed
868

869 870
          // If the current best reference mv is not centered on 0,0 then do a
          // 0,0 based search as well.
871
          if (!is_zero_mv(&best_ref_mv)) {
872
            tmp_err = INT_MAX;
873
            first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv, &tmp_err);
874 875 876

            if (tmp_err < motion_error) {
              motion_error = tmp_err;
877
              mv = tmp_mv;
878
            }
John Koleszar's avatar
John Koleszar committed