vp9_encoder.c 92 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_rd.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

54
55
#define SHARP_FILTER_QTHRESH 0          /* Q threshold for 8-tap sharp filter */

Jim Bankoski's avatar
Jim Bankoski committed
56
57
58
59
60
61
#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.
62

John Koleszar's avatar
John Koleszar committed
63
// #define OUTPUT_YUV_REC
John Koleszar's avatar
John Koleszar committed
64

65
#ifdef OUTPUT_YUV_DENOISED
66
FILE *yuv_denoised_file = NULL;
67
#endif
68
69
70
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
#endif
John Koleszar's avatar
John Koleszar committed
71
72
73

#if 0
FILE *framepsnr;
Yaowu Xu's avatar
Yaowu Xu committed
74
FILE *kf_list;
John Koleszar's avatar
John Koleszar committed
75
76
77
FILE *keyfile;
#endif

78
static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) {
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
  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;
  }
}

104
void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) {
105
  MACROBLOCK *const mb = &cpi->mb;
Deb Mukherjee's avatar
Deb Mukherjee committed
106
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
107
  if (cpi->common.allow_high_precision_mv) {
108
109
110
111
112
113
114
    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
115

116
117
118
119
120
121
122
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.
123
124
125
126
127
128
129
  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;
  }

130
  if (cm->frame_type == KEY_FRAME) {
131
    if (!is_spatial_svc(cpi))
132
      cpi->refresh_golden_frame = 1;
133
    cpi->refresh_alt_ref_frame = 1;
134
  } else {
135
    cm->fc = cm->frame_contexts[cm->frame_context_idx];
136
137
138
  }
}

139
void vp9_initialize_enc() {
John Koleszar's avatar
John Koleszar committed
140
141
142
  static int init_done = 0;

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

155
static void dealloc_compressor_data(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
156
  VP9_COMMON *const cm = &cpi->common;
157
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
158

John Koleszar's avatar
John Koleszar committed
159
160
  // Delete sementation map
  vpx_free(cpi->segmentation_map);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
161
162
163
  cpi->segmentation_map = NULL;
  vpx_free(cm->last_frame_seg_map);
  cm->last_frame_seg_map = NULL;
John Koleszar's avatar
John Koleszar committed
164
  vpx_free(cpi->coding_context.last_frame_seg_map_copy);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
165
  cpi->coding_context.last_frame_seg_map_copy = NULL;
John Koleszar's avatar
John Koleszar committed
166

167
  vpx_free(cpi->complexity_map);
168
169
170
171
172
  cpi->complexity_map = NULL;

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

Adrian Grange's avatar
Adrian Grange committed
173
  vp9_free_ref_frame_buffers(cm);
174
  vp9_free_context_buffers(cm);
John Koleszar's avatar
John Koleszar committed
175

176
177
  vp9_free_frame_buffer(&cpi->last_frame_uf);
  vp9_free_frame_buffer(&cpi->scaled_source);
178
  vp9_free_frame_buffer(&cpi->scaled_last_source);
179
  vp9_free_frame_buffer(&cpi->alt_ref_buffer);
180
  vp9_lookahead_destroy(cpi->lookahead);
John Koleszar's avatar
John Koleszar committed
181

John Koleszar's avatar
John Koleszar committed
182
183
  vpx_free(cpi->tok);
  cpi->tok = 0;
John Koleszar's avatar
John Koleszar committed
184

185
  vp9_free_pc_tree(cpi);
186

187
188
189
190
191
192
  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;
  }
193
194
195
196
197

  if (cpi->source_diff_var != NULL) {
    vpx_free(cpi->source_diff_var);
    cpi->source_diff_var = NULL;
  }
198

199
200
201
202
203
  for (i = 0; i < MAX_LAG_BUFFERS; ++i) {
    vp9_free_frame_buffer(&cpi->svc.scaled_frames[i]);
  }
  vpx_memset(&cpi->svc.scaled_frames[0], 0,
             MAX_LAG_BUFFERS * sizeof(cpi->svc.scaled_frames[0]));
John Koleszar's avatar
John Koleszar committed
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
244
245
246
247
248
249
250
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;
}

251
static void configure_static_seg_features(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
252
  VP9_COMMON *const cm = &cpi->common;
253
  const RATE_CONTROL *const rc = &cpi->rc;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
254
  struct segmentation *const seg = &cm->seg;
255

256
  int high_q = (int)(rc->avg_q > 48.0);
John Koleszar's avatar
John Koleszar committed
257
  int qi_delta;
258

John Koleszar's avatar
John Koleszar committed
259
260
261
  // Disable and clear down for KF
  if (cm->frame_type == KEY_FRAME) {
    // Clear down the global segmentation map
262
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
263
264
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
265
    cpi->static_mb_pct = 0;
266

John Koleszar's avatar
John Koleszar committed
267
    // Disable segmentation
268
    vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
269

John Koleszar's avatar
John Koleszar committed
270
    // Clear down the segment features.
271
    vp9_clearall_segfeatures(seg);
272
273
  } else if (cpi->refresh_alt_ref_frame) {
    // If this is an alt ref frame
John Koleszar's avatar
John Koleszar committed
274
    // Clear down the global segmentation map
275
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
276
277
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
278
    cpi->static_mb_pct = 0;
Paul Wilkins's avatar
Paul Wilkins committed
279

John Koleszar's avatar
John Koleszar committed
280
    // Disable segmentation and individual segment features by default
281
    vp9_disable_segmentation(seg);
282
    vp9_clearall_segfeatures(seg);
Paul Wilkins's avatar
Paul Wilkins committed
283

John Koleszar's avatar
John Koleszar committed
284
285
    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
286
    vp9_update_mbgraph_stats(cpi);
Paul Wilkins's avatar
Paul Wilkins committed
287

John Koleszar's avatar
John Koleszar committed
288
289
    // If segmentation was enabled set those features needed for the
    // arf itself.
290
291
292
    if (seg->enabled) {
      seg->update_map = 1;
      seg->update_data = 1;
Paul Wilkins's avatar
Paul Wilkins committed
293

294
      qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875);
295
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
296
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Paul Wilkins's avatar
Paul Wilkins committed
297

298
299
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
300

John Koleszar's avatar
John Koleszar committed
301
      // Where relevant assume segment data is delta data
302
      seg->abs_delta = SEGMENT_DELTADATA;
303
    }
304
  } else if (seg->enabled) {
305
306
    // All other frames if segmentation has been enabled

John Koleszar's avatar
John Koleszar committed
307
    // First normal frame in a valid gf or alt ref group
308
    if (rc->frames_since_golden == 0) {
Paul Wilkins's avatar
Paul Wilkins committed
309
      // Set up segment features for normal frames in an arf group
310
      if (rc->source_alt_ref_active) {
311
312
313
        seg->update_map = 0;
        seg->update_data = 1;
        seg->abs_delta = SEGMENT_DELTADATA;
Paul Wilkins's avatar
Paul Wilkins committed
314

315
        qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125);
316
        vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
317
        vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Paul Wilkins's avatar
Paul Wilkins committed
318

319
320
        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
321

John Koleszar's avatar
John Koleszar committed
322
323
        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
324
325
326
          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
327
        }
328
329
330
331
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

332
        vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
333

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

336
337
        seg->update_map = 0;
        seg->update_data = 0;
Paul Wilkins's avatar
Paul Wilkins committed
338

339
        vp9_clearall_segfeatures(seg);
John Koleszar's avatar
John Koleszar committed
340
      }
341
    } else if (rc->is_src_frame_alt_ref) {
342
343
344
      // 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
345

Paul Wilkins's avatar
Paul Wilkins committed
346
      // Enable ref frame features for segment 0 as well
347
348
      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
349

Paul Wilkins's avatar
Paul Wilkins committed
350
      // All mbs should use ALTREF_FRAME
351
352
353
354
      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
355

Paul Wilkins's avatar
Paul Wilkins committed
356
      // Skip all MBs if high Q (0,0 mv and skip coeffs)
John Koleszar's avatar
John Koleszar committed
357
      if (high_q) {
358
359
        vp9_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
360
      }
Adrian Grange's avatar
Adrian Grange committed
361
      // Enable data update
362
      seg->update_data = 1;
363
364
365
    } else {
      // All other frames.

John Koleszar's avatar
John Koleszar committed
366
      // No updates.. leave things as they are.
367
368
      seg->update_map = 0;
      seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
369
370
    }
  }
371
372
}

373
static void update_reference_segmentation_map(VP9_COMP *cpi) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
374
  VP9_COMMON *const cm = &cpi->common;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
375
376
  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
377
378
  int row, col;

379
  for (row = 0; row < cm->mi_rows; row++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
380
381
    MODE_INFO **mi_8x8 = mi_8x8_ptr;
    uint8_t *cache = cache_ptr;
382
383
    for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
      cache[0] = mi_8x8[0]->mbmi.segment_id;
384
    mi_8x8_ptr += cm->mi_stride;
385
    cache_ptr += cm->mi_cols;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
386
387
388
  }
}

389

390
static void set_speed_features(VP9_COMP *cpi) {
391
#if CONFIG_INTERNAL_STATS
392
  int i;
393
  for (i = 0; i < MAX_MODES; ++i)
John Koleszar's avatar
John Koleszar committed
394
    cpi->mode_chosen_counts[i] = 0;
395
#endif
John Koleszar's avatar
John Koleszar committed
396

397
  vp9_set_speed_features(cpi);
398

399
  // Set rd thresholds based on mode and speed setting
400
401
  vp9_set_rd_speed_thresholds(cpi);
  vp9_set_rd_speed_thresholds_sub8x8(cpi);
John Koleszar's avatar
John Koleszar committed
402
}
403

404
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
405
  VP9_COMMON *cm = &cpi->common;
406
  const VP9EncoderConfig *oxcf = &cpi->oxcf;
407

Dmitry Kovalev's avatar
Dmitry Kovalev committed
408
  cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
409
                                      cm->subsampling_x, cm->subsampling_y,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
410
                                      oxcf->lag_in_frames);
John Koleszar's avatar
John Koleszar committed
411
  if (!cpi->lookahead)
412
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
413
                       "Failed to allocate lag buffers");
John Koleszar's avatar
John Koleszar committed
414

415
  if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
416
                               oxcf->width, oxcf->height,
417
                               cm->subsampling_x, cm->subsampling_y,
418
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
419
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
420
                       "Failed to allocate altref buffer");
John Koleszar's avatar
John Koleszar committed
421
}
422

423
424
static void alloc_ref_frame_buffers(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
Adrian Grange's avatar
Adrian Grange committed
425
  if (vp9_alloc_ref_frame_buffers(cm, cm->width, cm->height))
426
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
427
                       "Failed to allocate frame buffers");
John Koleszar's avatar
John Koleszar committed
428
429
}

430
static void alloc_util_frame_buffers(VP9_COMP *cpi) {
431
  VP9_COMMON *const cm = &cpi->common;
432
433
434
  if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
                               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 last frame buffer");
438

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

446
447
448
449
450
  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,
451
452
                       "Failed to allocate scaled last source buffer");
}
453

454
455
void vp9_alloc_compressor_data(VP9_COMP *cpi) {
  VP9_COMMON *cm = &cpi->common;
456

457
458
459
460
461
462
463
  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)));
464
  }
465

466
467
468
469
470
471
  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;
Adrian Grange's avatar
Adrian Grange committed
472
473
474

  vp9_set_mb_mi(cm, cm->width, cm->height);
  vp9_init_context_buffers(cm);
475
  init_macroblockd(cm, xd);
476

477
  if (is_spatial_svc(cpi)) {
478
479
480
481
482
483
484
    if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
                                 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,
                         "Failed to reallocate alt_ref_buffer");
  }
485
486
}

James Zern's avatar
James Zern committed
487
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
488
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
489
  vp9_rc_update_framerate(cpi);
John Koleszar's avatar
John Koleszar committed
490
491
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
495
496
  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);
497

Dmitry Kovalev's avatar
Dmitry Kovalev committed
498
499
500
  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;
501
}
502

503
504
505
506
507
508
static void init_buffer_indices(VP9_COMP *cpi) {
  cpi->lst_fb_idx = 0;
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
}

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

John Koleszar's avatar
John Koleszar committed
512
  cpi->oxcf = *oxcf;
513
  cpi->framerate = oxcf->init_framerate;
John Koleszar's avatar
John Koleszar committed
514

515
516
  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
517
  cm->color_space = UNKNOWN;
John Koleszar's avatar
John Koleszar committed
518

519
520
  cm->width = oxcf->width;
  cm->height = oxcf->height;
521
  vp9_alloc_compressor_data(cpi);
522

523
524
525
526
527
  // Spatial scalability.
  cpi->svc.number_spatial_layers = oxcf->ss_number_layers;
  // Temporal scalability.
  cpi->svc.number_temporal_layers = oxcf->ts_number_layers;

528
529
  if ((cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) ||
      (cpi->svc.number_spatial_layers > 1 && cpi->oxcf.pass == 2)) {
530
    vp9_init_layer_context(cpi);
531
532
  }

John Koleszar's avatar
John Koleszar committed
533
  // change includes all joint functionality
Dmitry Kovalev's avatar
Dmitry Kovalev committed
534
  vp9_change_config(cpi, oxcf);
John Koleszar's avatar
John Koleszar committed
535

John Koleszar's avatar
John Koleszar committed
536
  cpi->static_mb_pct = 0;
537
  cpi->ref_frame_flags = 0;
538

539
  init_buffer_indices(cpi);
540

Ronald S. Bultje's avatar
Ronald S. Bultje committed
541
  set_tile_limits(cpi);
John Koleszar's avatar
John Koleszar committed
542
543
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
544
545
546
547
548
549
550
551
552
553
554
555
556
557
static void set_rc_buffer_sizes(RATE_CONTROL *rc,
                                const VP9EncoderConfig *oxcf) {
  const int64_t bandwidth = oxcf->target_bandwidth;
  const int64_t starting = oxcf->starting_buffer_level_ms;
  const int64_t optimal = oxcf->optimal_buffer_level_ms;
  const int64_t maximum = oxcf->maximum_buffer_size_ms;

  rc->starting_buffer_level = starting * bandwidth / 1000;
  rc->optimal_buffer_level = (optimal == 0) ? bandwidth / 8
                                            : optimal * bandwidth / 1000;
  rc->maximum_buffer_size = (maximum == 0) ? bandwidth / 8
                                           : maximum * bandwidth / 1000;
}

558
void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
559
  VP9_COMMON *const cm = &cpi->common;
560
  RATE_CONTROL *const rc = &cpi->rc;
John Koleszar's avatar
John Koleszar committed
561

562
563
564
565
566
567
568
569
  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
570

John Koleszar's avatar
John Koleszar committed
571
  cpi->oxcf = *oxcf;
John Koleszar's avatar
John Koleszar committed
572

573
  rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
John Koleszar's avatar
John Koleszar committed
574

575
576
  cpi->refresh_golden_frame = 0;
  cpi->refresh_last_frame = 1;
577
  cm->refresh_frame_context = 1;
578
  cm->reset_frame_context = 0;
John Koleszar's avatar
John Koleszar committed
579

580
  vp9_reset_segment_features(&cm->seg);
581
  vp9_set_high_precision_mv(cpi, 0);
John Koleszar's avatar
John Koleszar committed
582

John Koleszar's avatar
John Koleszar committed
583
584
  {
    int i;
John Koleszar's avatar
John Koleszar committed
585

Paul Wilkins's avatar
Paul Wilkins committed
586
    for (i = 0; i < MAX_SEGMENTS; i++)
John Koleszar's avatar
John Koleszar committed
587
588
      cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
  }
589
  cpi->encode_breakout = cpi->oxcf.encode_breakout;
John Koleszar's avatar
John Koleszar committed
590

Dmitry Kovalev's avatar
Dmitry Kovalev committed
591
  set_rc_buffer_sizes(rc, &cpi->oxcf);
John Koleszar's avatar
John Koleszar committed
592

593
594
  // Under a configuration change, where maximum_buffer_size may change,
  // keep buffer level clipped to the maximum allowed buffer size.
595
596
  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
597
598

  // Set up frame rate and related parameters rate control values.
599
  vp9_new_framerate(cpi, cpi->framerate);
John Koleszar's avatar
John Koleszar committed
600
601

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

605
  cm->interp_filter = cpi->sf.default_interp_filter;
John Koleszar's avatar
John Koleszar committed
606

607
608
  cm->display_width = cpi->oxcf.width;
  cm->display_height = cpi->oxcf.height;
John Koleszar's avatar
John Koleszar committed
609

610
611
  if (cpi->initial_width) {
    // Increasing the size of the frame beyond the first seen frame, or some
Adrian Grange's avatar
Adrian Grange committed
612
    // otherwise signaled maximum size, is not supported.
613
614
615
    // TODO(jkoleszar): exit gracefully.
    assert(cm->width <= cpi->initial_width);
    assert(cm->height <= cpi->initial_height);
John Koleszar's avatar
John Koleszar committed
616
  }
617
  update_frame_size(cpi);
John Koleszar's avatar
John Koleszar committed
618

619
  if ((cpi->svc.number_temporal_layers > 1 &&
620
      cpi->oxcf.rc_mode == VPX_CBR) ||
621
      (cpi->svc.number_spatial_layers > 1 && cpi->oxcf.pass == 2)) {
622
623
    vp9_update_layer_context_change_config(cpi,
                                           (int)cpi->oxcf.target_bandwidth);
624
625
  }

John Koleszar's avatar
John Koleszar committed
626
  cpi->alt_ref_source = NULL;
627
  rc->is_src_frame_alt_ref = 0;
Yaowu Xu's avatar
Yaowu Xu committed
628

John Koleszar's avatar
John Koleszar committed
629
#if 0
John Koleszar's avatar
John Koleszar committed
630
631
632
  // Experimental RD Code
  cpi->frame_distortion = 0;
  cpi->last_frame_distortion = 0;
John Koleszar's avatar
John Koleszar committed
633
634
#endif

Ronald S. Bultje's avatar
Ronald S. Bultje committed
635
  set_tile_limits(cpi);
Deb Mukherjee's avatar
Deb Mukherjee committed
636
637
638

  cpi->ext_refresh_frame_flags_pending = 0;
  cpi->ext_refresh_frame_context_pending = 0;
Tim Kopp's avatar
Tim Kopp committed
639

640
#if CONFIG_VP9_TEMPORAL_DENOISING
641
642
643
644
645
  if (cpi->oxcf.noise_sensitivity > 0) {
    vp9_denoiser_alloc(&(cpi->denoiser), cm->width, cm->height,
                       cm->subsampling_x, cm->subsampling_y,
                       VP9_ENC_BORDER_IN_PIXELS);
  }
Tim Kopp's avatar
Tim Kopp committed
646
#endif
John Koleszar's avatar
John Koleszar committed
647
648
}

649
#ifndef M_LOG2_E
John Koleszar's avatar
John Koleszar committed
650
#define M_LOG2_E 0.693147180559945309417
651
#endif
John Koleszar's avatar
John Koleszar committed
652
#define log2f(x) (log (x) / (float) M_LOG2_E)
653
654
655
656
657

static void cal_nmvjointsadcost(int *mvjointsadcost) {
  mvjointsadcost[0] = 600;
  mvjointsadcost[1] = 300;
  mvjointsadcost[2] = 300;
658
  mvjointsadcost[3] = 300;
659
660
661
662
663
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
664
665
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
666
667
668

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
669
670
671
672
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
673
674
675
676
677
678
  } while (++i <= MV_MAX);
}

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

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

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

691

692
VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
693
  unsigned int i, j;
694
695
  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
696

Dmitry Kovalev's avatar
Dmitry Kovalev committed
697
698
  if (!cm)
    return NULL;
John Koleszar's avatar
John Koleszar committed
699

Dmitry Kovalev's avatar
Dmitry Kovalev committed
700
  vp9_zero(*cpi);
John Koleszar's avatar
John Koleszar committed
701

John Koleszar's avatar
John Koleszar committed
702
  if (setjmp(cm->error.jmp)) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
703
704
    cm->error.setjmp = 0;
    vp9_remove_compressor(cpi);
John Koleszar's avatar
John Koleszar committed
705
706
707
    return 0;
  }

708
  cm->error.setjmp = 1;
John Koleszar's avatar
John Koleszar committed
709

Yaowu Xu's avatar
Yaowu Xu committed
710
  vp9_rtcd();
John Koleszar's avatar
John Koleszar committed
711

712
713
  cpi->use_svc = 0;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
714
  init_config(cpi, oxcf);
715
  vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
716

Dmitry Kovalev's avatar
Dmitry Kovalev committed
717
  cm->current_video_frame = 0;
718
719
  cpi->skippable_frame = 0;

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

724
725
726
727
  // Create a complexity map used for rd adjustment
  CHECK_MEM_ERROR(cm, cpi->complexity_map,
                  vpx_calloc(cm->mi_rows * cm->mi_cols, 1));

728
  // Create a map used for cyclic background refresh.
729
730
  CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
                  vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
731

John Koleszar's avatar
John Koleszar committed
732
733
  // And a place holder structure is the coding context
  // for use if we want to save and restore it
734
735
  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
736
737
738

  for (i = 0; i < (sizeof(cpi->mbgraph_stats) /
                   sizeof(cpi->mbgraph_stats[0])); i++) {
739
740
741
    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
742
  }
743

744
745
746
#if CONFIG_FP_MB_STATS
  cpi->use_fp_mb_stats = 0;
  if (cpi->use_fp_mb_stats) {
747
748
749
    // a place holder used to store the first pass mb stats in the first pass
    CHECK_MEM_ERROR(cm, cpi->twopass.frame_mb_stats_buf,
                    vpx_calloc(cm->MBs * sizeof(uint8_t), 1));
750
  } else {
751
    cpi->twopass.frame_mb_stats_buf = NULL;
752
753
754
  }
#endif

755
  cpi->refresh_alt_ref_frame = 0;
John Koleszar's avatar
John Koleszar committed
756

757
758
759
760
  // 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.
761
  cpi->multi_arf_last_grp_enabled = 0;
762
  if (oxcf->pass == 2) {
763
764
765
766
767
768
769
770
771
772
    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;
773
    cpi->multi_arf_enabled = 0;
774
  }
775

John Koleszar's avatar
John Koleszar committed
776
  cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
777
#if CONFIG_INTERNAL_STATS
John Koleszar's avatar
John Koleszar committed
778
779
780
781
782
783
784
785
786
787
  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;
788
789
790
    cpi->total_sq_error = 0;
    cpi->total_samples = 0;

John Koleszar's avatar
John Koleszar committed
791
792
793
794
    cpi->totalp_y = 0.0;
    cpi->totalp_u = 0.0;
    cpi->totalp_v = 0.0;
    cpi->totalp = 0.0;
795
796
797
    cpi->totalp_sq_error = 0;
    cpi->totalp_samples = 0;

John Koleszar's avatar
John Koleszar committed
798
799
800
    cpi->tot_recode_hits = 0;
    cpi->summed_quality = 0;
    cpi->summed_weights = 0;
801
802
    cpi->summedp_quality = 0;
    cpi->summedp_weights = 0;
John Koleszar's avatar
John Koleszar committed
803
804
805
806
807
808
809
810
  }

  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
811

812
813
#endif

814
  cpi->first_time_stamp_ever = INT64_MAX;
John Koleszar's avatar
John Koleszar committed
815

816
817
818
819
820
821
822
823
824
825
826
827
  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);
828

829
#if CONFIG_VP9_TEMPORAL_DENOISING
830
#ifdef OUTPUT_YUV_DENOISED
Tim Kopp's avatar
Tim Kopp committed
831
  yuv_denoised_file = fopen("denoised.yuv", "ab");
832
#endif
833
#endif
834
#ifdef OUTPUT_YUV_REC
John Koleszar's avatar
John Koleszar committed
835
  yuv_rec_file = fopen("rec.yuv", "wb");
836
#endif
John Koleszar's avatar
John Koleszar committed
837
838

#if 0
John Koleszar's avatar
John Koleszar committed
839
840
  framepsnr = fopen("framepsnr.stt", "a");
  kf_list = fopen("kf_list.stt", "w");
John Koleszar's avatar
John Koleszar committed
841
842
#endif

John Koleszar's avatar
John Koleszar committed
843
  cpi->output_pkt_list = oxcf->output_pkt_list;
John Koleszar's avatar
John Koleszar committed
844

845
  cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
846

847
  if (oxcf->pass == 1) {
848
    vp9_init_first_pass(cpi);
849
  } else if (oxcf->pass == 2) {
850