vp9_firstpass.c 79.2 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
15
16
17
18
19
20
21
22

#include "./vpx_scale_rtcd.h"

#include "vpx_mem/vpx_mem.h"
#include "vpx_scale/vpx_scale.h"
#include "vpx_scale/yv12config.h"

#include "vp9/common/vp9_entropymv.h"
#include "vp9/common/vp9_quant_common.h"
23
#include "vp9/common/vp9_reconinter.h"  // vp9_setup_dst_planes()
24
#include "vp9/common/vp9_systemdependent.h"
25

Marco Paniconi's avatar
Marco Paniconi committed
26
#include "vp9/encoder/vp9_aq_variance.h"
27
#include "vp9/encoder/vp9_block.h"
28
29
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
30
#include "vp9/encoder/vp9_encodemv.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
31
#include "vp9/encoder/vp9_encoder.h"
32
33
34
#include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
35
#include "vp9/encoder/vp9_quantize.h"
36
#include "vp9/encoder/vp9_ratectrl.h"
37
38
#include "vp9/encoder/vp9_rdopt.h"
#include "vp9/encoder/vp9_variance.h"
John Koleszar's avatar
John Koleszar committed
39

40
#define OUTPUT_FPF 0
John Koleszar's avatar
John Koleszar committed
41

42
43
#define IIFACTOR   12.5
#define IIKFACTOR1 12.5
44
#define IIKFACTOR2 15.0
45
#define RMAX       512.0
46
#define GF_RMAX    96.0
Paul Wilkins's avatar
Paul Wilkins committed
47
#define ERR_DIVISOR   150.0
48
#define MIN_DECAY_FACTOR 0.1
49
50
51
#define SVC_FACTOR_PT_LOW 0.45
#define FACTOR_PT_LOW 0.5
#define FACTOR_PT_HIGH 0.9
John Koleszar's avatar
John Koleszar committed
52

53
54
#define KF_MB_INTRA_MIN 150
#define GF_MB_INTRA_MIN 100
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
55

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

58
59
#define MIN_KF_BOOST        300

60
61
62
63
64
65
66
#if CONFIG_MULTIPLE_ARF
// Set MIN_GF_INTERVAL to 1 for the full decomposition.
#define MIN_GF_INTERVAL             2
#else
#define MIN_GF_INTERVAL             4
#endif

67
#define LONG_TERM_VBR_CORRECTION
68

69
70
71
72
73
74
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
  YV12_BUFFER_CONFIG temp = *a;
  *a = *b;
  *b = temp;
}

75
76
77
78
79
80
81
static int gfboost_qadjust(int qindex) {
  const double q = vp9_convert_qindex_to_q(qindex);
  return (int)((0.00000828 * q * q * q) +
               (-0.0055 * q * q) +
               (1.32 * q) + 79.3);
}

82
83
// Resets the first pass file to the given position using a relative seek from
// the current position.
Paul Wilkins's avatar
Paul Wilkins committed
84
static void reset_fpf_position(TWO_PASS *p,
85
                               const FIRSTPASS_STATS *position) {
86
  p->stats_in = position;
John Koleszar's avatar
John Koleszar committed
87
88
}

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

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

98

Adrian Grange's avatar
Adrian Grange committed
99
// Read frame stats at an offset from the current position.
Paul Wilkins's avatar
Paul Wilkins committed
100
static int read_frame_stats(const TWO_PASS *p,
101
102
                            FIRSTPASS_STATS *frame_stats, int offset) {
  const FIRSTPASS_STATS *fps_ptr = p->stats_in;
John Koleszar's avatar
John Koleszar committed
103

Adrian Grange's avatar
Adrian Grange committed
104
  // Check legality of offset.
John Koleszar's avatar
John Koleszar committed
105
  if (offset >= 0) {
106
    if (&fps_ptr[offset] >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
107
108
      return EOF;
  } else if (offset < 0) {
109
    if (&fps_ptr[offset] < p->stats_in_start)
John Koleszar's avatar
John Koleszar committed
110
111
112
113
114
      return EOF;
  }

  *frame_stats = fps_ptr[offset];
  return 1;
115
116
}

Paul Wilkins's avatar
Paul Wilkins committed
117
static int input_stats(TWO_PASS *p, FIRSTPASS_STATS *fps) {
118
  if (p->stats_in >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
119
    return EOF;
120

121
122
  *fps = *p->stats_in;
  ++p->stats_in;
John Koleszar's avatar
John Koleszar committed
123
  return 1;
124
125
}

126
127
static void output_stats(FIRSTPASS_STATS *stats,
                         struct vpx_codec_pkt_list *pktlist) {
John Koleszar's avatar
John Koleszar committed
128
129
130
131
132
  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);
133
134
135

// TEMP debug code
#if OUTPUT_FPF
John Koleszar's avatar
John Koleszar committed
136
137
138
139
  {
    FILE *fpfile;
    fpfile = fopen("firstpass.stt", "a");

140
    fprintf(fpfile, "%12.0f %12.0f %12.0f %12.0f %12.0f %12.4f %12.4f"
John Koleszar's avatar
John Koleszar committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
            "%12.4f %12.4f %12.4f %12.4f %12.4f %12.4f %12.4f"
            "%12.0f %12.0f %12.4f %12.0f %12.0f %12.4f\n",
            stats->frame,
            stats->intra_error,
            stats->coded_error,
            stats->sr_coded_error,
            stats->ssim_weighted_pred_err,
            stats->pcnt_inter,
            stats->pcnt_motion,
            stats->pcnt_second_ref,
            stats->pcnt_neutral,
            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);
  }
164
165
166
#endif
}

John Koleszar's avatar
John Koleszar committed
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
static void zero_stats(FIRSTPASS_STATS *section) {
  section->frame      = 0.0;
  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;
  section->MVr        = 0.0;
  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;
186
  section->spatial_layer_id = 0;
187
188
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
189
190
static void accumulate_stats(FIRSTPASS_STATS *section,
                             const FIRSTPASS_STATS *frame) {
John Koleszar's avatar
John Koleszar committed
191
  section->frame += frame->frame;
192
  section->spatial_layer_id = frame->spatial_layer_id;
John Koleszar's avatar
John Koleszar committed
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
  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;
  section->MVr        += frame->MVr;
  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;
210
211
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
212
213
static void subtract_stats(FIRSTPASS_STATS *section,
                           const FIRSTPASS_STATS *frame) {
John Koleszar's avatar
John Koleszar committed
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
  section->frame -= frame->frame;
  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;
  section->MVr        -= frame->MVr;
  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;
232
233
}

John Koleszar's avatar
John Koleszar committed
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
static void avg_stats(FIRSTPASS_STATS *section) {
  if (section->count < 1.0)
    return;

  section->intra_error /= section->count;
  section->coded_error /= section->count;
  section->sr_coded_error /= section->count;
  section->pcnt_inter  /= section->count;
  section->pcnt_second_ref /= section->count;
  section->pcnt_neutral /= section->count;
  section->pcnt_motion /= section->count;
  section->MVr        /= section->count;
  section->mvr_abs     /= section->count;
  section->MVc        /= section->count;
  section->mvc_abs     /= section->count;
  section->MVrv       /= section->count;
  section->MVcv       /= section->count;
  section->mv_in_out_count   /= section->count;
  section->duration   /= section->count;
253
254
}

255
256
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
257
258
static double calculate_modified_err(const TWO_PASS *twopass,
                                     const VP9EncoderConfig *oxcf,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
259
                                     const FIRSTPASS_STATS *this_frame) {
260
  const FIRSTPASS_STATS *const stats = &twopass->total_stats;
261
  const double av_err = stats->coded_error / stats->count;
262
  const double modified_error = av_err *
263
      pow(this_frame->coded_error / DOUBLE_DIVIDE_CHECK(av_err),
264
          oxcf->two_pass_vbrbias / 100.0);
265
266
  return fclamp(modified_error,
                twopass->modified_error_min, twopass->modified_error_max);
John Koleszar's avatar
John Koleszar committed
267
268
}

269
// This function returns the maximum target rate per frame.
270
271
static int frame_max_bits(const RATE_CONTROL *rc,
                          const VP9EncoderConfig *oxcf) {
272
  int64_t max_bits = ((int64_t)rc->avg_frame_bandwidth *
Dmitry Kovalev's avatar
Dmitry Kovalev committed
273
                          (int64_t)oxcf->two_pass_vbrmax_section) / 100;
Yaowu Xu's avatar
Yaowu Xu committed
274
  if (max_bits < 0)
Paul Wilkins's avatar
Paul Wilkins committed
275
    max_bits = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
276
277
  else if (max_bits > rc->max_frame_bandwidth)
    max_bits = rc->max_frame_bandwidth;
Paul Wilkins's avatar
Paul Wilkins committed
278

Yaowu Xu's avatar
Yaowu Xu committed
279
  return (int)max_bits;
John Koleszar's avatar
John Koleszar committed
280
281
}

282
void vp9_init_first_pass(VP9_COMP *cpi) {
283
  zero_stats(&cpi->twopass.total_stats);
John Koleszar's avatar
John Koleszar committed
284
285
}

286
void vp9_end_first_pass(VP9_COMP *cpi) {
287
288
289
290
291
292
293
294
295
  if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
    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);
  }
296
}
John Koleszar's avatar
John Koleszar committed
297

298
299
300
301
302
303
304
305
306
307
308
309
310
static vp9_variance_fn_t get_block_variance_fn(BLOCK_SIZE bsize) {
  switch (bsize) {
    case BLOCK_8X8:
      return vp9_mse8x8;
    case BLOCK_16X8:
      return vp9_mse16x8;
    case BLOCK_8X16:
      return vp9_mse8x16;
    default:
      return vp9_mse16x16;
  }
}

311
312
313
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
314
  unsigned int sse;
315
316
  const vp9_variance_fn_t fn = get_block_variance_fn(bsize);
  fn(src->buf, src->stride, ref->buf, ref->stride, &sse);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
317
  return sse;
318
319
}

320
321
322
323
324
325
326
327
328
329
330
// Refine the motion search range according to the frame dimension
// for first pass test.
static int get_search_range(const VP9_COMMON *cm) {
  int sr = 0;
  const int dim = MIN(cm->width, cm->height);

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

331
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
332
                                     const MV *ref_mv, MV *best_mv,
333
                                     int *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
334
  MACROBLOCKD *const xd = &x->e_mbd;
335
  MV tmp_mv = {0, 0};
336
  MV ref_mv_full = {ref_mv->row >> 3, ref_mv->col >> 3};
337
  int num00, tmp_err, n;
338
  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
339
  vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
340
  const int new_mv_mode_penalty = 256;
341

342
343
344
  int step_param = 3;
  int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
  const int sr = get_search_range(&cpi->common);
345
  step_param += sr;
346
347
  further_steps -= sr;

Adrian Grange's avatar
Adrian Grange committed
348
  // Override the default variance function to use MSE.
349
  v_fn_ptr.vf = get_block_variance_fn(bsize);
John Koleszar's avatar
John Koleszar committed
350

Adrian Grange's avatar
Adrian Grange committed
351
  // Center the initial step/diamond search on best mv.
352
  tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
353
                                    step_param,
354
                                    x->sadperbit16, &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
355
356
  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
357
358
359
360
361
  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;
362
    *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
363
364
  }

Adrian Grange's avatar
Adrian Grange committed
365
  // Carry out further step/diamond searches as necessary.
John Koleszar's avatar
John Koleszar committed
366
367
368
369
  n = num00;
  num00 = 0;

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

372
    if (num00) {
Adrian Grange's avatar
Adrian Grange committed
373
      --num00;
374
    } else {
375
      tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
John Koleszar's avatar
John Koleszar committed
376
                                        step_param + n, x->sadperbit16,
377
                                        &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
378
379
      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
380
      if (tmp_err < INT_MAX - new_mv_mode_penalty)
John Koleszar's avatar
John Koleszar committed
381
382
        tmp_err += new_mv_mode_penalty;

John Koleszar's avatar
John Koleszar committed
383
      if (tmp_err < *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
384
        *best_motion_err = tmp_err;
385
        *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
386
      }
John Koleszar's avatar
John Koleszar committed
387
    }
John Koleszar's avatar
John Koleszar committed
388
  }
John Koleszar's avatar
John Koleszar committed
389
390
}

391
392
393
394
395
396
397
398
399
400
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;
  }
}

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
static int find_fp_qindex() {
  int i;

  for (i = 0; i < QINDEX_RANGE; ++i)
    if (vp9_convert_qindex_to_q(i) >= 30.0)
      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;
}

427
void vp9_first_pass(VP9_COMP *cpi) {
John Koleszar's avatar
John Koleszar committed
428
  int mb_row, mb_col;
John Koleszar's avatar
John Koleszar committed
429
  MACROBLOCK *const x = &cpi->mb;
430
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
431
  MACROBLOCKD *const xd = &x->e_mbd;
James Zern's avatar
James Zern committed
432
  TileInfo tile;
433
434
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
435
  const PICK_MODE_CONTEXT *ctx = &cpi->pc_root->none;
436
  int i;
John Koleszar's avatar
John Koleszar committed
437
438

  int recon_yoffset, recon_uvoffset;
439
  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
440
  YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
441
  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
442
443
444
  int recon_y_stride = lst_yv12->y_stride;
  int recon_uv_stride = lst_yv12->uv_stride;
  int uv_mb_height = 16 >> (lst_yv12->y_height > lst_yv12->uv_height);
John Koleszar's avatar
John Koleszar committed
445
446
447
448
449
450
  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;
451
  int64_t sum_mvrs = 0, sum_mvcs = 0;
John Koleszar's avatar
John Koleszar committed
452
453
454
455
456
457
458
459
  int mvcount = 0;
  int intercount = 0;
  int second_ref_count = 0;
  int intrapenalty = 256;
  int neutral_count = 0;
  int new_mv_count = 0;
  int sum_in_vectors = 0;
  uint32_t lastmv_as_int = 0;
Paul Wilkins's avatar
Paul Wilkins committed
460
  TWO_PASS *twopass = &cpi->twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
461
  const MV zero_mv = {0, 0};
462
  const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
John Koleszar's avatar
John Koleszar committed
463

464
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
465

466
467
468
  set_first_pass_params(cpi);
  vp9_set_quantizer(cm, find_fp_qindex());

469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
  if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
    MV_REFERENCE_FRAME ref_frame = LAST_FRAME;
    const YV12_BUFFER_CONFIG *scaled_ref_buf = NULL;
    twopass = &cpi->svc.layer_context[cpi->svc.spatial_layer_id].twopass;

    vp9_scale_references(cpi);

    // Use either last frame or alt frame for motion search.
    if (cpi->ref_frame_flags & VP9_LAST_FLAG) {
      scaled_ref_buf = vp9_get_scaled_ref_frame(cpi, LAST_FRAME);
      ref_frame = LAST_FRAME;
    } else if (cpi->ref_frame_flags & VP9_ALT_FLAG) {
      scaled_ref_buf = vp9_get_scaled_ref_frame(cpi, ALTREF_FRAME);
      ref_frame = ALTREF_FRAME;
    }

    if (scaled_ref_buf != NULL) {
      // Update the stride since we are using scaled reference buffer
      first_ref_buf = scaled_ref_buf;
      recon_y_stride = first_ref_buf->y_stride;
      recon_uv_stride = first_ref_buf->uv_stride;
      uv_mb_height = 16 >> (first_ref_buf->y_height > first_ref_buf->uv_height);
    }

    // Disable golden frame for svc first pass for now.
    gld_yv12 = NULL;
    set_ref_ptrs(cm, xd, ref_frame, NONE);
496
497
498

    cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
                                        &cpi->scaled_source);
499
500
  }

John Koleszar's avatar
John Koleszar committed
501
  vp9_setup_src_planes(x, cpi->Source, 0, 0);
502
  vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
503
  vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
John Koleszar's avatar
John Koleszar committed
504

505
506
  xd->mi = cm->mi_grid_visible;
  xd->mi[0] = cm->mi;
John Koleszar's avatar
John Koleszar committed
507

508
  vp9_setup_block_planes(&x->e_mbd, cm->subsampling_x, cm->subsampling_y);
John Koleszar's avatar
John Koleszar committed
509

510
  vp9_frame_init_quantizer(cpi);
John Koleszar's avatar
John Koleszar committed
511

512
513
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][1];
514
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
515
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
516
    p[i].eobs = ctx->eobs_pbuf[i][1];
517
  }
518
  x->skip_recode = 0;
519

Dmitry Kovalev's avatar
Dmitry Kovalev committed
520
521
  vp9_init_mv_probs(cm);
  vp9_initialize_rd_consts(cpi);
John Koleszar's avatar
John Koleszar committed
522

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

Adrian Grange's avatar
Adrian Grange committed
526
  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
John Koleszar's avatar
John Koleszar committed
527
528
529
530
    int_mv best_ref_mv;

    best_ref_mv.as_int = 0;

Adrian Grange's avatar
Adrian Grange committed
531
    // Reset above block coeffs.
John Koleszar's avatar
John Koleszar committed
532
533
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
Alex Converse's avatar
Alex Converse committed
534
    recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
John Koleszar's avatar
John Koleszar committed
535

536
    // Set up limit values for motion vectors to prevent them extending
Adrian Grange's avatar
Adrian Grange committed
537
    // outside the UMV borders.
538
    x->mv_row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
John Koleszar's avatar
John Koleszar committed
539
    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
540
                    + BORDER_MV_PIXELS_B16;
John Koleszar's avatar
John Koleszar committed
541

Adrian Grange's avatar
Adrian Grange committed
542
    for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
John Koleszar's avatar
John Koleszar committed
543
      int this_error;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
544
      const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
545
      double error_weight = 1.0;
546
      const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
547

548
      vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
549

550
551
552
      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;
John Koleszar's avatar
John Koleszar committed
553
      xd->left_available = (mb_col != 0);
554
555
      xd->mi[0]->mbmi.sb_type = bsize;
      xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
James Zern's avatar
James Zern committed
556
      set_mi_row_col(xd, &tile,
557
558
                     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
559
                     cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
560

561
      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
562
        const int energy = vp9_block_energy(cpi, x, bsize);
563
564
565
        error_weight = vp9_vaq_inv_q_ratio(energy);
      }

Adrian Grange's avatar
Adrian Grange committed
566
      // Do intra 16x16 prediction.
567
568
569
570
571
572
573
      x->skip_encode = 0;
      xd->mi[0]->mbmi.mode = DC_PRED;
      xd->mi[0]->mbmi.tx_size = use_dc_pred ?
         (bsize >= BLOCK_16X16 ? TX_16X16 : TX_8X8) : TX_4X4;
      vp9_encode_intra_block_plane(x, bsize, 0);
      this_error = vp9_get_mb_ss(x->plane[0].src_diff);

574
      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
575
        vp9_clear_system_state();
576
        this_error = (int)(this_error * error_weight);
577
      }
John Koleszar's avatar
John Koleszar committed
578

Adrian Grange's avatar
Adrian Grange committed
579
580
      // Intrapenalty below deals with situations where the intra and inter
      // error scores are very low (e.g. a plain black frame).
581
582
583
584
      // 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
585
586
587
      // 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
588
      // Accumulate the intra error.
John Koleszar's avatar
John Koleszar committed
589
590
      intra_error += (int64_t)this_error;

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

Adrian Grange's avatar
Adrian Grange committed
596
      // Other than for the first frame do a motion search.
John Koleszar's avatar
John Koleszar committed
597
      if (cm->current_video_frame > 0) {
598
        int tmp_err, motion_error;
John Koleszar's avatar
John Koleszar committed
599
        int_mv mv, tmp_mv;
600

601
        xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
602
603
        motion_error = get_prediction_error(bsize, &x->plane[0].src,
                                            &xd->plane[0].pre[0]);
Adrian Grange's avatar
Adrian Grange committed
604
        // Assume 0,0 motion with no mv overhead.
John Koleszar's avatar
John Koleszar committed
605
606
607
        mv.as_int = tmp_mv.as_int = 0;

        // Test last reference frame using the previous best mv as the
Adrian Grange's avatar
Adrian Grange committed
608
        // starting point (best reference) for the search.
609
        first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
610
                                 &motion_error);
611
        if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
612
          vp9_clear_system_state();
613
          motion_error = (int)(motion_error * error_weight);
614
        }
John Koleszar's avatar
John Koleszar committed
615

616
617
        // If the current best reference mv is not centered on 0,0 then do a 0,0
        // based search as well.
John Koleszar's avatar
John Koleszar committed
618
619
        if (best_ref_mv.as_int) {
          tmp_err = INT_MAX;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
620
          first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
621
                                   &tmp_err);
622
          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
623
            vp9_clear_system_state();
624
            tmp_err = (int)(tmp_err * error_weight);
625
          }
John Koleszar's avatar
John Koleszar committed
626
627
628
629
630
631

          if (tmp_err < motion_error) {
            motion_error = tmp_err;
            mv.as_int = tmp_mv.as_int;
          }
        }
John Koleszar's avatar
John Koleszar committed
632

Adrian Grange's avatar
Adrian Grange committed
633
        // Search in an older reference frame.
634
        if (cm->current_video_frame > 1 && gld_yv12 != NULL) {
Adrian Grange's avatar
Adrian Grange committed
635
          // Assume 0,0 motion with no mv overhead.
636
637
638
          int gf_motion_error;

          xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
639
640
          gf_motion_error = get_prediction_error(bsize, &x->plane[0].src,
                                                 &xd->plane[0].pre[0]);
John Koleszar's avatar
John Koleszar committed
641

Dmitry Kovalev's avatar
Dmitry Kovalev committed
642
          first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
643
                                   &gf_motion_error);
644
          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
645
            vp9_clear_system_state();
646
            gf_motion_error = (int)(gf_motion_error * error_weight);
647
          }
John Koleszar's avatar
John Koleszar committed
648

Dmitry Kovalev's avatar
Dmitry Kovalev committed
649
          if (gf_motion_error < motion_error && gf_motion_error < this_error)
Adrian Grange's avatar
Adrian Grange committed
650
            ++second_ref_count;
John Koleszar's avatar
John Koleszar committed
651

Adrian Grange's avatar
Adrian Grange committed
652
          // Reset to last frame as reference buffer.
653
654
655
          xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
          xd->plane[1].pre[0].buf = first_ref_buf->u_buffer + recon_uvoffset;
          xd->plane[2].pre[0].buf = first_ref_buf->v_buffer + recon_uvoffset;
John Koleszar's avatar
John Koleszar committed
656

Adrian Grange's avatar
Adrian Grange committed
657
658
659
660
          // In accumulating a score for the older reference frame take the
          // best of the motion predicted score and the intra coded error
          // (just as will be done for) accumulation of "coded_error" for
          // the last frame.
John Koleszar's avatar
John Koleszar committed
661
662
663
664
          if (gf_motion_error < this_error)
            sr_coded_error += gf_motion_error;
          else
            sr_coded_error += this_error;
665
        } else {
John Koleszar's avatar
John Koleszar committed
666
          sr_coded_error += motion_error;
667
        }
Adrian Grange's avatar
Adrian Grange committed
668
        // Start by assuming that intra mode is best.
669
        best_ref_mv.as_int = 0;
John Koleszar's avatar
John Koleszar committed
670

John Koleszar's avatar
John Koleszar committed
671
        if (motion_error <= this_error) {
Adrian Grange's avatar
Adrian Grange committed
672
673
674
          // Keep a count of cases where the inter and intra were very close
          // and very low. This helps with scene cut detection for example in
          // cropped clips with black bars at the sides or top and bottom.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
675
676
          if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
              this_error < 2 * intrapenalty)
Adrian Grange's avatar
Adrian Grange committed
677
            ++neutral_count;
John Koleszar's avatar
John Koleszar committed
678

Yaowu Xu's avatar
Yaowu Xu committed
679
680
          mv.as_mv.row *= 8;
          mv.as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
681
          this_error = motion_error;
682
683
684
685
686
          xd->mi[0]->mbmi.mode = NEWMV;
          xd->mi[0]->mbmi.mv[0] = mv;
          xd->mi[0]->mbmi.tx_size = TX_4X4;
          xd->mi[0]->mbmi.ref_frame[0] = LAST_FRAME;
          xd->mi[0]->mbmi.ref_frame[1] = NONE;
687
          vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
688
          vp9_encode_sby_pass1(x, bsize);
John Koleszar's avatar
John Koleszar committed
689
690
691
692
693
694
          sum_mvr += mv.as_mv.row;
          sum_mvr_abs += abs(mv.as_mv.row);
          sum_mvc += mv.as_mv.col;
          sum_mvc_abs += abs(mv.as_mv.col);
          sum_mvrs += mv.as_mv.row * mv.as_mv.row;
          sum_mvcs += mv.as_mv.col * mv.as_mv.col;
Adrian Grange's avatar
Adrian Grange committed
695
          ++intercount;
John Koleszar's avatar
John Koleszar committed
696
697
698
699

          best_ref_mv.as_int = mv.as_int;

          if (mv.as_int) {
Adrian Grange's avatar
Adrian Grange committed
700
            ++mvcount;
John Koleszar's avatar
John Koleszar committed
701

Adrian Grange's avatar
Adrian Grange committed
702
            // Non-zero vector, was it different from the last non zero vector?
John Koleszar's avatar
John Koleszar committed
703
            if (mv.as_int != lastmv_as_int)
Adrian Grange's avatar
Adrian Grange committed
704
              ++new_mv_count;
John Koleszar's avatar
John Koleszar committed
705
706
            lastmv_as_int = mv.as_int;

Adrian Grange's avatar
Adrian Grange committed
707
            // Does the row vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
708
709
            if (mb_row < cm->mb_rows / 2) {
              if (mv.as_mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
710
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
711
              else if (mv.as_mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
712
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
713
714
            } else if (mb_row > cm->mb_rows / 2) {
              if (mv.as_mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
715
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
716
              else if (mv.as_mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
717
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
718
719
            }

Adrian Grange's avatar
Adrian Grange committed
720
            // Does the col vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
721
722
            if (mb_col < cm->mb_cols / 2) {
              if (mv.as_mv.col > 0)
Adrian Grange's avatar
Adrian Grange committed
723
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
724
              else if (mv.as_mv.col < 0)
Adrian Grange's avatar
Adrian Grange committed
725
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
726
727
            } else if (mb_col > cm->mb_cols / 2) {
              if (mv.as_mv.col > 0)
Adrian Grange's avatar
Adrian Grange committed
728
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
729
              else if (mv.as_mv.col < 0)
Adrian Grange's avatar
Adrian Grange committed
730
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
731
732
            }
          }
John Koleszar's avatar
John Koleszar committed
733
        }
734
      } else {
John Koleszar's avatar
John Koleszar committed
735
        sr_coded_error += (int64_t)this_error;
736
      }
John Koleszar's avatar
John Koleszar committed
737
      coded_error += (int64_t)this_error;
John Koleszar's avatar
John Koleszar committed
738

Adrian Grange's avatar
Adrian Grange committed
739
      // Adjust to the next column of MBs.
John Koleszar's avatar
John Koleszar committed
740
      x->plane[0].src.buf += 16;
Alex Converse's avatar
Alex Converse committed
741
742
      x->plane[1].src.buf += uv_mb_height;
      x->plane[2].src.buf += uv_mb_height;
John Koleszar's avatar
John Koleszar committed
743

John Koleszar's avatar
John Koleszar committed
744
      recon_yoffset += 16;
Alex Converse's avatar
Alex Converse committed
745
      recon_uvoffset += uv_mb_height;
John Koleszar's avatar
John Koleszar committed
746
747
    }

Adrian Grange's avatar
Adrian Grange committed
748
    // Adjust to the next row of MBs.
John Koleszar's avatar
John Koleszar committed
749
    x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
Alex Converse's avatar
Alex Converse committed
750
751
752
753
    x->plane[1].src.buf += uv_mb_height * x->plane[1].src.stride -
                           uv_mb_height * cm->mb_cols;
    x->plane[2].src.buf += uv_mb_height * x->plane[1].src.stride -
                           uv_mb_height * cm->mb_cols;
John Koleszar's avatar
John Koleszar committed
754

755
    vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
756
757
  }

758
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
759
  {
760
761
    FIRSTPASS_STATS fps;

762
    fps.frame = cm->current_video_frame;
763
    fps.spatial_layer_id = cpi->svc.spatial_layer_id;
764
765
766
    fps.intra_error = (double)(intra_error >> 8);
    fps.coded_error = (double)(coded_error >> 8);
    fps.sr_coded_error = (double)(sr_coded_error >> 8);
767
768
769
770
    fps.count = 1.0;
    fps.pcnt_inter = (double)intercount / cm->MBs;
    fps.pcnt_second_ref = (double)second_ref_count / cm->MBs;
    fps.pcnt_neutral = (double)neutral_count / cm->MBs;
John Koleszar's avatar
John Koleszar committed
771
772

    if (mvcount > 0) {
773
774
775
776
      fps.MVr = (double)sum_mvr / mvcount;
      fps.mvr_abs = (double)sum_mvr_abs / mvcount;
      fps.MVc = (double)sum_mvc / mvcount;
      fps.mvc_abs = (double)sum_mvc_abs / mvcount;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
777
778
      fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / mvcount)) / mvcount;
      fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / mvcount;
779
      fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2);
John Koleszar's avatar
John Koleszar committed
780
      fps.new_mv_count = new_mv_count;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
781
      fps.pcnt_motion = (double)mvcount / cm->MBs;
782
783
784
785
786
787
788
789
790
791
    } else {
      fps.MVr = 0.0;
      fps.mvr_abs = 0.0;
      fps.MVc = 0.0;
      fps.mvc_abs = 0.0;
      fps.MVrv = 0.0;
      fps.MVcv = 0.0;
      fps.mv_in_out_count = 0.0;
      fps.new_mv_count = 0.0;
      fps.pcnt_motion = 0.0;
Paul Wilkins's avatar
Paul Wilkins committed
792
    }
John Koleszar's avatar
John Koleszar committed
793

794
795
796
    // TODO(paulwilkins):  Handle the case when duration is set to 0, or
    // something less than the full time between subsequent values of
    // cpi->source_time_stamp.
797
    fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start);
John Koleszar's avatar
John Koleszar committed
798

Adrian Grange's avatar
Adrian Grange committed
799
    // Don't want to do output stats with a stack variable!
800
801
    twopass->this_frame_stats = fps;
    output_stats(&twopass->this_frame_stats, cpi->output_pkt_list);
802
    accumulate_stats(&twopass->total_stats, &fps);
John Koleszar's avatar
John Koleszar committed
803
804
805
  }

  // Copy the previous Last Frame back into gf and and arf buffers if
Adrian Grange's avatar
Adrian Grange committed
806
  // the prediction is good enough... but also don't allow it to lag too far.
807
  if ((twopass->sr_update_lag > 3) ||
John Koleszar's avatar
John Koleszar committed
808
      ((cm->current_video_frame > 0) &&
809
810
811
       (twopass->this_frame_stats.pcnt_inter > 0.20) &&
       ((twopass->this_frame_stats.intra_error /
         DOUBLE_DIVIDE_CHECK(twopass->this_frame_stats.coded_error)) > 2.0))) {
812
813
814
    if (gld_yv12 != NULL) {
      vp8_yv12_copy_frame(lst_yv12, gld_yv12);
    }
815
    twopass->sr_update_lag = 1;
816
  } else {
Adrian Grange's avatar
Adrian Grange committed
817
    ++twopass->sr_update_lag;
818
  }
819

820
821
  vp9_extend_frame_borders(new_yv12);

822
823
824
825
826
827
  if (cpi->use_svc && cpi->svc.number_temporal_layers == 1) {
    vp9_update_reference_frames(cpi);
  } else {
    // Swap frame pointers so last frame refers to the frame we just compressed.
    swap_yv12(lst_yv12, new_yv12);
  }
828

829
830
  // Special case for the first frame. Copy into the GF buffer as a second
  // reference.
831
  if (cm->current_video_frame == 0 && gld_yv12 != NULL) {
John Koleszar's avatar
John Koleszar committed
832
    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
833
  }
John Koleszar's avatar
John Koleszar committed
834

Adrian Grange's avatar
Adrian Grange committed
835
  // Use this to see what the first pass reconstruction looks like.
John Koleszar's avatar
John Koleszar committed
836
837
838
  if (0) {
    char filename[512];
    FILE *recon_file;
839
840
    snprintf(filename, sizeof(filename), "enc%04d.yuv",
             (int)cm->current_video_frame);
John Koleszar's avatar
John Koleszar committed
841

John Koleszar's avatar
John Koleszar committed
842
843
844
845
846
    if (cm->current_video_frame == 0)
      recon_file = fopen(filename, "wb");
    else
      recon_file = fopen(filename, "ab");

Frank Galligan's avatar
Frank Galligan committed
847
    (void)fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file);
John Koleszar's avatar
John Koleszar committed
848
849
    fclose(recon_file);
  }
John Koleszar's avatar
John Koleszar committed
850

Adrian Grange's avatar
Adrian Grange committed
851
  ++cm->current_video_frame;
John Koleszar's avatar
John Koleszar committed
852
853
}

John Koleszar's avatar
John Koleszar committed
854
855
856
857
static double calc_correction_factor(double err_per_mb,
                                     double err_divisor,
                                     double pt_low,
                                     double pt_high,
858
859
                                     int q) {
  const double error_term = err_per_mb / err_divisor;
860

John Koleszar's avatar
John Koleszar committed
861
  // Adjustment based on actual quantizer to power term.
Paul Wilkins's avatar
Paul Wilkins committed
862
  const double power_term = MIN(vp9_convert_qindex_to_q(q) * 0.0125 + pt_low,
863
                                pt_high);
864

Adrian Grange's avatar
Adrian Grange committed
865
  // Calculate correction factor.
John Koleszar's avatar
John Koleszar committed
866
867
  if (power_term < 1.0)
    assert(error_term >= 0.0);
868

869
  return fclamp(pow(error_term, power_term), 0.05, 5.0);
870
871
}

872
873
874
static int get_twopass_worst_quality(const VP9_COMP *cpi,
                                     const FIRSTPASS_STATS *stats,
                                     int section_target_bandwidth) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
875
  const RATE_CONTROL *const rc = &cpi->rc;
876
  const VP9EncoderConfig *const oxcf = &cpi->oxcf;
John Koleszar's avatar
John Koleszar committed
877

878
879
880
881
882
883
  if (section_target_bandwidth <= 0) {
    return rc->worst_quality;  // Highest value allowed
  } else {
    const int num_mbs = cpi->common.MBs;
    const double section_err = stats->coded_error / stats->count;
    const double err_per_mb = section_err / num_mbs;
884
    const double speed_term = 1.0 + 0.04 * oxcf->speed;
885
886
887
    const int target_norm_bits_per_mb = ((uint64_t)section_target_bandwidth <<
                                            BPER_MB_NORMBITS) / num_mbs;
    int q;
888
889
890
891
892
    int is_svc_upper_layer = 0;
    if (cpi->use_svc && cpi->svc.number_temporal_layers == 1 &&
        cpi->svc.spatial_layer_id > 0) {
      is_svc_upper_layer = 1;
    }
893
894
895
896

    // Try and pick a max Q that will be high enough to encode the
    // content at the given rate.
    for (q = rc->best_quality; q < rc->worst_quality; ++q) {
897
898
      const double factor =
          calc_correction_factor(err_per_mb, ERR_DIVISOR,
899
900
                                 is_svc_upper_layer ? SVC_FACTOR_PT_LOW :
                                 FACTOR_PT_LOW, FACTOR_PT_HIGH, q);
901
902
903
904
905
      const int bits_per_mb = vp9_rc_bits_per_mb(INTER_FRAME, q,
                                                 factor * speed_term);
      if (bits_per_mb <= target_norm_bits_per_mb)
        break;
    }
John Koleszar's avatar
John Koleszar committed
906

907
    // Restriction on active max q for constrained quality mode.
908
    if (cpi->oxcf.rc_mode == RC_MODE_CONSTRAINED_QUALITY)
909
      q = MAX(q, oxcf->cq_level);
910
    return q;
John Koleszar's avatar
John Koleszar committed
911
  }
John Koleszar's avatar
John Koleszar committed
912