vp9_firstpass.c 81.5 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

68
// #define LONG_TERM_VBR_CORRECTION
69

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

76
77
78
79
80
81
82
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);
}

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

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

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

99

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

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

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

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

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

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

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

141
    fprintf(fpfile, "%12.0f %12.0f %12.0f %12.0f %12.0f %12.4f %12.4f"
John Koleszar's avatar
John Koleszar committed
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
            "%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);
  }
165
166
167
#endif
}

John Koleszar's avatar
John Koleszar committed
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
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->ssim_weighted_pred_err = 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;
188
  section->spatial_layer_id = 0;
189
190
}

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

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

John Koleszar's avatar
John Koleszar committed
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
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->ssim_weighted_pred_err /= 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;
258
259
}

260
261
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
262
263
static double calculate_modified_err(const VP9_COMP *cpi,
                                     const FIRSTPASS_STATS *this_frame) {
Paul Wilkins's avatar
Paul Wilkins committed
264
  const TWO_PASS *twopass = &cpi->twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
265
  const SVC *const svc = &cpi->svc;
266
267
268
269
  const FIRSTPASS_STATS *stats;
  double av_err;
  double modified_error;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
270
271
272
  if (svc->number_spatial_layers > 1 &&
      svc->number_temporal_layers == 1) {
    twopass = &svc->layer_context[svc->spatial_layer_id].twopass;
273
274
275
276
277
278
279
  }

  stats = &twopass->total_stats;
  av_err = stats->ssim_weighted_pred_err / stats->count;
  modified_error = av_err * pow(this_frame->ssim_weighted_pred_err /
                   DOUBLE_DIVIDE_CHECK(av_err),
                   cpi->oxcf.two_pass_vbrbias / 100.0);
280

281
282
  return fclamp(modified_error,
                twopass->modified_error_min, twopass->modified_error_max);
John Koleszar's avatar
John Koleszar committed
283
284
}

285
static const double weight_table[256] = {
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.020000,
  0.020000, 0.020000, 0.020000, 0.020000, 0.020000, 0.031250, 0.062500,
  0.093750, 0.125000, 0.156250, 0.187500, 0.218750, 0.250000, 0.281250,
  0.312500, 0.343750, 0.375000, 0.406250, 0.437500, 0.468750, 0.500000,
  0.531250, 0.562500, 0.593750, 0.625000, 0.656250, 0.687500, 0.718750,
  0.750000, 0.781250, 0.812500, 0.843750, 0.875000, 0.906250, 0.937500,
  0.968750, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000, 1.000000,
  1.000000, 1.000000, 1.000000, 1.000000
323
324
};

325
static double simple_weight(const YV12_BUFFER_CONFIG *buf) {
John Koleszar's avatar
John Koleszar committed
326
  int i, j;
327
328
329
330
331
332
333
334
335
336
337
  double sum = 0.0;
  const int w = buf->y_crop_width;
  const int h = buf->y_crop_height;
  const uint8_t *row = buf->y_buffer;

  for (i = 0; i < h; ++i) {
    const uint8_t *pixel = row;
    for (j = 0; j < w; ++j)
      sum += weight_table[*pixel++];
    row += buf->y_stride;
  }
John Koleszar's avatar
John Koleszar committed
338

339
  return MAX(0.1, sum / (w * h));
John Koleszar's avatar
John Koleszar committed
340
341
}

342
// This function returns the maximum target rate per frame.
343
344
static int frame_max_bits(const RATE_CONTROL *rc,
                          const VP9EncoderConfig *oxcf) {
345
  int64_t max_bits = ((int64_t)rc->avg_frame_bandwidth *
Dmitry Kovalev's avatar
Dmitry Kovalev committed
346
                          (int64_t)oxcf->two_pass_vbrmax_section) / 100;
Yaowu Xu's avatar
Yaowu Xu committed
347
  if (max_bits < 0)
Paul Wilkins's avatar
Paul Wilkins committed
348
    max_bits = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
349
350
  else if (max_bits > rc->max_frame_bandwidth)
    max_bits = rc->max_frame_bandwidth;
Paul Wilkins's avatar
Paul Wilkins committed
351

Yaowu Xu's avatar
Yaowu Xu committed
352
  return (int)max_bits;
John Koleszar's avatar
John Koleszar committed
353
354
}

355
void vp9_init_first_pass(VP9_COMP *cpi) {
356
  zero_stats(&cpi->twopass.total_stats);
John Koleszar's avatar
John Koleszar committed
357
358
}

359
void vp9_end_first_pass(VP9_COMP *cpi) {
360
361
362
363
364
365
366
367
368
  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);
  }
369
}
John Koleszar's avatar
John Koleszar committed
370

371
372
373
374
375
376
377
378
379
380
381
382
383
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;
  }
}

384
385
386
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
387
  unsigned int sse;
388
389
  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
390
  return sse;
391
392
}

393
394
395
396
397
398
399
400
401
402
403
// 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;
}

404
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
405
                                     const MV *ref_mv, MV *best_mv,
406
                                     int *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
407
  MACROBLOCKD *const xd = &x->e_mbd;
408
  MV tmp_mv = {0, 0};
409
  MV ref_mv_full = {ref_mv->row >> 3, ref_mv->col >> 3};
410
  int num00, tmp_err, n;
411
  const BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
412
  vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
413
  const int new_mv_mode_penalty = 256;
414

415
416
417
  int step_param = 3;
  int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
  const int sr = get_search_range(&cpi->common);
418
  step_param += sr;
419
420
  further_steps -= sr;

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

Adrian Grange's avatar
Adrian Grange committed
424
  // Center the initial step/diamond search on best mv.
425
  tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
426
                                    step_param,
427
                                    x->sadperbit16, &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
428
429
  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
430
431
432
433
434
  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;
435
    *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
436
437
  }

Adrian Grange's avatar
Adrian Grange committed
438
  // Carry out further step/diamond searches as necessary.
John Koleszar's avatar
John Koleszar committed
439
440
441
442
  n = num00;
  num00 = 0;

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

445
    if (num00) {
Adrian Grange's avatar
Adrian Grange committed
446
      --num00;
447
    } else {
448
      tmp_err = cpi->diamond_search_sad(x, &cpi->ss_cfg, &ref_mv_full, &tmp_mv,
John Koleszar's avatar
John Koleszar committed
449
                                        step_param + n, x->sadperbit16,
450
                                        &num00, &v_fn_ptr, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
451
452
      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
453
      if (tmp_err < INT_MAX - new_mv_mode_penalty)
John Koleszar's avatar
John Koleszar committed
454
455
        tmp_err += new_mv_mode_penalty;

John Koleszar's avatar
John Koleszar committed
456
      if (tmp_err < *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
457
        *best_motion_err = tmp_err;
458
        *best_mv = tmp_mv;
John Koleszar's avatar
John Koleszar committed
459
      }
John Koleszar's avatar
John Koleszar committed
460
    }
John Koleszar's avatar
John Koleszar committed
461
  }
John Koleszar's avatar
John Koleszar committed
462
463
}

464
465
466
467
468
469
470
471
472
473
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;
  }
}

474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
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;
}

500
void vp9_first_pass(VP9_COMP *cpi) {
John Koleszar's avatar
John Koleszar committed
501
  int mb_row, mb_col;
John Koleszar's avatar
John Koleszar committed
502
  MACROBLOCK *const x = &cpi->mb;
503
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
504
  MACROBLOCKD *const xd = &x->e_mbd;
James Zern's avatar
James Zern committed
505
  TileInfo tile;
506
507
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
508
  const PICK_MODE_CONTEXT *ctx = &cpi->pc_root->none;
509
  int i;
John Koleszar's avatar
John Koleszar committed
510
511

  int recon_yoffset, recon_uvoffset;
512
  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
513
  YV12_BUFFER_CONFIG *gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
514
  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
515
516
517
  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
518
519
520
521
522
523
  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;
524
  int64_t sum_mvrs = 0, sum_mvcs = 0;
John Koleszar's avatar
John Koleszar committed
525
526
527
528
529
530
531
532
  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
533
  TWO_PASS *twopass = &cpi->twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
534
  const MV zero_mv = {0, 0};
535
  const YV12_BUFFER_CONFIG *first_ref_buf = lst_yv12;
John Koleszar's avatar
John Koleszar committed
536

537
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
538

539
540
541
  set_first_pass_params(cpi);
  vp9_set_quantizer(cm, find_fp_qindex());

542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
  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);
569
570
571

    cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
                                        &cpi->scaled_source);
572
573
  }

John Koleszar's avatar
John Koleszar committed
574
  vp9_setup_src_planes(x, cpi->Source, 0, 0);
575
  vp9_setup_pre_planes(xd, 0, first_ref_buf, 0, 0, NULL);
576
  vp9_setup_dst_planes(xd->plane, new_yv12, 0, 0);
John Koleszar's avatar
John Koleszar committed
577

578
579
  xd->mi = cm->mi_grid_visible;
  xd->mi[0] = cm->mi;
John Koleszar's avatar
John Koleszar committed
580

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

583
  vp9_frame_init_quantizer(cpi);
John Koleszar's avatar
John Koleszar committed
584

585
586
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][1];
587
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
588
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
589
    p[i].eobs = ctx->eobs_pbuf[i][1];
590
  }
591
  x->skip_recode = 0;
592

Dmitry Kovalev's avatar
Dmitry Kovalev committed
593
594
  vp9_init_mv_probs(cm);
  vp9_initialize_rd_consts(cpi);
John Koleszar's avatar
John Koleszar committed
595

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

Adrian Grange's avatar
Adrian Grange committed
599
  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
John Koleszar's avatar
John Koleszar committed
600
601
602
603
    int_mv best_ref_mv;

    best_ref_mv.as_int = 0;

Adrian Grange's avatar
Adrian Grange committed
604
    // Reset above block coeffs.
John Koleszar's avatar
John Koleszar committed
605
606
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
Alex Converse's avatar
Alex Converse committed
607
    recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
John Koleszar's avatar
John Koleszar committed
608

609
    // Set up limit values for motion vectors to prevent them extending
Adrian Grange's avatar
Adrian Grange committed
610
    // outside the UMV borders.
611
    x->mv_row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
John Koleszar's avatar
John Koleszar committed
612
    x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16)
613
                    + BORDER_MV_PIXELS_B16;
John Koleszar's avatar
John Koleszar committed
614

Adrian Grange's avatar
Adrian Grange committed
615
    for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
John Koleszar's avatar
John Koleszar committed
616
      int this_error;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
617
      const int use_dc_pred = (mb_col || mb_row) && (!mb_col || !mb_row);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
618
      double error_weight = 1.0;
619
      const BLOCK_SIZE bsize = get_bsize(cm, mb_row, mb_col);
620

621
      vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
622

623
624
625
      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
626
      xd->left_available = (mb_col != 0);
627
628
      xd->mi[0]->mbmi.sb_type = bsize;
      xd->mi[0]->mbmi.ref_frame[0] = INTRA_FRAME;
James Zern's avatar
James Zern committed
629
      set_mi_row_col(xd, &tile,
630
631
                     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
632
                     cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
633

634
      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
635
        const int energy = vp9_block_energy(cpi, x, bsize);
636
637
638
        error_weight = vp9_vaq_inv_q_ratio(energy);
      }

Adrian Grange's avatar
Adrian Grange committed
639
      // Do intra 16x16 prediction.
640
641
642
643
644
645
646
      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);

647
      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
648
        vp9_clear_system_state();
649
        this_error = (int)(this_error * error_weight);
650
      }
John Koleszar's avatar
John Koleszar committed
651

Adrian Grange's avatar
Adrian Grange committed
652
653
      // Intrapenalty below deals with situations where the intra and inter
      // error scores are very low (e.g. a plain black frame).
654
655
656
657
      // 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
658
659
660
      // 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
661
      // Accumulate the intra error.
John Koleszar's avatar
John Koleszar committed
662
663
      intra_error += (int64_t)this_error;

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

Adrian Grange's avatar
Adrian Grange committed
669
      // Other than for the first frame do a motion search.
John Koleszar's avatar
John Koleszar committed
670
      if (cm->current_video_frame > 0) {
671
        int tmp_err, motion_error;
John Koleszar's avatar
John Koleszar committed
672
        int_mv mv, tmp_mv;
673

674
        xd->plane[0].pre[0].buf = first_ref_buf->y_buffer + recon_yoffset;
675
676
        motion_error = get_prediction_error(bsize, &x->plane[0].src,
                                            &xd->plane[0].pre[0]);
Adrian Grange's avatar
Adrian Grange committed
677
        // Assume 0,0 motion with no mv overhead.
John Koleszar's avatar
John Koleszar committed
678
679
680
        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
681
        // starting point (best reference) for the search.
682
        first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
683
                                 &motion_error);
684
        if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
685
          vp9_clear_system_state();
686
          motion_error = (int)(motion_error * error_weight);
687
        }
John Koleszar's avatar
John Koleszar committed
688

689
690
        // 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
691
692
        if (best_ref_mv.as_int) {
          tmp_err = INT_MAX;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
693
          first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
694
                                   &tmp_err);
695
          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
696
            vp9_clear_system_state();
697
            tmp_err = (int)(tmp_err * error_weight);
698
          }
John Koleszar's avatar
John Koleszar committed
699
700
701
702
703
704

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

Adrian Grange's avatar
Adrian Grange committed
706
        // Search in an older reference frame.
707
        if (cm->current_video_frame > 1 && gld_yv12 != NULL) {
Adrian Grange's avatar
Adrian Grange committed
708
          // Assume 0,0 motion with no mv overhead.
709
710
711
          int gf_motion_error;

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
715
          first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
716
                                   &gf_motion_error);
717
          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
718
            vp9_clear_system_state();
719
            gf_motion_error = (int)(gf_motion_error * error_weight);
720
          }
John Koleszar's avatar
John Koleszar committed
721

Dmitry Kovalev's avatar
Dmitry Kovalev committed
722
          if (gf_motion_error < motion_error && gf_motion_error < this_error)
Adrian Grange's avatar
Adrian Grange committed
723
            ++second_ref_count;
John Koleszar's avatar
John Koleszar committed
724

Adrian Grange's avatar
Adrian Grange committed
725
          // Reset to last frame as reference buffer.
726
727
728
          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
729

Adrian Grange's avatar
Adrian Grange committed
730
731
732
733
          // 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
734
735
736
737
          if (gf_motion_error < this_error)
            sr_coded_error += gf_motion_error;
          else
            sr_coded_error += this_error;
738
        } else {
John Koleszar's avatar
John Koleszar committed
739
          sr_coded_error += motion_error;
740
        }
Adrian Grange's avatar
Adrian Grange committed
741
        // Start by assuming that intra mode is best.
742
        best_ref_mv.as_int = 0;
John Koleszar's avatar
John Koleszar committed
743

John Koleszar's avatar
John Koleszar committed
744
        if (motion_error <= this_error) {
Adrian Grange's avatar
Adrian Grange committed
745
746
747
          // 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
748
749
          if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
              this_error < 2 * intrapenalty)
Adrian Grange's avatar
Adrian Grange committed
750
            ++neutral_count;
John Koleszar's avatar
John Koleszar committed
751

Yaowu Xu's avatar
Yaowu Xu committed
752
753
          mv.as_mv.row *= 8;
          mv.as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
754
          this_error = motion_error;
755
756
757
758
759
          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;
760
          vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
761
          vp9_encode_sby_pass1(x, bsize);
John Koleszar's avatar
John Koleszar committed
762
763
764
765
766
767
          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
768
          ++intercount;
John Koleszar's avatar
John Koleszar committed
769
770
771
772

          best_ref_mv.as_int = mv.as_int;

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

Adrian Grange's avatar
Adrian Grange committed
775
            // Non-zero vector, was it different from the last non zero vector?
John Koleszar's avatar
John Koleszar committed
776
            if (mv.as_int != lastmv_as_int)
Adrian Grange's avatar
Adrian Grange committed
777
              ++new_mv_count;
John Koleszar's avatar
John Koleszar committed
778
779
            lastmv_as_int = mv.as_int;

Adrian Grange's avatar
Adrian Grange committed
780
            // Does the row vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
781
782
            if (mb_row < cm->mb_rows / 2) {
              if (mv.as_mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
783
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
784
              else if (mv.as_mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
785
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
786
787
            } else if (mb_row > cm->mb_rows / 2) {
              if (mv.as_mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
788
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
789
              else if (mv.as_mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
790
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
791
792
            }

Adrian Grange's avatar
Adrian Grange committed
793
            // Does the col vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
794
795
            if (mb_col < cm->mb_cols / 2) {
              if (mv.as_mv.col > 0)
Adrian Grange's avatar
Adrian Grange committed
796
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
797
              else if (mv.as_mv.col < 0)
Adrian Grange's avatar
Adrian Grange committed
798
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
799
800
            } else if (mb_col > cm->mb_cols / 2) {
              if (mv.as_mv.col > 0)
Adrian Grange's avatar
Adrian Grange committed
801
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
802
              else if (mv.as_mv.col < 0)
Adrian Grange's avatar
Adrian Grange committed
803
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
804
805
            }
          }
John Koleszar's avatar
John Koleszar committed
806
        }
807
      } else {
John Koleszar's avatar
John Koleszar committed
808
        sr_coded_error += (int64_t)this_error;
809
      }
John Koleszar's avatar
John Koleszar committed
810
      coded_error += (int64_t)this_error;
John Koleszar's avatar
John Koleszar committed
811

Adrian Grange's avatar
Adrian Grange committed
812
      // Adjust to the next column of MBs.
John Koleszar's avatar
John Koleszar committed
813
      x->plane[0].src.buf += 16;
Alex Converse's avatar
Alex Converse committed
814
815
      x->plane[1].src.buf += uv_mb_height;
      x->plane[2].src.buf += uv_mb_height;
John Koleszar's avatar
John Koleszar committed
816

John Koleszar's avatar
John Koleszar committed
817
      recon_yoffset += 16;
Alex Converse's avatar
Alex Converse committed
818
      recon_uvoffset += uv_mb_height;
John Koleszar's avatar
John Koleszar committed
819
820
    }

Adrian Grange's avatar
Adrian Grange committed
821
    // Adjust to the next row of MBs.
John Koleszar's avatar
John Koleszar committed
822
    x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
Alex Converse's avatar
Alex Converse committed
823
824
825
826
    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
827

828
    vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
829
830
  }

831
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
832
833
834
  {
    FIRSTPASS_STATS fps;

835
    fps.frame = cm->current_video_frame;
836
    fps.spatial_layer_id = cpi->svc.spatial_layer_id;
837
838
839
    fps.intra_error = (double)(intra_error >> 8);
    fps.coded_error = (double)(coded_error >> 8);
    fps.sr_coded_error = (double)(sr_coded_error >> 8);
840
    fps.ssim_weighted_pred_err = fps.coded_error * simple_weight(cpi->Source);
841
842
843
844
    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
845
846

    if (mvcount > 0) {
847
848
849
850
      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
851
852
      fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / mvcount)) / mvcount;
      fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / mvcount;
853
      fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2);
John Koleszar's avatar
John Koleszar committed
854
      fps.new_mv_count = new_mv_count;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
855
      fps.pcnt_motion = (double)mvcount / cm->MBs;
856
857
858
859
860
861
862
863
864
865
    } 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
866
    }
John Koleszar's avatar
John Koleszar committed
867

868
869
870
    // 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.
871
    fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start);
John Koleszar's avatar
John Koleszar committed
872

Adrian Grange's avatar
Adrian Grange committed
873
    // Don't want to do output stats with a stack variable!
874
    twopass->this_frame_stats = fps;
875
    output_stats(&twopass->this_frame_stats, cpi->output_pkt_list);
876
    accumulate_stats(&twopass->total_stats, &fps);
John Koleszar's avatar
John Koleszar committed
877
878
879
  }

  // Copy the previous Last Frame back into gf and and arf buffers if
Adrian Grange's avatar
Adrian Grange committed
880
  // the prediction is good enough... but also don't allow it to lag too far.
881
  if ((twopass->sr_update_lag > 3) ||
John Koleszar's avatar
John Koleszar committed
882
      ((cm->current_video_frame > 0) &&
883
884
885
       (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))) {
886
887
888
    if (gld_yv12 != NULL) {
      vp8_yv12_copy_frame(lst_yv12, gld_yv12);
    }
889
    twopass->sr_update_lag = 1;
890
  } else {
Adrian Grange's avatar
Adrian Grange committed
891
    ++twopass->sr_update_lag;
892
  }
893

894
895
  vp9_extend_frame_borders(new_yv12);

896
897
898
899
900
901
  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);
  }
902

903
904
  // Special case for the first frame. Copy into the GF buffer as a second
  // reference.
905
  if (cm->current_video_frame == 0 && gld_yv12 != NULL) {
John Koleszar's avatar
John Koleszar committed
906
    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
907
  }
John Koleszar's avatar
John Koleszar committed
908

Adrian Grange's avatar
Adrian Grange committed
909
  // Use this to see what the first pass reconstruction looks like.
John Koleszar's avatar
John Koleszar committed
910
911
912
  if (0) {
    char filename[512];
    FILE *recon_file;
913
914
    snprintf(filename, sizeof(filename), "enc%04d.yuv",
             (int)cm->current_video_frame);
John Koleszar's avatar
John Koleszar committed
915

John Koleszar's avatar
John Koleszar committed
916
917
918
919
920
    if (cm->current_video_frame == 0)
      recon_file = fopen(filename, "wb");
    else
      recon_file = fopen(filename, "ab");

Frank Galligan's avatar
Frank Galligan committed
921
    (void)fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file);
John Koleszar's avatar
John Koleszar committed
922
923
    fclose(recon_file);
  }
John Koleszar's avatar
John Koleszar committed
924

Adrian Grange's avatar
Adrian Grange committed
925
  ++cm->current_video_frame;
John Koleszar's avatar
John Koleszar committed
926
927
}