vp9_encoder.c 88 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
 */

Jim Bankoski's avatar
Jim Bankoski committed
11
12
13
14
15
16
#include <math.h>
#include <stdio.h>
#include <limits.h>

#include "./vpx_config.h"
#include "./vpx_scale_rtcd.h"
17
18
#include "vpx/internal/vpx_psnr.h"
#include "vpx_ports/vpx_timer.h"
John Koleszar's avatar
John Koleszar committed
19

Jim Bankoski's avatar
Jim Bankoski committed
20
#include "vp9/common/vp9_alloccommon.h"
21
#include "vp9/common/vp9_filter.h"
22
#include "vp9/common/vp9_idct.h"
Jim Bankoski's avatar
Jim Bankoski committed
23
24
25
#if CONFIG_VP9_POSTPROC
#include "vp9/common/vp9_postproc.h"
#endif
26
#include "vp9/common/vp9_reconinter.h"
27
#include "vp9/common/vp9_systemdependent.h"
Jim Bankoski's avatar
Jim Bankoski committed
28
#include "vp9/common/vp9_tile_common.h"
29

30
#include "vp9/encoder/vp9_aq_complexity.h"
Marco Paniconi's avatar
Marco Paniconi committed
31
32
#include "vp9/encoder/vp9_aq_cyclicrefresh.h"
#include "vp9/encoder/vp9_aq_variance.h"
33
#include "vp9/encoder/vp9_bitstream.h"
34
#include "vp9/encoder/vp9_context_tree.h"
35
#include "vp9/encoder/vp9_encodeframe.h"
36
#include "vp9/encoder/vp9_encodemv.h"
37
#include "vp9/encoder/vp9_firstpass.h"
Jim Bankoski's avatar
Jim Bankoski committed
38
#include "vp9/encoder/vp9_mbgraph.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
39
#include "vp9/encoder/vp9_encoder.h"
Jim Bankoski's avatar
Jim Bankoski committed
40
#include "vp9/encoder/vp9_picklpf.h"
41
#include "vp9/encoder/vp9_ratectrl.h"
42
#include "vp9/encoder/vp9_rdopt.h"
Jim Bankoski's avatar
Jim Bankoski committed
43
#include "vp9/encoder/vp9_segmentation.h"
Yaowu Xu's avatar
Yaowu Xu committed
44
#include "vp9/encoder/vp9_speed_features.h"
Dmitry Kovalev's avatar
Dmitry Kovalev committed
45
46
47
#if CONFIG_INTERNAL_STATS
#include "vp9/encoder/vp9_ssim.h"
#endif
48
#include "vp9/encoder/vp9_temporal_filter.h"
49
#include "vp9/encoder/vp9_resize.h"
50
#include "vp9/encoder/vp9_svc_layercontext.h"
Paul Wilkins's avatar
Paul Wilkins committed
51

52
void vp9_coef_tree_initialize();
53

Adrian Grange's avatar
Adrian Grange committed
54
55
#define DEFAULT_INTERP_FILTER SWITCHABLE

56
57
#define SHARP_FILTER_QTHRESH 0          /* Q threshold for 8-tap sharp filter */

Jim Bankoski's avatar
Jim Bankoski committed
58
59
60
61
62
63
#define ALTREF_HIGH_PRECISION_MV 1      // Whether to use high precision mv
                                         //  for altref computation.
#define HIGH_PRECISION_MV_QTHRESH 200   // Q threshold for high precision
                                         // mv. Choose a very high value for
                                         // now so that HIGH_PRECISION is always
                                         // chosen.
64

John Koleszar's avatar
John Koleszar committed
65
// #define OUTPUT_YUV_REC
John Koleszar's avatar
John Koleszar committed
66

67
68
69
#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file;
#endif
John Koleszar's avatar
John Koleszar committed
70
71
72
#ifdef OUTPUT_YUV_SRC
FILE *yuv_file;
#endif
73
74
75
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
#endif
John Koleszar's avatar
John Koleszar committed
76
77
78

#if 0
FILE *framepsnr;
Yaowu Xu's avatar
Yaowu Xu committed
79
FILE *kf_list;
John Koleszar's avatar
John Koleszar committed
80
81
82
FILE *keyfile;
#endif

83
static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) {
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  switch (mode) {
    case NORMAL:
      *hr = 1;
      *hs = 1;
      break;
    case FOURFIVE:
      *hr = 4;
      *hs = 5;
      break;
    case THREEFIVE:
      *hr = 3;
      *hs = 5;
    break;
    case ONETWO:
      *hr = 1;
      *hs = 2;
    break;
    default:
      *hr = 1;
      *hs = 1;
       assert(0);
      break;
  }
}

Deb Mukherjee's avatar
Deb Mukherjee committed
109
static void set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) {
110
  MACROBLOCK *const mb = &cpi->mb;
Deb Mukherjee's avatar
Deb Mukherjee committed
111
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
112
  if (cpi->common.allow_high_precision_mv) {
113
114
115
116
117
118
119
    mb->mvcost = mb->nmvcost_hp;
    mb->mvsadcost = mb->nmvsadcost_hp;
  } else {
    mb->mvcost = mb->nmvcost;
    mb->mvsadcost = mb->nmvsadcost;
  }
}
Paul Wilkins's avatar
Paul Wilkins committed
120

121
122
123
124
125
126
127
static void setup_frame(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  // Set up entropy context depending on frame type. The decoder mandates
  // the use of the default context, index 0, for keyframes and inter
  // frames where the error_resilient_mode or intra_only flag is set. For
  // other inter-frames the encoder currently uses only two contexts;
  // context 1 for ALTREF frames and context 0 for the others.
128
129
130
131
132
133
134
  if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
    vp9_setup_past_independence(cm);
  } else {
    if (!cpi->use_svc)
      cm->frame_context_idx = cpi->refresh_alt_ref_frame;
  }

135
  if (cm->frame_type == KEY_FRAME) {
136
137
    cpi->refresh_golden_frame = 1;
    cpi->refresh_alt_ref_frame = 1;
138
  } else {
139
    cm->fc = cm->frame_contexts[cm->frame_context_idx];
140
141
142
  }
}

143
void vp9_initialize_enc() {
John Koleszar's avatar
John Koleszar committed
144
145
146
  static int init_done = 0;

  if (!init_done) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
147
    vp9_init_neighbors();
148
    vp9_coef_tree_initialize();
149
150
    vp9_tokenize_initialize();
    vp9_init_me_luts();
151
    vp9_rc_init_minq_luts();
152
    vp9_entropy_mv_init();
153
    vp9_entropy_mode_init();
154
    vp9_temporal_filter_init();
John Koleszar's avatar
John Koleszar committed
155
156
    init_done = 1;
  }
John Koleszar's avatar
John Koleszar committed
157
158
}

159
static void dealloc_compressor_data(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
160
  VP9_COMMON *const cm = &cpi->common;
161
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
162

John Koleszar's avatar
John Koleszar committed
163
164
  // Delete sementation map
  vpx_free(cpi->segmentation_map);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
165
166
167
  cpi->segmentation_map = NULL;
  vpx_free(cm->last_frame_seg_map);
  cm->last_frame_seg_map = NULL;
John Koleszar's avatar
John Koleszar committed
168
  vpx_free(cpi->coding_context.last_frame_seg_map_copy);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
169
  cpi->coding_context.last_frame_seg_map_copy = NULL;
John Koleszar's avatar
John Koleszar committed
170

171
  vpx_free(cpi->complexity_map);
172
173
174
175
176
  cpi->complexity_map = NULL;

  vp9_cyclic_refresh_free(cpi->cyclic_refresh);
  cpi->cyclic_refresh = NULL;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
177
  vp9_free_frame_buffers(cm);
178
  vp9_free_context_buffers(cm);
John Koleszar's avatar
John Koleszar committed
179

180
181
  vp9_free_frame_buffer(&cpi->last_frame_uf);
  vp9_free_frame_buffer(&cpi->scaled_source);
182
  vp9_free_frame_buffer(&cpi->scaled_last_source);
183
  vp9_free_frame_buffer(&cpi->alt_ref_buffer);
184
  vp9_lookahead_destroy(cpi->lookahead);
John Koleszar's avatar
John Koleszar committed
185

John Koleszar's avatar
John Koleszar committed
186
187
  vpx_free(cpi->tok);
  cpi->tok = 0;
John Koleszar's avatar
John Koleszar committed
188

189
  vp9_free_pc_tree(cpi);
190

191
192
193
194
195
196
  for (i = 0; i < cpi->svc.number_spatial_layers; ++i) {
    LAYER_CONTEXT *const lc = &cpi->svc.layer_context[i];
    vpx_free(lc->rc_twopass_stats_in.buf);
    lc->rc_twopass_stats_in.buf = NULL;
    lc->rc_twopass_stats_in.sz = 0;
  }
John Koleszar's avatar
John Koleszar committed
197
198
}

199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
static void save_coding_context(VP9_COMP *cpi) {
  CODING_CONTEXT *const cc = &cpi->coding_context;
  VP9_COMMON *cm = &cpi->common;

  // Stores a snapshot of key state variables which can subsequently be
  // restored with a call to vp9_restore_coding_context. These functions are
  // intended for use in a re-code loop in vp9_compress_frame where the
  // quantizer value is adjusted between loop iterations.
  vp9_copy(cc->nmvjointcost,  cpi->mb.nmvjointcost);
  vp9_copy(cc->nmvcosts,  cpi->mb.nmvcosts);
  vp9_copy(cc->nmvcosts_hp,  cpi->mb.nmvcosts_hp);

  vp9_copy(cc->segment_pred_probs, cm->seg.pred_probs);

  vpx_memcpy(cpi->coding_context.last_frame_seg_map_copy,
             cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols));

  vp9_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
  vp9_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);

  cc->fc = cm->fc;
}

static void restore_coding_context(VP9_COMP *cpi) {
  CODING_CONTEXT *const cc = &cpi->coding_context;
  VP9_COMMON *cm = &cpi->common;

  // Restore key state variables to the snapshot state stored in the
  // previous call to vp9_save_coding_context.
  vp9_copy(cpi->mb.nmvjointcost, cc->nmvjointcost);
  vp9_copy(cpi->mb.nmvcosts, cc->nmvcosts);
  vp9_copy(cpi->mb.nmvcosts_hp, cc->nmvcosts_hp);

  vp9_copy(cm->seg.pred_probs, cc->segment_pred_probs);

  vpx_memcpy(cm->last_frame_seg_map,
             cpi->coding_context.last_frame_seg_map_copy,
             (cm->mi_rows * cm->mi_cols));

  vp9_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
  vp9_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);

  cm->fc = cc->fc;
}

244
static void configure_static_seg_features(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
245
  VP9_COMMON *const cm = &cpi->common;
246
  const RATE_CONTROL *const rc = &cpi->rc;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
247
  struct segmentation *const seg = &cm->seg;
248

249
  int high_q = (int)(rc->avg_q > 48.0);
John Koleszar's avatar
John Koleszar committed
250
  int qi_delta;
251

John Koleszar's avatar
John Koleszar committed
252
253
254
  // Disable and clear down for KF
  if (cm->frame_type == KEY_FRAME) {
    // Clear down the global segmentation map
255
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
256
257
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
258
    cpi->static_mb_pct = 0;
259

John Koleszar's avatar
John Koleszar committed
260
    // Disable segmentation
261
    vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
262

John Koleszar's avatar
John Koleszar committed
263
    // Clear down the segment features.
264
    vp9_clearall_segfeatures(seg);
265
266
  } else if (cpi->refresh_alt_ref_frame) {
    // If this is an alt ref frame
John Koleszar's avatar
John Koleszar committed
267
    // Clear down the global segmentation map
268
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
269
270
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
271
    cpi->static_mb_pct = 0;
Paul Wilkins's avatar
Paul Wilkins committed
272

John Koleszar's avatar
John Koleszar committed
273
    // Disable segmentation and individual segment features by default
274
    vp9_disable_segmentation(seg);
275
    vp9_clearall_segfeatures(seg);
Paul Wilkins's avatar
Paul Wilkins committed
276

John Koleszar's avatar
John Koleszar committed
277
278
    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
279
    vp9_update_mbgraph_stats(cpi);
Paul Wilkins's avatar
Paul Wilkins committed
280

John Koleszar's avatar
John Koleszar committed
281
282
    // If segmentation was enabled set those features needed for the
    // arf itself.
283
284
285
    if (seg->enabled) {
      seg->update_map = 1;
      seg->update_data = 1;
Paul Wilkins's avatar
Paul Wilkins committed
286

287
      qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875);
288
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
289
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Paul Wilkins's avatar
Paul Wilkins committed
290

291
292
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
293

John Koleszar's avatar
John Koleszar committed
294
      // Where relevant assume segment data is delta data
295
      seg->abs_delta = SEGMENT_DELTADATA;
296
    }
297
  } else if (seg->enabled) {
298
299
    // All other frames if segmentation has been enabled

John Koleszar's avatar
John Koleszar committed
300
    // First normal frame in a valid gf or alt ref group
301
    if (rc->frames_since_golden == 0) {
Paul Wilkins's avatar
Paul Wilkins committed
302
      // Set up segment features for normal frames in an arf group
303
      if (rc->source_alt_ref_active) {
304
305
306
        seg->update_map = 0;
        seg->update_data = 1;
        seg->abs_delta = SEGMENT_DELTADATA;
Paul Wilkins's avatar
Paul Wilkins committed
307

308
        qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125);
309
        vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
310
        vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Paul Wilkins's avatar
Paul Wilkins committed
311

312
313
        vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
        vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Paul Wilkins's avatar
Paul Wilkins committed
314

John Koleszar's avatar
John Koleszar committed
315
316
        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
317
318
319
          vp9_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
          vp9_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
          vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
320
        }
321
322
323
324
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

325
        vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
326

327
        vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
Paul Wilkins's avatar
Paul Wilkins committed
328

329
330
        seg->update_map = 0;
        seg->update_data = 0;
Paul Wilkins's avatar
Paul Wilkins committed
331

332
        vp9_clearall_segfeatures(seg);
John Koleszar's avatar
John Koleszar committed
333
      }
334
    } else if (rc->is_src_frame_alt_ref) {
335
336
337
      // Special case where we are coding over the top of a previous
      // alt ref frame.
      // Segment coding disabled for compred testing
John Koleszar's avatar
John Koleszar committed
338

Paul Wilkins's avatar
Paul Wilkins committed
339
      // Enable ref frame features for segment 0 as well
340
341
      vp9_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
      vp9_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
John Koleszar's avatar
John Koleszar committed
342

Paul Wilkins's avatar
Paul Wilkins committed
343
      // All mbs should use ALTREF_FRAME
344
345
346
347
      vp9_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
      vp9_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
      vp9_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
      vp9_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
John Koleszar's avatar
John Koleszar committed
348

Paul Wilkins's avatar
Paul Wilkins committed
349
      // Skip all MBs if high Q (0,0 mv and skip coeffs)
John Koleszar's avatar
John Koleszar committed
350
      if (high_q) {
351
352
        vp9_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
353
      }
Adrian Grange's avatar
Adrian Grange committed
354
      // Enable data update
355
      seg->update_data = 1;
356
357
358
    } else {
      // All other frames.

John Koleszar's avatar
John Koleszar committed
359
      // No updates.. leave things as they are.
360
361
      seg->update_map = 0;
      seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
362
363
    }
  }
364
365
}

366
static void update_reference_segmentation_map(VP9_COMP *cpi) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
367
  VP9_COMMON *const cm = &cpi->common;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
368
369
  MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
  uint8_t *cache_ptr = cm->last_frame_seg_map;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
370
371
  int row, col;

372
  for (row = 0; row < cm->mi_rows; row++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
373
374
    MODE_INFO **mi_8x8 = mi_8x8_ptr;
    uint8_t *cache = cache_ptr;
375
376
    for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
      cache[0] = mi_8x8[0]->mbmi.segment_id;
377
    mi_8x8_ptr += cm->mi_stride;
378
    cache_ptr += cm->mi_cols;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
379
380
381
  }
}

382

383
static void set_speed_features(VP9_COMP *cpi) {
384
#if CONFIG_INTERNAL_STATS
385
  int i;
386
  for (i = 0; i < MAX_MODES; ++i)
John Koleszar's avatar
John Koleszar committed
387
    cpi->mode_chosen_counts[i] = 0;
388
#endif
John Koleszar's avatar
John Koleszar committed
389

390
  vp9_set_speed_features(cpi);
391

392
  // Set rd thresholds based on mode and speed setting
393
394
  vp9_set_rd_speed_thresholds(cpi);
  vp9_set_rd_speed_thresholds_sub8x8(cpi);
John Koleszar's avatar
John Koleszar committed
395
}
396

397
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
398
  VP9_COMMON *cm = &cpi->common;
399
  const VP9EncoderConfig *oxcf = &cpi->oxcf;
400

Dmitry Kovalev's avatar
Dmitry Kovalev committed
401
  cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
402
                                      cm->subsampling_x, cm->subsampling_y,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
403
                                      oxcf->lag_in_frames);
John Koleszar's avatar
John Koleszar committed
404
  if (!cpi->lookahead)
405
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
406
                       "Failed to allocate lag buffers");
John Koleszar's avatar
John Koleszar committed
407

408
  if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
409
                               oxcf->width, oxcf->height,
410
                               cm->subsampling_x, cm->subsampling_y,
411
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
412
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
413
                       "Failed to allocate altref buffer");
John Koleszar's avatar
John Koleszar committed
414
}
415

416
417
static void alloc_ref_frame_buffers(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
418
  if (vp9_alloc_frame_buffers(cm, cm->width, cm->height))
419
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
420
                       "Failed to allocate frame buffers");
John Koleszar's avatar
John Koleszar committed
421
422
}

423
static void alloc_util_frame_buffers(VP9_COMP *cpi) {
424
  VP9_COMMON *const cm = &cpi->common;
425
426
427
  if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
428
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
429
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
430
                       "Failed to allocate last frame buffer");
431

432
433
434
  if (vp9_realloc_frame_buffer(&cpi->scaled_source,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
435
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
436
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
437
                       "Failed to allocate scaled source buffer");
438

439
440
441
442
443
  if (vp9_realloc_frame_buffer(&cpi->scaled_last_source,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
444
445
                       "Failed to allocate scaled last source buffer");
}
446

447
448
void vp9_alloc_compressor_data(VP9_COMP *cpi) {
  VP9_COMMON *cm = &cpi->common;
449

450
451
452
453
454
455
456
  vp9_alloc_context_buffers(cm, cm->width, cm->height);

  vpx_free(cpi->tok);

  {
    unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
    CHECK_MEM_ERROR(cm, cpi->tok, vpx_calloc(tokens, sizeof(*cpi->tok)));
457
  }
458

459
460
461
462
463
464
465
  vp9_setup_pc_tree(&cpi->common, cpi);
}

static void update_frame_size(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
  vp9_update_frame_size(cm);
466
  init_macroblockd(cm, xd);
467
468
}

James Zern's avatar
James Zern committed
469
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
470
471
  cpi->oxcf.framerate = framerate < 0.1 ? 30 : framerate;
  vp9_rc_update_framerate(cpi);
John Koleszar's avatar
John Koleszar committed
472
473
}

474
int64_t vp9_rescale(int64_t val, int64_t num, int denom) {
John Koleszar's avatar
John Koleszar committed
475
476
477
  int64_t llnum = num;
  int64_t llden = denom;
  int64_t llval = val;
478

Jingning Han's avatar
Jingning Han committed
479
  return (llval * llnum / llden);
480
481
}

Ronald S. Bultje's avatar
Ronald S. Bultje committed
482
483
static void set_tile_limits(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
484

Dmitry Kovalev's avatar
Dmitry Kovalev committed
485
486
  int min_log2_tile_cols, max_log2_tile_cols;
  vp9_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
487

Dmitry Kovalev's avatar
Dmitry Kovalev committed
488
489
490
  cm->log2_tile_cols = clamp(cpi->oxcf.tile_columns,
                             min_log2_tile_cols, max_log2_tile_cols);
  cm->log2_tile_rows = cpi->oxcf.tile_rows;
491
}
492

493
494
495
496
497
498
static void init_buffer_indices(VP9_COMP *cpi) {
  cpi->lst_fb_idx = 0;
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
}

499
static void init_config(struct VP9_COMP *cpi, VP9EncoderConfig *oxcf) {
500
  VP9_COMMON *const cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
501

John Koleszar's avatar
John Koleszar committed
502
  cpi->oxcf = *oxcf;
John Koleszar's avatar
John Koleszar committed
503

504
505
  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
John Koleszar's avatar
John Koleszar committed
506

507
508
  cm->width = oxcf->width;
  cm->height = oxcf->height;
509
  vp9_alloc_compressor_data(cpi);
510

511
512
513
514
515
  // Spatial scalability.
  cpi->svc.number_spatial_layers = oxcf->ss_number_layers;
  // Temporal scalability.
  cpi->svc.number_temporal_layers = oxcf->ts_number_layers;

516
  if ((cpi->svc.number_temporal_layers > 1 &&
517
      cpi->oxcf.rc_mode == VPX_CBR) ||
518
      (cpi->svc.number_spatial_layers > 1 &&
Dmitry Kovalev's avatar
Dmitry Kovalev committed
519
      cpi->oxcf.mode == TWO_PASS_SECOND_BEST)) {
520
    vp9_init_layer_context(cpi);
521
522
  }

John Koleszar's avatar
John Koleszar committed
523
  // change includes all joint functionality
Dmitry Kovalev's avatar
Dmitry Kovalev committed
524
  vp9_change_config(cpi, oxcf);
John Koleszar's avatar
John Koleszar committed
525

John Koleszar's avatar
John Koleszar committed
526
  cpi->static_mb_pct = 0;
527
  cpi->ref_frame_flags = 0;
528

529
  init_buffer_indices(cpi);
530

Ronald S. Bultje's avatar
Ronald S. Bultje committed
531
  set_tile_limits(cpi);
John Koleszar's avatar
John Koleszar committed
532
533
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
static int get_pass(MODE mode) {
  switch (mode) {
    case REALTIME:
    case ONE_PASS_GOOD:
    case ONE_PASS_BEST:
      return 0;

    case TWO_PASS_FIRST:
      return 1;

    case TWO_PASS_SECOND_GOOD:
    case TWO_PASS_SECOND_BEST:
      return 2;
  }
  return -1;
}

551
void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
552
  VP9_COMMON *const cm = &cpi->common;
553
  RATE_CONTROL *const rc = &cpi->rc;
John Koleszar's avatar
John Koleszar committed
554

555
556
557
558
559
560
561
562
  if (cm->profile != oxcf->profile)
    cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;

  if (cm->profile <= PROFILE_1)
    assert(cm->bit_depth == BITS_8);
  else
    assert(cm->bit_depth > BITS_8);
John Koleszar's avatar
John Koleszar committed
563

John Koleszar's avatar
John Koleszar committed
564
  cpi->oxcf = *oxcf;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
565
  cpi->pass = get_pass(cpi->oxcf.mode);
John Koleszar's avatar
John Koleszar committed
566

567
  rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
John Koleszar's avatar
John Koleszar committed
568

569
570
  cpi->refresh_golden_frame = 0;
  cpi->refresh_last_frame = 1;
571
  cm->refresh_frame_context = 1;
572
  cm->reset_frame_context = 0;
John Koleszar's avatar
John Koleszar committed
573

574
  vp9_reset_segment_features(&cm->seg);
Deb Mukherjee's avatar
Deb Mukherjee committed
575
  set_high_precision_mv(cpi, 0);
John Koleszar's avatar
John Koleszar committed
576

John Koleszar's avatar
John Koleszar committed
577
578
  {
    int i;
John Koleszar's avatar
John Koleszar committed
579

Paul Wilkins's avatar
Paul Wilkins committed
580
    for (i = 0; i < MAX_SEGMENTS; i++)
John Koleszar's avatar
John Koleszar committed
581
582
      cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
  }
583
  cpi->encode_breakout = cpi->oxcf.encode_breakout;
John Koleszar's avatar
John Koleszar committed
584
585

  // local file playback mode == really big buffer
586
  if (cpi->oxcf.rc_mode == VPX_VBR) {
587
588
589
    cpi->oxcf.starting_buffer_level_ms = 60000;
    cpi->oxcf.optimal_buffer_level_ms = 60000;
    cpi->oxcf.maximum_buffer_size_ms = 240000;
John Koleszar's avatar
John Koleszar committed
590
591
  }

592
593
  rc->starting_buffer_level = vp9_rescale(cpi->oxcf.starting_buffer_level_ms,
                                          cpi->oxcf.target_bandwidth, 1000);
John Koleszar's avatar
John Koleszar committed
594
595

  // Set or reset optimal and maximum buffer levels.
596
597
  if (cpi->oxcf.optimal_buffer_level_ms == 0)
    rc->optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
John Koleszar's avatar
John Koleszar committed
598
  else
599
600
    rc->optimal_buffer_level = vp9_rescale(cpi->oxcf.optimal_buffer_level_ms,
                                           cpi->oxcf.target_bandwidth, 1000);
John Koleszar's avatar
John Koleszar committed
601

602
603
  if (cpi->oxcf.maximum_buffer_size_ms == 0)
    rc->maximum_buffer_size = cpi->oxcf.target_bandwidth / 8;
John Koleszar's avatar
John Koleszar committed
604
  else
605
606
    rc->maximum_buffer_size = vp9_rescale(cpi->oxcf.maximum_buffer_size_ms,
                                          cpi->oxcf.target_bandwidth, 1000);
607
608
  // Under a configuration change, where maximum_buffer_size may change,
  // keep buffer level clipped to the maximum allowed buffer size.
609
610
  rc->bits_off_target = MIN(rc->bits_off_target, rc->maximum_buffer_size);
  rc->buffer_level = MIN(rc->buffer_level, rc->maximum_buffer_size);
John Koleszar's avatar
John Koleszar committed
611
612

  // Set up frame rate and related parameters rate control values.
James Zern's avatar
James Zern committed
613
  vp9_new_framerate(cpi, cpi->oxcf.framerate);
John Koleszar's avatar
John Koleszar committed
614
615

  // Set absolute upper and lower quality limits
616
617
  rc->worst_quality = cpi->oxcf.worst_allowed_q;
  rc->best_quality = cpi->oxcf.best_allowed_q;
John Koleszar's avatar
John Koleszar committed
618

619
  cm->interp_filter = DEFAULT_INTERP_FILTER;
John Koleszar's avatar
John Koleszar committed
620

621
622
  cm->display_width = cpi->oxcf.width;
  cm->display_height = cpi->oxcf.height;
John Koleszar's avatar
John Koleszar committed
623

624
625
  if (cpi->initial_width) {
    // Increasing the size of the frame beyond the first seen frame, or some
Adrian Grange's avatar
Adrian Grange committed
626
    // otherwise signaled maximum size, is not supported.
627
628
629
    // TODO(jkoleszar): exit gracefully.
    assert(cm->width <= cpi->initial_width);
    assert(cm->height <= cpi->initial_height);
John Koleszar's avatar
John Koleszar committed
630
  }
631
  update_frame_size(cpi);
John Koleszar's avatar
John Koleszar committed
632

633
  if ((cpi->svc.number_temporal_layers > 1 &&
634
      cpi->oxcf.rc_mode == VPX_CBR) ||
635
      (cpi->svc.number_spatial_layers > 1 && cpi->pass == 2)) {
636
637
    vp9_update_layer_context_change_config(cpi,
                                           (int)cpi->oxcf.target_bandwidth);
638
639
  }

John Koleszar's avatar
John Koleszar committed
640
  cpi->alt_ref_source = NULL;
641
  rc->is_src_frame_alt_ref = 0;
Yaowu Xu's avatar
Yaowu Xu committed
642

John Koleszar's avatar
John Koleszar committed
643
#if 0
John Koleszar's avatar
John Koleszar committed
644
645
646
  // Experimental RD Code
  cpi->frame_distortion = 0;
  cpi->last_frame_distortion = 0;
John Koleszar's avatar
John Koleszar committed
647
648
#endif

Ronald S. Bultje's avatar
Ronald S. Bultje committed
649
  set_tile_limits(cpi);
Deb Mukherjee's avatar
Deb Mukherjee committed
650
651
652

  cpi->ext_refresh_frame_flags_pending = 0;
  cpi->ext_refresh_frame_context_pending = 0;
Tim Kopp's avatar
Tim Kopp committed
653
654
655

#if CONFIG_DENOISING
  vp9_denoiser_alloc(&(cpi->denoiser), cm->width, cm->height,
656
657
658
659
660
661
                     // TODO(tkopp) An unrelated bug causes
                     // cm->subsampling_{x,y} to be uninitialized at this point
                     // in execution. For now we assume YUV-420, which is x/y
                     // subsampling of 1.
                     1, 1,
                     // cm->subsampling_x, cm->subsampling_y,
Tim Kopp's avatar
Tim Kopp committed
662
663
                     VP9_ENC_BORDER_IN_PIXELS);
#endif
John Koleszar's avatar
John Koleszar committed
664
665
}

666
#ifndef M_LOG2_E
John Koleszar's avatar
John Koleszar committed
667
#define M_LOG2_E 0.693147180559945309417
668
#endif
John Koleszar's avatar
John Koleszar committed
669
#define log2f(x) (log (x) / (float) M_LOG2_E)
670
671
672
673
674

static void cal_nmvjointsadcost(int *mvjointsadcost) {
  mvjointsadcost[0] = 600;
  mvjointsadcost[1] = 300;
  mvjointsadcost[2] = 300;
675
  mvjointsadcost[3] = 300;
676
677
678
679
680
}

static void cal_nmvsadcosts(int *mvsadcost[2]) {
  int i = 1;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
681
682
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
683
684
685

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
686
687
688
689
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
690
691
692
693
694
695
  } while (++i <= MV_MAX);
}

static void cal_nmvsadcosts_hp(int *mvsadcost[2]) {
  int i = 1;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
696
697
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
698
699
700

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
701
702
703
704
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
705
706
707
  } while (++i <= MV_MAX);
}

708

709
VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
710
  unsigned int i, j;
711
712
  VP9_COMP *const cpi = vpx_memalign(32, sizeof(VP9_COMP));
  VP9_COMMON *const cm = cpi != NULL ? &cpi->common : NULL;
John Koleszar's avatar
John Koleszar committed
713

Dmitry Kovalev's avatar
Dmitry Kovalev committed
714
715
  if (!cm)
    return NULL;
John Koleszar's avatar
John Koleszar committed
716

Dmitry Kovalev's avatar
Dmitry Kovalev committed
717
  vp9_zero(*cpi);
John Koleszar's avatar
John Koleszar committed
718

John Koleszar's avatar
John Koleszar committed
719
  if (setjmp(cm->error.jmp)) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
720
721
    cm->error.setjmp = 0;
    vp9_remove_compressor(cpi);
John Koleszar's avatar
John Koleszar committed
722
723
724
    return 0;
  }

725
  cm->error.setjmp = 1;
John Koleszar's avatar
John Koleszar committed
726

Yaowu Xu's avatar
Yaowu Xu committed
727
  vp9_rtcd();
John Koleszar's avatar
John Koleszar committed
728

729
730
  cpi->use_svc = 0;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
731
  init_config(cpi, oxcf);
732
  vp9_rc_init(&cpi->oxcf, cpi->pass, &cpi->rc);
733

Dmitry Kovalev's avatar
Dmitry Kovalev committed
734
  cm->current_video_frame = 0;
John Koleszar's avatar
John Koleszar committed
735
736

  // Set reference frame sign bias for ALTREF frame to 1 (for now)
737
  cm->ref_frame_sign_bias[ALTREF_FRAME] = 1;
John Koleszar's avatar
John Koleszar committed
738
739

  cpi->gold_is_last = 0;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
740
741
  cpi->alt_is_last = 0;
  cpi->gold_is_alt = 0;
John Koleszar's avatar
John Koleszar committed
742
743

  // Create the encoder segmentation map and set all entries to 0
744
745
  CHECK_MEM_ERROR(cm, cpi->segmentation_map,
                  vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
John Koleszar's avatar
John Koleszar committed
746

747
748
749
750
  // Create a complexity map used for rd adjustment
  CHECK_MEM_ERROR(cm, cpi->complexity_map,
                  vpx_calloc(cm->mi_rows * cm->mi_cols, 1));

751
  // Create a map used for cyclic background refresh.
752
753
  CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
                  vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
754

John Koleszar's avatar
John Koleszar committed
755
756
  // And a place holder structure is the coding context
  // for use if we want to save and restore it
757
758
  CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy,
                  vpx_calloc(cm->mi_rows * cm->mi_cols, 1));
John Koleszar's avatar
John Koleszar committed
759
760
761

  for (i = 0; i < (sizeof(cpi->mbgraph_stats) /
                   sizeof(cpi->mbgraph_stats[0])); i++) {
762
763
764
    CHECK_MEM_ERROR(cm, cpi->mbgraph_stats[i].mb_stats,
                    vpx_calloc(cm->MBs *
                               sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
John Koleszar's avatar
John Koleszar committed
765
  }
766

767
  cpi->refresh_alt_ref_frame = 0;
John Koleszar's avatar
John Koleszar committed
768

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
  // Note that at the moment multi_arf will not work with svc.
  // For the current check in all the execution paths are defaulted to 0
  // pending further tuning and testing. The code is left in place here
  // as a place holder in regard to the required paths.
  if (cpi->pass == 2) {
    if (cpi->use_svc) {
      cpi->multi_arf_allowed = 0;
      cpi->multi_arf_enabled = 0;
    } else {
      // Disable by default for now.
      cpi->multi_arf_allowed = 0;
      cpi->multi_arf_enabled = 0;
    }
  } else {
    cpi->multi_arf_allowed = 0;
784
    cpi->multi_arf_enabled = 0;
785
  }
786

John Koleszar's avatar
John Koleszar committed
787
  cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
788
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
789
790
791
792
793
794
795
796
797
798
  cpi->b_calculate_ssimg = 0;

  cpi->count = 0;
  cpi->bytes = 0;

  if (cpi->b_calculate_psnr) {
    cpi->total_y = 0.0;
    cpi->total_u = 0.0;
    cpi->total_v = 0.0;
    cpi->total = 0.0;
799
800
801
    cpi->total_sq_error = 0;
    cpi->total_samples = 0;

John Koleszar's avatar
John Koleszar committed
802
803
804
805
    cpi->totalp_y = 0.0;
    cpi->totalp_u = 0.0;
    cpi->totalp_v = 0.0;
    cpi->totalp = 0.0;
806
807
808
    cpi->totalp_sq_error = 0;
    cpi->totalp_samples = 0;

John Koleszar's avatar
John Koleszar committed
809
810
811
    cpi->tot_recode_hits = 0;
    cpi->summed_quality = 0;
    cpi->summed_weights = 0;
812
813
    cpi->summedp_quality = 0;
    cpi->summedp_weights = 0;
John Koleszar's avatar
John Koleszar committed
814
815
816
817
818
819
820
821
  }

  if (cpi->b_calculate_ssimg) {
    cpi->total_ssimg_y = 0;
    cpi->total_ssimg_u = 0;
    cpi->total_ssimg_v = 0;
    cpi->total_ssimg_all = 0;
  }
John Koleszar's avatar
John Koleszar committed
822

823
824
#endif

825
  cpi->first_time_stamp_ever = INT64_MAX;
John Koleszar's avatar
John Koleszar committed
826

827
828
829
830
831
832
833
834
835
836
837
838
  cal_nmvjointsadcost(cpi->mb.nmvjointsadcost);
  cpi->mb.nmvcost[0] = &cpi->mb.nmvcosts[0][MV_MAX];
  cpi->mb.nmvcost[1] = &cpi->mb.nmvcosts[1][MV_MAX];
  cpi->mb.nmvsadcost[0] = &cpi->mb.nmvsadcosts[0][MV_MAX];
  cpi->mb.nmvsadcost[1] = &cpi->mb.nmvsadcosts[1][MV_MAX];
  cal_nmvsadcosts(cpi->mb.nmvsadcost);

  cpi->mb.nmvcost_hp[0] = &cpi->mb.nmvcosts_hp[0][MV_MAX];
  cpi->mb.nmvcost_hp[1] = &cpi->mb.nmvcosts_hp[1][MV_MAX];
  cpi->mb.nmvsadcost_hp[0] = &cpi->mb.nmvsadcosts_hp[0][MV_MAX];
  cpi->mb.nmvsadcost_hp[1] = &cpi->mb.nmvsadcosts_hp[1][MV_MAX];
  cal_nmvsadcosts_hp(cpi->mb.nmvsadcost_hp);
839

840
841
842
#ifdef OUTPUT_YUV_DENOISED
  yuv_denoised_file = fopen("denoised.yuv", "ab");
#endif
John Koleszar's avatar
John Koleszar committed
843
#ifdef OUTPUT_YUV_SRC
John Koleszar's avatar
John Koleszar committed
844
  yuv_file = fopen("bd.yuv", "ab");
John Koleszar's avatar
John Koleszar committed
845
#endif
846
#ifdef OUTPUT_YUV_REC
John Koleszar's avatar
John Koleszar committed
847
  yuv_rec_file = fopen("rec.yuv", "wb");
848
#endif
John Koleszar's avatar
John Koleszar committed
849
850

#if 0
John Koleszar's avatar
John Koleszar committed
851
852
  framepsnr = fopen("framepsnr.stt", "a");
  kf_list = fopen("kf_list.stt", "w");
John Koleszar's avatar
John Koleszar committed
853
854
#endif

John Koleszar's avatar
John Koleszar committed
855
  cpi->output_pkt_list = oxcf->output_pkt_list;
John Koleszar's avatar
John Koleszar committed
856

857
  cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
858

John Koleszar's avatar
John Koleszar committed
859
  if (cpi->pass == 1) {
860
    vp9_init_first_pass(cpi);
John Koleszar's avatar
John Koleszar committed
861
  } else if (cpi->pass == 2) {
862
863
    const size_t packet_sz = sizeof(FIRSTPASS_STATS);
    const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz);
John Koleszar's avatar
John Koleszar committed
864

865
866
867
868
869
870
871
872
873
    if (cpi->svc.number_spatial_layers > 1
        && cpi->svc.number_temporal_layers == 1) {
      FIRSTPASS_STATS *const stats = oxcf->two_pass_stats_in.buf;
      FIRSTPASS_STATS *stats_copy[VPX_SS_MAX_LAYERS] = {0};
      int i;

      for (i = 0; i < oxcf->ss_number_layers; ++i) {
        FIRSTPASS_STATS *const last_packet_for_layer =
            &stats[packets - oxcf->ss_number_layers + i];
874
        const int layer_id = (int)last_packet_for_layer->spatial_layer_id;
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
        const int packets_in_layer = (int)last_packet_for_layer->count + 1;
        if (layer_id >= 0 && layer_id < oxcf->ss_number_layers) {
          LAYER_CONTEXT *const lc = &cpi->svc.layer_context[layer_id];

          vpx_free(lc->rc_twopass_stats_in.buf);

          lc->rc_twopass_stats_in.sz = packets_in_layer * packet_sz;
          CHECK_MEM_ERROR(cm, lc->rc_twopass_stats_in.buf,
                          vpx_malloc(lc->rc_twopass_stats_in.sz));
          lc->twopass.stats_in_start = lc->rc_twopass_stats_in.buf;
          lc->twopass.stats_in = lc->twopass.stats_in_start;
          lc->twopass.stats_in_end = lc->twopass.stats_in_start
                                     + packets_in_layer - 1;
          stats_copy[layer_id] = lc->rc_twopass_stats_in.buf;
        }
      }

      for (i = 0; i < packets; ++i) {
893
        const int layer_id = (int)stats[i].spatial_layer_id;
894
895
896
897
898
899
        if (layer_id >= 0 && layer_id < oxcf->ss_number_layers
            && stats_copy[layer_id] != NULL) {
          *stats_copy[layer_id] = stats[i];
          ++stats_copy[layer_id];
        }
      }
900
901

      vp9_init_second_pass_spatial_svc(cpi);
902
903
904
905
906
    } else {
      cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
      cpi->twopass.stats_in = cpi->twopass.stats_in_start;
      cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];

907
908
      vp9_init_second_pass