vp9_encoder.c 90.9 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_SRC
FILE *yuv_file;
#endif
70 71 72
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
#endif
John Koleszar's avatar
John Koleszar committed
73 74 75

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

80
static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) {
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  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
106
static void set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) {
107
  MACROBLOCK *const mb = &cpi->mb;
Deb Mukherjee's avatar
Deb Mukherjee committed
108
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
109
  if (cpi->common.allow_high_precision_mv) {
110 111 112 113 114 115 116
    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
117

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
static void setup_key_frame(VP9_COMP *cpi) {
  vp9_setup_past_independence(&cpi->common);

  // All buffers are implicitly updated on key frames.
  cpi->refresh_golden_frame = 1;
  cpi->refresh_alt_ref_frame = 1;
}

static void setup_inter_frame(VP9_COMMON *cm) {
  if (cm->error_resilient_mode || cm->intra_only)
    vp9_setup_past_independence(cm);

  assert(cm->frame_context_idx < FRAME_CONTEXTS);
  cm->fc = cm->frame_contexts[cm->frame_context_idx];
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
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.
  if (cm->frame_type == KEY_FRAME) {
    setup_key_frame(cpi);
  } else {
    if (!cm->intra_only && !cm->error_resilient_mode && !cpi->use_svc)
        cm->frame_context_idx = cpi->refresh_alt_ref_frame;
     setup_inter_frame(cm);
  }
}



152
void vp9_initialize_enc() {
John Koleszar's avatar
John Koleszar committed
153 154 155
  static int init_done = 0;

  if (!init_done) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
156 157 158
    vp9_init_neighbors();
    vp9_init_quant_tables();

159
    vp9_coef_tree_initialize();
160 161
    vp9_tokenize_initialize();
    vp9_init_me_luts();
162
    vp9_rc_init_minq_luts();
163
    vp9_entropy_mv_init();
164
    vp9_entropy_mode_init();
165
    vp9_temporal_filter_init();
John Koleszar's avatar
John Koleszar committed
166 167
    init_done = 1;
  }
John Koleszar's avatar
John Koleszar committed
168 169
}

170
static void dealloc_compressor_data(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
171
  VP9_COMMON *const cm = &cpi->common;
172
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
173

John Koleszar's avatar
John Koleszar committed
174 175
  // Delete sementation map
  vpx_free(cpi->segmentation_map);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
176 177 178
  cpi->segmentation_map = NULL;
  vpx_free(cm->last_frame_seg_map);
  cm->last_frame_seg_map = NULL;
John Koleszar's avatar
John Koleszar committed
179
  vpx_free(cpi->coding_context.last_frame_seg_map_copy);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
180
  cpi->coding_context.last_frame_seg_map_copy = NULL;
John Koleszar's avatar
John Koleszar committed
181

182
  vpx_free(cpi->complexity_map);
183 184 185 186 187
  cpi->complexity_map = NULL;

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

John Koleszar's avatar
John Koleszar committed
188
  vpx_free(cpi->active_map);
189
  cpi->active_map = NULL;
John Koleszar's avatar
John Koleszar committed
190

Dmitry Kovalev's avatar
Dmitry Kovalev committed
191
  vp9_free_frame_buffers(cm);
John Koleszar's avatar
John Koleszar committed
192

193 194
  vp9_free_frame_buffer(&cpi->last_frame_uf);
  vp9_free_frame_buffer(&cpi->scaled_source);
195
  vp9_free_frame_buffer(&cpi->scaled_last_source);
196
  vp9_free_frame_buffer(&cpi->alt_ref_buffer);
197
  vp9_lookahead_destroy(cpi->lookahead);
John Koleszar's avatar
John Koleszar committed
198

John Koleszar's avatar
John Koleszar committed
199 200
  vpx_free(cpi->tok);
  cpi->tok = 0;
John Koleszar's avatar
John Koleszar committed
201

202 203
  vp9_free_pc_tree(&cpi->mb);

204 205 206 207 208 209
  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
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 251 252 253 254 255 256
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;
}

257
static void configure_static_seg_features(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
258
  VP9_COMMON *const cm = &cpi->common;
259
  const RATE_CONTROL *const rc = &cpi->rc;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
260
  struct segmentation *const seg = &cm->seg;
261

262
  int high_q = (int)(rc->avg_q > 48.0);
John Koleszar's avatar
John Koleszar committed
263
  int qi_delta;
264

John Koleszar's avatar
John Koleszar committed
265 266 267
  // Disable and clear down for KF
  if (cm->frame_type == KEY_FRAME) {
    // 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;
272

John Koleszar's avatar
John Koleszar committed
273
    // Disable segmentation
274
    vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
275

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

John Koleszar's avatar
John Koleszar committed
286
    // Disable segmentation and individual segment features by default
287
    vp9_disable_segmentation(seg);
288
    vp9_clearall_segfeatures(seg);
Paul Wilkins's avatar
Paul Wilkins committed
289

John Koleszar's avatar
John Koleszar committed
290 291
    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
292
    vp9_update_mbgraph_stats(cpi);
Paul Wilkins's avatar
Paul Wilkins committed
293

John Koleszar's avatar
John Koleszar committed
294 295
    // If segmentation was enabled set those features needed for the
    // arf itself.
296 297 298
    if (seg->enabled) {
      seg->update_map = 1;
      seg->update_data = 1;
Paul Wilkins's avatar
Paul Wilkins committed
299

300
      qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875);
301
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
302
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Paul Wilkins's avatar
Paul Wilkins committed
303

304 305
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
306

John Koleszar's avatar
John Koleszar committed
307
      // Where relevant assume segment data is delta data
308
      seg->abs_delta = SEGMENT_DELTADATA;
309
    }
310
  } else if (seg->enabled) {
311 312
    // All other frames if segmentation has been enabled

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

321
        qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125);
322
        vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
323
        vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Paul Wilkins's avatar
Paul Wilkins committed
324

325 326
        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
327

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

338
        vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
339

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

342 343
        seg->update_map = 0;
        seg->update_data = 0;
Paul Wilkins's avatar
Paul Wilkins committed
344

345
        vp9_clearall_segfeatures(seg);
John Koleszar's avatar
John Koleszar committed
346
      }
347
    } else if (rc->is_src_frame_alt_ref) {
348 349 350
      // 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
351

Paul Wilkins's avatar
Paul Wilkins committed
352
      // Enable ref frame features for segment 0 as well
353 354
      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
355

Paul Wilkins's avatar
Paul Wilkins committed
356
      // All mbs should use ALTREF_FRAME
357 358 359 360
      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
361

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

John Koleszar's avatar
John Koleszar committed
372
      // No updates.. leave things as they are.
373 374
      seg->update_map = 0;
      seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
375 376
    }
  }
377 378
}

379
static void update_reference_segmentation_map(VP9_COMP *cpi) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
380
  VP9_COMMON *const cm = &cpi->common;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
381 382
  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
383 384
  int row, col;

385
  for (row = 0; row < cm->mi_rows; row++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
386 387
    MODE_INFO **mi_8x8 = mi_8x8_ptr;
    uint8_t *cache = cache_ptr;
388 389
    for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
      cache[0] = mi_8x8[0]->mbmi.segment_id;
390
    mi_8x8_ptr += cm->mi_stride;
391
    cache_ptr += cm->mi_cols;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
392 393 394
  }
}

395

396
static void set_speed_features(VP9_COMP *cpi) {
397
#if CONFIG_INTERNAL_STATS
398
  int i;
399
  for (i = 0; i < MAX_MODES; ++i)
John Koleszar's avatar
John Koleszar committed
400
    cpi->mode_chosen_counts[i] = 0;
401
#endif
John Koleszar's avatar
John Koleszar committed
402

403
  vp9_set_speed_features(cpi);
404

405
  // Set rd thresholds based on mode and speed setting
406 407
  vp9_set_rd_speed_thresholds(cpi);
  vp9_set_rd_speed_thresholds_sub8x8(cpi);
John Koleszar's avatar
John Koleszar committed
408

409
  cpi->mb.fwd_txm4x4 = vp9_fdct4x4;
Yaowu Xu's avatar
Yaowu Xu committed
410
  if (cpi->oxcf.lossless || cpi->mb.e_mbd.lossless) {
411
    cpi->mb.fwd_txm4x4 = vp9_fwht4x4;
John Koleszar's avatar
John Koleszar committed
412
  }
John Koleszar's avatar
John Koleszar committed
413
}
414

415
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
416
  VP9_COMMON *cm = &cpi->common;
417
  const VP9EncoderConfig *oxcf = &cpi->oxcf;
418

Dmitry Kovalev's avatar
Dmitry Kovalev committed
419
  cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
420
                                      cm->subsampling_x, cm->subsampling_y,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
421
                                      oxcf->lag_in_frames);
John Koleszar's avatar
John Koleszar committed
422
  if (!cpi->lookahead)
423
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
424
                       "Failed to allocate lag buffers");
John Koleszar's avatar
John Koleszar committed
425

426
  if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
427
                               oxcf->width, oxcf->height,
428
                               cm->subsampling_x, cm->subsampling_y,
429
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
430
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
431
                       "Failed to allocate altref buffer");
John Koleszar's avatar
John Koleszar committed
432
}
433

434 435
void vp9_alloc_compressor_data(VP9_COMP *cpi) {
  VP9_COMMON *cm = &cpi->common;
John Koleszar's avatar
John Koleszar committed
436

437
  if (vp9_alloc_frame_buffers(cm, cm->width, cm->height))
438
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
439
                       "Failed to allocate frame buffers");
John Koleszar's avatar
John Koleszar committed
440

441 442 443
  if (vp9_alloc_frame_buffer(&cpi->last_frame_uf,
                             cm->width, cm->height,
                             cm->subsampling_x, cm->subsampling_y,
444
                             VP9_ENC_BORDER_IN_PIXELS))
445
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
446
                       "Failed to allocate last frame buffer");
John Koleszar's avatar
John Koleszar committed
447

448 449 450
  if (vp9_alloc_frame_buffer(&cpi->scaled_source,
                             cm->width, cm->height,
                             cm->subsampling_x, cm->subsampling_y,
451
                             VP9_ENC_BORDER_IN_PIXELS))
452
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
453
                       "Failed to allocate scaled source buffer");
John Koleszar's avatar
John Koleszar committed
454

455 456 457 458 459 460 461
  if (vp9_alloc_frame_buffer(&cpi->scaled_last_source,
                             cm->width, cm->height,
                             cm->subsampling_x, cm->subsampling_y,
                             VP9_ENC_BORDER_IN_PIXELS))
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                       "Failed to allocate scaled last source buffer");

John Koleszar's avatar
John Koleszar committed
462
  vpx_free(cpi->tok);
John Koleszar's avatar
John Koleszar committed
463

John Koleszar's avatar
John Koleszar committed
464
  {
465
    unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
John Koleszar's avatar
John Koleszar committed
466

467
    CHECK_MEM_ERROR(cm, cpi->tok, vpx_calloc(tokens, sizeof(*cpi->tok)));
John Koleszar's avatar
John Koleszar committed
468
  }
469 470

  vp9_setup_pc_tree(&cpi->common, &cpi->mb);
John Koleszar's avatar
John Koleszar committed
471 472
}

473
static void update_frame_size(VP9_COMP *cpi) {
474 475
  VP9_COMMON *const cm = &cpi->common;
  MACROBLOCKD *const xd = &cpi->mb.e_mbd;
476

477
  vp9_update_frame_size(cm);
478

479
  // Update size of buffers local to this frame
480 481 482
  if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
483
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
484
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
485 486
                       "Failed to reallocate last frame buffer");

487 488 489
  if (vp9_realloc_frame_buffer(&cpi->scaled_source,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
490
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
491
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
492
                       "Failed to reallocate scaled source buffer");
493

494 495 496 497 498 499 500
  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,
                       "Failed to reallocate scaled last source buffer");

501 502 503 504
  {
    int y_stride = cpi->scaled_source.y_stride;

    if (cpi->sf.search_method == NSTEP) {
505
      vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
506
    } else if (cpi->sf.search_method == DIAMOND) {
507
      vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
508 509
    }
  }
510

511
  init_macroblockd(cm, xd);
512 513
}

James Zern's avatar
James Zern committed
514
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
515 516
  cpi->oxcf.framerate = framerate < 0.1 ? 30 : framerate;
  vp9_rc_update_framerate(cpi);
John Koleszar's avatar
John Koleszar committed
517 518
}

519
int64_t vp9_rescale(int64_t val, int64_t num, int denom) {
John Koleszar's avatar
John Koleszar committed
520 521 522
  int64_t llnum = num;
  int64_t llden = denom;
  int64_t llval = val;
523

Jingning Han's avatar
Jingning Han committed
524
  return (llval * llnum / llden);
525 526
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
530 531
  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);
532

Dmitry Kovalev's avatar
Dmitry Kovalev committed
533 534 535
  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;
536
}
537

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

John Koleszar's avatar
John Koleszar committed
541
  cpi->oxcf = *oxcf;
John Koleszar's avatar
John Koleszar committed
542

543 544
  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
John Koleszar's avatar
John Koleszar committed
545

546 547
  cm->width = oxcf->width;
  cm->height = oxcf->height;
548 549 550
  cm->subsampling_x = 0;
  cm->subsampling_y = 0;
  vp9_alloc_compressor_data(cpi);
551

552 553 554 555 556
  // Spatial scalability.
  cpi->svc.number_spatial_layers = oxcf->ss_number_layers;
  // Temporal scalability.
  cpi->svc.number_temporal_layers = oxcf->ts_number_layers;

557
  if ((cpi->svc.number_temporal_layers > 1 &&
558
      cpi->oxcf.rc_mode == RC_MODE_CBR) ||
559
      (cpi->svc.number_spatial_layers > 1 &&
Dmitry Kovalev's avatar
Dmitry Kovalev committed
560
      cpi->oxcf.mode == TWO_PASS_SECOND_BEST)) {
561
    vp9_init_layer_context(cpi);
562 563
  }

John Koleszar's avatar
John Koleszar committed
564
  // change includes all joint functionality
Dmitry Kovalev's avatar
Dmitry Kovalev committed
565
  vp9_change_config(cpi, oxcf);
John Koleszar's avatar
John Koleszar committed
566

John Koleszar's avatar
John Koleszar committed
567
  cpi->static_mb_pct = 0;
568

569 570 571 572
  cpi->lst_fb_idx = 0;
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;

Ronald S. Bultje's avatar
Ronald S. Bultje committed
573
  set_tile_limits(cpi);
John Koleszar's avatar
John Koleszar committed
574 575
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
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;
}

593
void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
594
  VP9_COMMON *const cm = &cpi->common;
595
  RATE_CONTROL *const rc = &cpi->rc;
John Koleszar's avatar
John Koleszar committed
596

597 598 599 600 601 602 603 604
  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
605

John Koleszar's avatar
John Koleszar committed
606
  cpi->oxcf = *oxcf;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
607 608 609
  cpi->pass = get_pass(cpi->oxcf.mode);
  if (cpi->oxcf.mode == REALTIME)
    cpi->oxcf.play_alternate = 0;
John Koleszar's avatar
John Koleszar committed
610

John Koleszar's avatar
John Koleszar committed
611
  cpi->oxcf.lossless = oxcf->lossless;
612 613 614 615 616 617 618 619 620
  if (cpi->oxcf.lossless) {
    // In lossless mode, make sure right quantizer range and correct transform
    // is set.
    cpi->oxcf.worst_allowed_q = 0;
    cpi->oxcf.best_allowed_q = 0;
    cpi->mb.e_mbd.itxm_add = vp9_iwht4x4_add;
  } else {
    cpi->mb.e_mbd.itxm_add = vp9_idct4x4_add;
  }
621
  rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
622
  cpi->ref_frame_flags = VP9_ALT_FLAG | VP9_GOLD_FLAG | VP9_LAST_FLAG;
John Koleszar's avatar
John Koleszar committed
623

624 625
  cpi->refresh_golden_frame = 0;
  cpi->refresh_last_frame = 1;
626
  cm->refresh_frame_context = 1;
627
  cm->reset_frame_context = 0;
John Koleszar's avatar
John Koleszar committed
628

629
  vp9_reset_segment_features(&cm->seg);
Deb Mukherjee's avatar
Deb Mukherjee committed
630
  set_high_precision_mv(cpi, 0);
John Koleszar's avatar
John Koleszar committed
631

John Koleszar's avatar
John Koleszar committed
632 633
  {
    int i;
John Koleszar's avatar
John Koleszar committed
634

Paul Wilkins's avatar
Paul Wilkins committed
635
    for (i = 0; i < MAX_SEGMENTS; i++)
John Koleszar's avatar
John Koleszar committed
636 637
      cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
  }
638
  cpi->encode_breakout = cpi->oxcf.encode_breakout;
John Koleszar's avatar
John Koleszar committed
639 640

  // local file playback mode == really big buffer
641
  if (cpi->oxcf.rc_mode == RC_MODE_VBR) {
John Koleszar's avatar
John Koleszar committed
642 643 644 645 646 647 648 649
    cpi->oxcf.starting_buffer_level   = 60000;
    cpi->oxcf.optimal_buffer_level    = 60000;
    cpi->oxcf.maximum_buffer_size     = 240000;
  }

  // Convert target bandwidth from Kbit/s to Bit/s
  cpi->oxcf.target_bandwidth       *= 1000;

650 651 652
  cpi->oxcf.starting_buffer_level =
      vp9_rescale(cpi->oxcf.starting_buffer_level,
                  cpi->oxcf.target_bandwidth, 1000);
John Koleszar's avatar
John Koleszar committed
653 654 655 656 657

  // Set or reset optimal and maximum buffer levels.
  if (cpi->oxcf.optimal_buffer_level == 0)
    cpi->oxcf.optimal_buffer_level = cpi->oxcf.target_bandwidth / 8;
  else
658 659 660
    cpi->oxcf.optimal_buffer_level =
        vp9_rescale(cpi->oxcf.optimal_buffer_level,
                    cpi->oxcf.target_bandwidth, 1000);
John Koleszar's avatar
John Koleszar committed
661 662 663 664

  if (cpi->oxcf.maximum_buffer_size == 0)
    cpi->oxcf.maximum_buffer_size = cpi->oxcf.target_bandwidth / 8;
  else
665 666 667
    cpi->oxcf.maximum_buffer_size =
        vp9_rescale(cpi->oxcf.maximum_buffer_size,
                    cpi->oxcf.target_bandwidth, 1000);
668 669
  // Under a configuration change, where maximum_buffer_size may change,
  // keep buffer level clipped to the maximum allowed buffer size.
670 671
  rc->bits_off_target = MIN(rc->bits_off_target, cpi->oxcf.maximum_buffer_size);
  rc->buffer_level = MIN(rc->buffer_level, cpi->oxcf.maximum_buffer_size);
John Koleszar's avatar
John Koleszar committed
672 673

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

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

680
  cm->interp_filter = DEFAULT_INTERP_FILTER;
John Koleszar's avatar
John Koleszar committed
681

682 683
  cm->display_width = cpi->oxcf.width;
  cm->display_height = cpi->oxcf.height;
John Koleszar's avatar
John Koleszar committed
684

685 686
  if (cpi->initial_width) {
    // Increasing the size of the frame beyond the first seen frame, or some
Adrian Grange's avatar
Adrian Grange committed
687
    // otherwise signaled maximum size, is not supported.
688 689 690
    // TODO(jkoleszar): exit gracefully.
    assert(cm->width <= cpi->initial_width);
    assert(cm->height <= cpi->initial_height);
John Koleszar's avatar
John Koleszar committed
691
  }
692
  update_frame_size(cpi);
John Koleszar's avatar
John Koleszar committed
693

694
  if ((cpi->svc.number_temporal_layers > 1 &&
695
      cpi->oxcf.rc_mode == RC_MODE_CBR) ||
696
      (cpi->svc.number_spatial_layers > 1 && cpi->pass == 2)) {
697 698
    vp9_update_layer_context_change_config(cpi,
                                           (int)cpi->oxcf.target_bandwidth);
699 700
  }

701 702 703
#if CONFIG_MULTIPLE_ARF
  vp9_zero(cpi->alt_ref_source);
#else
John Koleszar's avatar
John Koleszar committed
704
  cpi->alt_ref_source = NULL;
705
#endif
706
  rc->is_src_frame_alt_ref = 0;
Yaowu Xu's avatar
Yaowu Xu committed
707

John Koleszar's avatar
John Koleszar committed
708
#if 0
John Koleszar's avatar
John Koleszar committed
709 710 711
  // Experimental RD Code
  cpi->frame_distortion = 0;
  cpi->last_frame_distortion = 0;
John Koleszar's avatar
John Koleszar committed
712 713
#endif

Ronald S. Bultje's avatar
Ronald S. Bultje committed
714
  set_tile_limits(cpi);
Deb Mukherjee's avatar
Deb Mukherjee committed
715 716 717

  cpi->ext_refresh_frame_flags_pending = 0;
  cpi->ext_refresh_frame_context_pending = 0;
John Koleszar's avatar
John Koleszar committed
718 719
}

720
#ifndef M_LOG2_E
John Koleszar's avatar
John Koleszar committed
721
#define M_LOG2_E 0.693147180559945309417
722
#endif
John Koleszar's avatar
John Koleszar committed
723
#define log2f(x) (log (x) / (float) M_LOG2_E)
724 725 726 727 728

static void cal_nmvjointsadcost(int *mvjointsadcost) {
  mvjointsadcost[0] = 600;
  mvjointsadcost[1] = 300;
  mvjointsadcost[2] = 300;
729
  mvjointsadcost[3] = 300;
730 731 732 733 734
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
735 736
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
737 738 739

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
740 741 742 743
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
744 745 746 747 748 749
  } while (++i <= MV_MAX);
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
750 751
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
752 753 754

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
755 756 757 758
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
759 760 761
  } while (++i <= MV_MAX);
}

762

763
VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
764
  int i, j;
765 766
  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
767

Dmitry Kovalev's avatar
Dmitry Kovalev committed
768 769
  if (!cm)
    return NULL;
John Koleszar's avatar
John Koleszar committed
770

Dmitry Kovalev's avatar
Dmitry Kovalev committed
771
  vp9_zero(*cpi);
John Koleszar's avatar
John Koleszar committed
772

John Koleszar's avatar
John Koleszar committed
773
  if (setjmp(cm->error.jmp)) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
774 775
    cm->error.setjmp = 0;
    vp9_remove_compressor(cpi);
John Koleszar's avatar
John Koleszar committed
776 777 778
    return 0;
  }

779
  cm->error.setjmp = 1;
John Koleszar's avatar
John Koleszar committed
780

Yaowu Xu's avatar
Yaowu Xu committed
781
  vp9_rtcd();
John Koleszar's avatar
John Koleszar committed
782

783 784
  cpi->use_svc = 0;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
785
  init_config(cpi, oxcf);
786
  vp9_rc_init(&cpi->oxcf, cpi->pass, &cpi->rc);