vp9_firstpass.c 79.8 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
23

#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"
#include "vp9/common/vp9_reconinter.h"  // setup_dst_planes()
24
#include "vp9/common/vp9_systemdependent.h"
25

26
#include "vp9/encoder/vp9_block.h"
27
28
#include "vp9/encoder/vp9_encodeframe.h"
#include "vp9/encoder/vp9_encodemb.h"
29
#include "vp9/encoder/vp9_encodemv.h"
30
31
32
#include "vp9/encoder/vp9_extend.h"
#include "vp9/encoder/vp9_firstpass.h"
#include "vp9/encoder/vp9_mcomp.h"
33
#include "vp9/encoder/vp9_onyx_int.h"
34
#include "vp9/encoder/vp9_quantize.h"
35
#include "vp9/encoder/vp9_ratectrl.h"
36
#include "vp9/encoder/vp9_rdopt.h"
37
#include "vp9/encoder/vp9_vaq.h"
38
#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
John Koleszar's avatar
John Koleszar committed
49

50
51
#define KF_MB_INTRA_MIN 150
#define GF_MB_INTRA_MIN 100
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
52

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

55
56
57
#define MIN_KF_BOOST        300

#define DISABLE_RC_LONG_TERM_MEM 0
58

59
60
61
62
63
64
static void swap_yv12(YV12_BUFFER_CONFIG *a, YV12_BUFFER_CONFIG *b) {
  YV12_BUFFER_CONFIG temp = *a;
  *a = *b;
  *b = temp;
}

John Koleszar's avatar
John Koleszar committed
65
66
67
static int select_cq_level(int qindex) {
  int ret_val = QINDEX_RANGE - 1;
  int i;
Paul Wilkins's avatar
Paul Wilkins committed
68

69
  double target_q = (vp9_convert_qindex_to_q(qindex) * 0.5847) + 1.0;
Paul Wilkins's avatar
Paul Wilkins committed
70

Adrian Grange's avatar
Adrian Grange committed
71
  for (i = 0; i < QINDEX_RANGE; ++i) {
72
    if (target_q <= vp9_convert_qindex_to_q(i)) {
John Koleszar's avatar
John Koleszar committed
73
74
      ret_val = i;
      break;
Paul Wilkins's avatar
Paul Wilkins committed
75
    }
John Koleszar's avatar
John Koleszar committed
76
  }
Paul Wilkins's avatar
Paul Wilkins committed
77

John Koleszar's avatar
John Koleszar committed
78
  return ret_val;
Paul Wilkins's avatar
Paul Wilkins committed
79
}
Paul Wilkins's avatar
CQ Mode    
Paul Wilkins committed
80

81
82
83
84
85
86
87
88
89
90
91
92
93
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);
}

static int kfboost_qadjust(int qindex) {
  const double q = vp9_convert_qindex_to_q(qindex);
  return (int)((0.00000973 * q * q * q) +
               (-0.00613 * q * q) +
               (1.316 * q) + 121.2);
}
John Koleszar's avatar
John Koleszar committed
94

95
96
// Resets the first pass file to the given position using a relative seek from
// the current position.
97
98
99
static void reset_fpf_position(struct twopass_rc *p,
                               FIRSTPASS_STATS *position) {
  p->stats_in = position;
John Koleszar's avatar
John Koleszar committed
100
101
}

102
103
104
static int lookup_next_frame_stats(const struct twopass_rc *p,
                                   FIRSTPASS_STATS *next_frame) {
  if (p->stats_in >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
105
    return EOF;
John Koleszar's avatar
John Koleszar committed
106

107
  *next_frame = *p->stats_in;
John Koleszar's avatar
John Koleszar committed
108
  return 1;
John Koleszar's avatar
John Koleszar committed
109
110
}

111

Adrian Grange's avatar
Adrian Grange committed
112
// Read frame stats at an offset from the current position.
113
114
115
static int read_frame_stats(const struct twopass_rc *p,
                            FIRSTPASS_STATS *frame_stats, int offset) {
  const FIRSTPASS_STATS *fps_ptr = p->stats_in;
John Koleszar's avatar
John Koleszar committed
116

Adrian Grange's avatar
Adrian Grange committed
117
  // Check legality of offset.
John Koleszar's avatar
John Koleszar committed
118
  if (offset >= 0) {
119
    if (&fps_ptr[offset] >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
120
121
      return EOF;
  } else if (offset < 0) {
122
    if (&fps_ptr[offset] < p->stats_in_start)
John Koleszar's avatar
John Koleszar committed
123
124
125
126
127
      return EOF;
  }

  *frame_stats = fps_ptr[offset];
  return 1;
128
129
}

130
131
static int input_stats(struct twopass_rc *p, FIRSTPASS_STATS *fps) {
  if (p->stats_in >= p->stats_in_end)
John Koleszar's avatar
John Koleszar committed
132
    return EOF;
133

134
135
  *fps = *p->stats_in;
  ++p->stats_in;
John Koleszar's avatar
John Koleszar committed
136
  return 1;
137
138
}

139
140
static void output_stats(FIRSTPASS_STATS *stats,
                         struct vpx_codec_pkt_list *pktlist) {
John Koleszar's avatar
John Koleszar committed
141
142
143
144
145
  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);
146
147
148

// TEMP debug code
#if OUTPUT_FPF
John Koleszar's avatar
John Koleszar committed
149
150
151
152
  {
    FILE *fpfile;
    fpfile = fopen("firstpass.stt", "a");

153
    fprintf(fpfile, "%12.0f %12.0f %12.0f %12.0f %12.0f %12.4f %12.4f"
John Koleszar's avatar
John Koleszar committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
            "%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);
  }
177
178
179
#endif
}

John Koleszar's avatar
John Koleszar committed
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
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;
200
201
}

John Koleszar's avatar
John Koleszar committed
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
static void accumulate_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) {
  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;
222
223
}

John Koleszar's avatar
John Koleszar committed
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
static void subtract_stats(FIRSTPASS_STATS *section, FIRSTPASS_STATS *frame) {
  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;
244
245
}

John Koleszar's avatar
John Koleszar committed
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
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;
266
267
}

268
269
// Calculate a modified Error used in distributing bits between easier and
// harder frames.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
270
271
272
static double calculate_modified_err(const VP9_COMP *cpi,
                                     const FIRSTPASS_STATS *this_frame) {
  const struct twopass_rc *const twopass = &cpi->twopass;
273
  const FIRSTPASS_STATS *const stats = &twopass->total_stats;
274
  const double av_err = stats->ssim_weighted_pred_err / stats->count;
275
276
277
  double modified_error = av_err * pow(this_frame->ssim_weighted_pred_err /
                                           DOUBLE_DIVIDE_CHECK(av_err),
                                       cpi->oxcf.two_pass_vbrbias / 100.0);
278

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

283
static const double weight_table[256] = {
284
285
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
  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
321
322
};

323
static double simple_weight(const YV12_BUFFER_CONFIG *buf) {
John Koleszar's avatar
John Koleszar committed
324
  int i, j;
325
326
327
328
329
330
331
332
333
334
335
  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
336

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

340
// This function returns the maximum target rate per frame.
Dmitry Kovalev's avatar
Dmitry Kovalev committed
341
static int frame_max_bits(const VP9_COMP *cpi) {
342
  int64_t max_bits =
Paul Wilkins's avatar
Paul Wilkins committed
343
344
    ((int64_t)cpi->rc.av_per_frame_bandwidth *
     (int64_t)cpi->oxcf.two_pass_vbrmax_section) / 100;
345

Yaowu Xu's avatar
Yaowu Xu committed
346
  if (max_bits < 0)
Paul Wilkins's avatar
Paul Wilkins committed
347
348
349
350
    max_bits = 0;
  else if (max_bits > cpi->rc.max_frame_bandwidth)
    max_bits = cpi->rc.max_frame_bandwidth;

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

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

358
void vp9_end_first_pass(VP9_COMP *cpi) {
359
  output_stats(&cpi->twopass.total_stats, cpi->output_pkt_list);
360
}
John Koleszar's avatar
John Koleszar committed
361

362
363
364
365
366
367
368
369
370
371
372
373
374
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;
  }
}

375
static unsigned int zz_motion_search(const MACROBLOCK *x) {
376
  const MACROBLOCKD *const xd = &x->e_mbd;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
377
378
  const uint8_t *const src = x->plane[0].src.buf;
  const int src_stride = x->plane[0].src.stride;
379
  const uint8_t *const ref = xd->plane[0].pre[0].buf;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
380
381
  const int ref_stride = xd->plane[0].pre[0].stride;
  unsigned int sse;
382
383
  vp9_variance_fn_t fn = get_block_variance_fn(xd->mi_8x8[0]->mbmi.sb_type);
  fn(src, src_stride, ref, ref_stride, &sse);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
384
  return sse;
385
386
}

387
static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
388
                                     const MV *ref_mv, MV *best_mv,
389
                                     int *best_motion_err) {
John Koleszar's avatar
John Koleszar committed
390
  MACROBLOCKD *const xd = &x->e_mbd;
391
  MV tmp_mv = {0, 0};
392
393
  MV ref_mv_full = {ref_mv->row >> 3, ref_mv->col >> 3};
  int num00, tmp_err, n, sr = 0;
John Koleszar's avatar
John Koleszar committed
394
395
  int step_param = 3;
  int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
396
397
  const BLOCK_SIZE bsize = xd->mi_8x8[0]->mbmi.sb_type;
  vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
John Koleszar's avatar
John Koleszar committed
398
  int new_mv_mode_penalty = 256;
399
  const int quart_frm = MIN(cpi->common.width, cpi->common.height);
400

Adrian Grange's avatar
Adrian Grange committed
401
402
  // Refine the motion search range according to the frame dimension
  // for first pass test.
403
  while ((quart_frm << sr) < MAX_FULL_PEL_VAL)
Adrian Grange's avatar
Adrian Grange committed
404
    ++sr;
405

406
  step_param += sr;
407
408
  further_steps -= sr;

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

Adrian Grange's avatar
Adrian Grange committed
412
  // Center the initial step/diamond search on best mv.
413
  tmp_err = cpi->diamond_search_sad(x, &ref_mv_full, &tmp_mv,
414
                                    step_param,
John Koleszar's avatar
John Koleszar committed
415
                                    x->sadperbit16, &num00, &v_fn_ptr,
416
                                    x->nmvjointcost,
417
                                    x->mvcost, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
418
419
  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
420
421
422
423
424
  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;
425
426
    best_mv->row = tmp_mv.row;
    best_mv->col = tmp_mv.col;
John Koleszar's avatar
John Koleszar committed
427
428
  }

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

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

436
    if (num00) {
Adrian Grange's avatar
Adrian Grange committed
437
      --num00;
438
    } else {
439
      tmp_err = cpi->diamond_search_sad(x, &ref_mv_full, &tmp_mv,
John Koleszar's avatar
John Koleszar committed
440
441
                                        step_param + n, x->sadperbit16,
                                        &num00, &v_fn_ptr,
442
                                        x->nmvjointcost,
443
                                        x->mvcost, ref_mv);
Deb Mukherjee's avatar
Deb Mukherjee committed
444
445
      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
446
      if (tmp_err < INT_MAX - new_mv_mode_penalty)
John Koleszar's avatar
John Koleszar committed
447
448
        tmp_err += new_mv_mode_penalty;

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

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

468
void vp9_first_pass(VP9_COMP *cpi) {
John Koleszar's avatar
John Koleszar committed
469
  int mb_row, mb_col;
John Koleszar's avatar
John Koleszar committed
470
  MACROBLOCK *const x = &cpi->mb;
471
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
472
  MACROBLOCKD *const xd = &x->e_mbd;
James Zern's avatar
James Zern committed
473
  TileInfo tile;
474
475
  struct macroblock_plane *const p = x->plane;
  struct macroblockd_plane *const pd = xd->plane;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
476
  const PICK_MODE_CONTEXT *ctx = &x->sb64_context;
477
  int i;
John Koleszar's avatar
John Koleszar committed
478
479

  int recon_yoffset, recon_uvoffset;
480
481
  YV12_BUFFER_CONFIG *const lst_yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
  YV12_BUFFER_CONFIG *const gld_yv12 = get_ref_frame_buffer(cpi, GOLDEN_FRAME);
482
  YV12_BUFFER_CONFIG *const new_yv12 = get_frame_new_buffer(cm);
483
484
  const int recon_y_stride = lst_yv12->y_stride;
  const int recon_uv_stride = lst_yv12->uv_stride;
Alex Converse's avatar
Alex Converse committed
485
  const int uv_mb_height = 16 >> (lst_yv12->y_height > lst_yv12->uv_height);
John Koleszar's avatar
John Koleszar committed
486
487
488
489
490
491
  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;
492
  int64_t sum_mvrs = 0, sum_mvcs = 0;
John Koleszar's avatar
John Koleszar committed
493
494
495
496
497
498
499
500
  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;
501
  struct twopass_rc *const twopass = &cpi->twopass;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
502
  const MV zero_mv = {0, 0};
John Koleszar's avatar
John Koleszar committed
503

504
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
505

John Koleszar's avatar
John Koleszar committed
506
  vp9_setup_src_planes(x, cpi->Source, 0, 0);
507
  setup_pre_planes(xd, 0, lst_yv12, 0, 0, NULL);
508
  setup_dst_planes(xd, new_yv12, 0, 0);
John Koleszar's avatar
John Koleszar committed
509

510
  xd->mi_8x8 = cm->mi_grid_visible;
Adrian Grange's avatar
Adrian Grange committed
511
  xd->mi_8x8[0] = cm->mi;
John Koleszar's avatar
John Koleszar committed
512

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

515
  vp9_frame_init_quantizer(cpi);
John Koleszar's avatar
John Koleszar committed
516

517
518
  for (i = 0; i < MAX_MB_PLANE; ++i) {
    p[i].coeff = ctx->coeff_pbuf[i][1];
519
    p[i].qcoeff = ctx->qcoeff_pbuf[i][1];
520
    pd[i].dqcoeff = ctx->dqcoeff_pbuf[i][1];
521
    p[i].eobs = ctx->eobs_pbuf[i][1];
522
  }
523
  x->skip_recode = 0;
524

Dmitry Kovalev's avatar
Dmitry Kovalev committed
525
526
  vp9_init_mv_probs(cm);
  vp9_initialize_rd_consts(cpi);
John Koleszar's avatar
John Koleszar committed
527

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

Adrian Grange's avatar
Adrian Grange committed
531
  for (mb_row = 0; mb_row < cm->mb_rows; ++mb_row) {
John Koleszar's avatar
John Koleszar committed
532
533
534
535
    int_mv best_ref_mv;

    best_ref_mv.as_int = 0;

Adrian Grange's avatar
Adrian Grange committed
536
    // Reset above block coeffs.
John Koleszar's avatar
John Koleszar committed
537
538
    xd->up_available = (mb_row != 0);
    recon_yoffset = (mb_row * recon_y_stride * 16);
Alex Converse's avatar
Alex Converse committed
539
    recon_uvoffset = (mb_row * recon_uv_stride * uv_mb_height);
John Koleszar's avatar
John Koleszar committed
540

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

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

553
      vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
554

555
556
557
      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
558
      xd->left_available = (mb_col != 0);
559
      xd->mi_8x8[0]->mbmi.sb_type = bsize;
560
      xd->mi_8x8[0]->mbmi.ref_frame[0] = INTRA_FRAME;
James Zern's avatar
James Zern committed
561
      set_mi_row_col(xd, &tile,
562
563
                     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
564
                     cm->mi_rows, cm->mi_cols);
Jingning Han's avatar
Jingning Han committed
565

566
      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
567
        const int energy = vp9_block_energy(cpi, x, bsize);
568
569
570
        error_weight = vp9_vaq_inv_q_ratio(energy);
      }

Adrian Grange's avatar
Adrian Grange committed
571
      // Do intra 16x16 prediction.
572
      this_error = vp9_encode_intra(x, use_dc_pred);
573
      if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
574
        vp9_clear_system_state();
575
        this_error = (int)(this_error * error_weight);
576
      }
John Koleszar's avatar
John Koleszar committed
577

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

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

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

        xd->plane[0].pre[0].buf = lst_yv12->y_buffer + recon_yoffset;
601
        motion_error = zz_motion_search(x);
Adrian Grange's avatar
Adrian Grange committed
602
        // Assume 0,0 motion with no mv overhead.
John Koleszar's avatar
John Koleszar committed
603
604
605
        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
606
        // starting point (best reference) for the search.
607
        first_pass_motion_search(cpi, x, &best_ref_mv.as_mv, &mv.as_mv,
608
                                 &motion_error);
609
        if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
610
          vp9_clear_system_state();
611
          motion_error = (int)(motion_error * error_weight);
612
        }
John Koleszar's avatar
John Koleszar committed
613

614
615
        // 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
616
617
        if (best_ref_mv.as_int) {
          tmp_err = INT_MAX;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
618
          first_pass_motion_search(cpi, x, &zero_mv, &tmp_mv.as_mv,
619
                                   &tmp_err);
620
          if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
621
            vp9_clear_system_state();
622
            tmp_err = (int)(tmp_err * error_weight);
623
          }
John Koleszar's avatar
John Koleszar committed
624
625
626
627
628
629

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

Adrian Grange's avatar
Adrian Grange committed
631
        // Search in an older reference frame.
John Koleszar's avatar
John Koleszar committed
632
        if (cm->current_video_frame > 1) {
Adrian Grange's avatar
Adrian Grange committed
633
          // Assume 0,0 motion with no mv overhead.
634
635
636
          int gf_motion_error;

          xd->plane[0].pre[0].buf = gld_yv12->y_buffer + recon_yoffset;
637
          gf_motion_error = zz_motion_search(x);
John Koleszar's avatar
John Koleszar committed
638

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
646
          if (gf_motion_error < motion_error && gf_motion_error < this_error)
Adrian Grange's avatar
Adrian Grange committed
647
            ++second_ref_count;
John Koleszar's avatar
John Koleszar committed
648

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

Adrian Grange's avatar
Adrian Grange committed
654
655
656
657
          // 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
658
659
660
661
          if (gf_motion_error < this_error)
            sr_coded_error += gf_motion_error;
          else
            sr_coded_error += this_error;
662
        } else {
John Koleszar's avatar
John Koleszar committed
663
          sr_coded_error += motion_error;
664
        }
Adrian Grange's avatar
Adrian Grange committed
665
        // Start by assuming that intra mode is best.
666
        best_ref_mv.as_int = 0;
John Koleszar's avatar
John Koleszar committed
667

John Koleszar's avatar
John Koleszar committed
668
        if (motion_error <= this_error) {
Adrian Grange's avatar
Adrian Grange committed
669
670
671
          // 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
672
673
          if (((this_error - intrapenalty) * 9 <= motion_error * 10) &&
              this_error < 2 * intrapenalty)
Adrian Grange's avatar
Adrian Grange committed
674
            ++neutral_count;
John Koleszar's avatar
John Koleszar committed
675

Yaowu Xu's avatar
Yaowu Xu committed
676
677
          mv.as_mv.row *= 8;
          mv.as_mv.col *= 8;
John Koleszar's avatar
John Koleszar committed
678
          this_error = motion_error;
679
680
          xd->mi_8x8[0]->mbmi.mode = NEWMV;
          xd->mi_8x8[0]->mbmi.mv[0] = mv;
681
682
683
          xd->mi_8x8[0]->mbmi.tx_size = TX_4X4;
          xd->mi_8x8[0]->mbmi.ref_frame[0] = LAST_FRAME;
          xd->mi_8x8[0]->mbmi.ref_frame[1] = NONE;
684
          vp9_build_inter_predictors_sby(xd, mb_row << 1, mb_col << 1, bsize);
685
          vp9_encode_sby_pass1(x, bsize);
John Koleszar's avatar
John Koleszar committed
686
687
688
689
690
691
          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
692
          ++intercount;
John Koleszar's avatar
John Koleszar committed
693
694
695
696

          best_ref_mv.as_int = mv.as_int;

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

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

Adrian Grange's avatar
Adrian Grange committed
704
            // Does the row vector point inwards or outwards?
John Koleszar's avatar
John Koleszar committed
705
706
            if (mb_row < cm->mb_rows / 2) {
              if (mv.as_mv.row > 0)
Adrian Grange's avatar
Adrian Grange committed
707
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
708
              else if (mv.as_mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
709
                ++sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
710
711
            } else if (mb_row > cm->mb_rows / 2) {
              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
              else if (mv.as_mv.row < 0)
Adrian Grange's avatar
Adrian Grange committed
714
                --sum_in_vectors;
John Koleszar's avatar
John Koleszar committed
715
716
            }

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

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

John Koleszar's avatar
John Koleszar committed
741
      recon_yoffset += 16;
Alex Converse's avatar
Alex Converse committed
742
      recon_uvoffset += uv_mb_height;
John Koleszar's avatar
John Koleszar committed
743
744
    }

Adrian Grange's avatar
Adrian Grange committed
745
    // Adjust to the next row of MBs.
John Koleszar's avatar
John Koleszar committed
746
    x->plane[0].src.buf += 16 * x->plane[0].src.stride - 16 * cm->mb_cols;
Alex Converse's avatar
Alex Converse committed
747
748
749
750
    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
751

752
    vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
753
754
  }

755
  vp9_clear_system_state();
John Koleszar's avatar
John Koleszar committed
756
757
758
  {
    FIRSTPASS_STATS fps;

759
    fps.frame = cm->current_video_frame;
760
761
762
    fps.intra_error = (double)(intra_error >> 8);
    fps.coded_error = (double)(coded_error >> 8);
    fps.sr_coded_error = (double)(sr_coded_error >> 8);
763
    fps.ssim_weighted_pred_err = fps.coded_error * simple_weight(cpi->Source);
764
765
766
767
    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
768
769

    if (mvcount > 0) {
770
771
772
773
      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
774
775
      fps.MVrv = ((double)sum_mvrs - (fps.MVr * fps.MVr / mvcount)) / mvcount;
      fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / mvcount;
776
      fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2);
John Koleszar's avatar
John Koleszar committed
777
      fps.new_mv_count = new_mv_count;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
778
      fps.pcnt_motion = (double)mvcount / cm->MBs;
779
780
781
782
783
784
785
786
787
788
    } 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
789
    }
John Koleszar's avatar
John Koleszar committed
790

791
792
793
    // 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.
794
    fps.duration = (double)(cpi->source->ts_end - cpi->source->ts_start);
John Koleszar's avatar
John Koleszar committed
795

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

  // Copy the previous Last Frame back into gf and and arf buffers if
Adrian Grange's avatar
Adrian Grange committed
803
  // the prediction is good enough... but also don't allow it to lag too far.
804
  if ((twopass->sr_update_lag > 3) ||
John Koleszar's avatar
John Koleszar committed
805
      ((cm->current_video_frame > 0) &&
806
807
808
       (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))) {
John Koleszar's avatar
John Koleszar committed
809
    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
810
    twopass->sr_update_lag = 1;
811
  } else {
Adrian Grange's avatar
Adrian Grange committed
812
    ++twopass->sr_update_lag;
813
  }
Adrian Grange's avatar
Adrian Grange committed
814
  // Swap frame pointers so last frame refers to the frame we just compressed.
815
816
  swap_yv12(lst_yv12, new_yv12);

817
  vp9_extend_frame_borders(lst_yv12);
John Koleszar's avatar
John Koleszar committed
818

819
820
  // Special case for the first frame. Copy into the GF buffer as a second
  // reference.
821
  if (cm->current_video_frame == 0)
John Koleszar's avatar
John Koleszar committed
822
    vp8_yv12_copy_frame(lst_yv12, gld_yv12);
John Koleszar's avatar
John Koleszar committed
823

Adrian Grange's avatar
Adrian Grange committed
824
  // Use this to see what the first pass reconstruction looks like.
John Koleszar's avatar
John Koleszar committed
825
826
827
  if (0) {
    char filename[512];
    FILE *recon_file;
828
829
    snprintf(filename, sizeof(filename), "enc%04d.yuv",
             (int)cm->current_video_frame);
John Koleszar's avatar
John Koleszar committed
830

John Koleszar's avatar
John Koleszar committed
831
832
833
834
835
    if (cm->current_video_frame == 0)
      recon_file = fopen(filename, "wb");
    else
      recon_file = fopen(filename, "ab");

Frank Galligan's avatar
Frank Galligan committed
836
    (void)fwrite(lst_yv12->buffer_alloc, lst_yv12->frame_size, 1, recon_file);
John Koleszar's avatar
John Koleszar committed
837
838
    fclose(recon_file);
  }
John Koleszar's avatar
John Koleszar committed
839

Adrian Grange's avatar
Adrian Grange committed
840
  ++cm->current_video_frame;
John Koleszar's avatar
John Koleszar committed
841
842
}

Adrian Grange's avatar
Adrian Grange committed
843
844