vp9_encoder.c 95.8 KB
Newer Older
John Koleszar's avatar
John Koleszar committed
1
/*
2
 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
John Koleszar's avatar
John Koleszar committed
3
 *
4
 *  Use of this source code is governed by a BSD-style license
5 6
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
7
 *  in the file PATENTS.  All contributing project authors may
8
 *  be found in the AUTHORS file in the root of the source tree.
John Koleszar's avatar
John Koleszar committed
9 10
 */

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
    vp9_zero(cpi->interp_filter_selected);
135
  } else {
136
    cm->fc = cm->frame_contexts[cm->frame_context_idx];
137
    vp9_zero(cpi->interp_filter_selected[0]);
138 139 140
  }
}

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

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

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

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

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

Jingning Han's avatar
Jingning Han committed
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
  vpx_free(cpi->nmvcosts[0]);
  vpx_free(cpi->nmvcosts[1]);
  cpi->nmvcosts[0] = NULL;
  cpi->nmvcosts[1] = NULL;

  vpx_free(cpi->nmvcosts_hp[0]);
  vpx_free(cpi->nmvcosts_hp[1]);
  cpi->nmvcosts_hp[0] = NULL;
  cpi->nmvcosts_hp[1] = NULL;

  vpx_free(cpi->nmvsadcosts[0]);
  vpx_free(cpi->nmvsadcosts[1]);
  cpi->nmvsadcosts[0] = NULL;
  cpi->nmvsadcosts[1] = NULL;

  vpx_free(cpi->nmvsadcosts_hp[0]);
  vpx_free(cpi->nmvsadcosts_hp[1]);
  cpi->nmvsadcosts_hp[0] = NULL;
  cpi->nmvsadcosts_hp[1] = NULL;

192 193 194
  vp9_cyclic_refresh_free(cpi->cyclic_refresh);
  cpi->cyclic_refresh = NULL;

Adrian Grange's avatar
Adrian Grange committed
195
  vp9_free_ref_frame_buffers(cm);
196
  vp9_free_context_buffers(cm);
John Koleszar's avatar
John Koleszar committed
197

198 199
  vp9_free_frame_buffer(&cpi->last_frame_uf);
  vp9_free_frame_buffer(&cpi->scaled_source);
200
  vp9_free_frame_buffer(&cpi->scaled_last_source);
201
  vp9_free_frame_buffer(&cpi->alt_ref_buffer);
202
  vp9_lookahead_destroy(cpi->lookahead);
John Koleszar's avatar
John Koleszar committed
203

John Koleszar's avatar
John Koleszar committed
204 205
  vpx_free(cpi->tok);
  cpi->tok = 0;
John Koleszar's avatar
John Koleszar committed
206

207
  vp9_free_pc_tree(cpi);
208

209 210 211 212 213 214
  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;
  }
215 216 217 218 219

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

221 222 223 224 225
  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
226 227
}

228 229 230 231 232 233 234 235 236
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);
Jingning Han's avatar
Jingning Han committed
237 238 239 240 241 242 243 244 245

  vpx_memcpy(cc->nmvcosts[0], cpi->nmvcosts[0],
             MV_VALS * sizeof(*cpi->nmvcosts[0]));
  vpx_memcpy(cc->nmvcosts[1], cpi->nmvcosts[1],
             MV_VALS * sizeof(*cpi->nmvcosts[1]));
  vpx_memcpy(cc->nmvcosts_hp[0], cpi->nmvcosts_hp[0],
             MV_VALS * sizeof(*cpi->nmvcosts_hp[0]));
  vpx_memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1],
             MV_VALS * sizeof(*cpi->nmvcosts_hp[1]));
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264

  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);
Jingning Han's avatar
Jingning Han committed
265 266 267 268 269 270 271 272 273

  vpx_memcpy(cpi->nmvcosts[0], cc->nmvcosts[0],
             MV_VALS * sizeof(*cc->nmvcosts[0]));
  vpx_memcpy(cpi->nmvcosts[1], cc->nmvcosts[1],
             MV_VALS * sizeof(*cc->nmvcosts[1]));
  vpx_memcpy(cpi->nmvcosts_hp[0], cc->nmvcosts_hp[0],
             MV_VALS * sizeof(*cc->nmvcosts_hp[0]));
  vpx_memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1],
             MV_VALS * sizeof(*cc->nmvcosts_hp[1]));
274 275 276 277 278 279 280 281 282 283 284 285 286

  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;
}

287
static void configure_static_seg_features(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
288
  VP9_COMMON *const cm = &cpi->common;
289
  const RATE_CONTROL *const rc = &cpi->rc;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
290
  struct segmentation *const seg = &cm->seg;
291

292
  int high_q = (int)(rc->avg_q > 48.0);
John Koleszar's avatar
John Koleszar committed
293
  int qi_delta;
294

John Koleszar's avatar
John Koleszar committed
295 296 297
  // Disable and clear down for KF
  if (cm->frame_type == KEY_FRAME) {
    // Clear down the global segmentation map
298
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
299 300
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
301
    cpi->static_mb_pct = 0;
302

John Koleszar's avatar
John Koleszar committed
303
    // Disable segmentation
304
    vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
305

John Koleszar's avatar
John Koleszar committed
306
    // Clear down the segment features.
307
    vp9_clearall_segfeatures(seg);
308 309
  } else if (cpi->refresh_alt_ref_frame) {
    // If this is an alt ref frame
John Koleszar's avatar
John Koleszar committed
310
    // Clear down the global segmentation map
311
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
312 313
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
314
    cpi->static_mb_pct = 0;
Paul Wilkins's avatar
Paul Wilkins committed
315

John Koleszar's avatar
John Koleszar committed
316
    // Disable segmentation and individual segment features by default
317
    vp9_disable_segmentation(seg);
318
    vp9_clearall_segfeatures(seg);
Paul Wilkins's avatar
Paul Wilkins committed
319

John Koleszar's avatar
John Koleszar committed
320 321
    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
322
    vp9_update_mbgraph_stats(cpi);
Paul Wilkins's avatar
Paul Wilkins committed
323

John Koleszar's avatar
John Koleszar committed
324 325
    // If segmentation was enabled set those features needed for the
    // arf itself.
326 327 328
    if (seg->enabled) {
      seg->update_map = 1;
      seg->update_data = 1;
Paul Wilkins's avatar
Paul Wilkins committed
329

330
      qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875);
331
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
332
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Paul Wilkins's avatar
Paul Wilkins committed
333

334 335
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
336

John Koleszar's avatar
John Koleszar committed
337
      // Where relevant assume segment data is delta data
338
      seg->abs_delta = SEGMENT_DELTADATA;
339
    }
340
  } else if (seg->enabled) {
341 342
    // All other frames if segmentation has been enabled

John Koleszar's avatar
John Koleszar committed
343
    // First normal frame in a valid gf or alt ref group
344
    if (rc->frames_since_golden == 0) {
Paul Wilkins's avatar
Paul Wilkins committed
345
      // Set up segment features for normal frames in an arf group
346
      if (rc->source_alt_ref_active) {
347 348 349
        seg->update_map = 0;
        seg->update_data = 1;
        seg->abs_delta = SEGMENT_DELTADATA;
Paul Wilkins's avatar
Paul Wilkins committed
350

351
        qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125);
352
        vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
353
        vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Paul Wilkins's avatar
Paul Wilkins committed
354

355 356
        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
357

John Koleszar's avatar
John Koleszar committed
358 359
        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
360 361 362
          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
363
        }
364 365 366 367
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

368
        vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
369

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

372 373
        seg->update_map = 0;
        seg->update_data = 0;
Paul Wilkins's avatar
Paul Wilkins committed
374

375
        vp9_clearall_segfeatures(seg);
John Koleszar's avatar
John Koleszar committed
376
      }
377
    } else if (rc->is_src_frame_alt_ref) {
378 379 380
      // 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
381

Paul Wilkins's avatar
Paul Wilkins committed
382
      // Enable ref frame features for segment 0 as well
383 384
      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
385

Paul Wilkins's avatar
Paul Wilkins committed
386
      // All mbs should use ALTREF_FRAME
387 388 389 390
      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
391

Paul Wilkins's avatar
Paul Wilkins committed
392
      // Skip all MBs if high Q (0,0 mv and skip coeffs)
John Koleszar's avatar
John Koleszar committed
393
      if (high_q) {
394 395
        vp9_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
396
      }
Adrian Grange's avatar
Adrian Grange committed
397
      // Enable data update
398
      seg->update_data = 1;
399 400 401
    } else {
      // All other frames.

John Koleszar's avatar
John Koleszar committed
402
      // No updates.. leave things as they are.
403 404
      seg->update_map = 0;
      seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
405 406
    }
  }
407 408
}

409
static void update_reference_segmentation_map(VP9_COMP *cpi) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
410
  VP9_COMMON *const cm = &cpi->common;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
411 412
  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
413 414
  int row, col;

415
  for (row = 0; row < cm->mi_rows; row++) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
416 417
    MODE_INFO **mi_8x8 = mi_8x8_ptr;
    uint8_t *cache = cache_ptr;
418 419
    for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
      cache[0] = mi_8x8[0]->mbmi.segment_id;
420
    mi_8x8_ptr += cm->mi_stride;
421
    cache_ptr += cm->mi_cols;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
422 423 424
  }
}

425

426
static void set_speed_features(VP9_COMP *cpi) {
427
#if CONFIG_INTERNAL_STATS
428
  int i;
429
  for (i = 0; i < MAX_MODES; ++i)
John Koleszar's avatar
John Koleszar committed
430
    cpi->mode_chosen_counts[i] = 0;
431
#endif
John Koleszar's avatar
John Koleszar committed
432

433
  vp9_set_speed_features(cpi);
434

435
  // Set rd thresholds based on mode and speed setting
436 437
  vp9_set_rd_speed_thresholds(cpi);
  vp9_set_rd_speed_thresholds_sub8x8(cpi);
John Koleszar's avatar
John Koleszar committed
438
}
439

440
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
441
  VP9_COMMON *cm = &cpi->common;
442
  const VP9EncoderConfig *oxcf = &cpi->oxcf;
443

Dmitry Kovalev's avatar
Dmitry Kovalev committed
444
  cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
445
                                      cm->subsampling_x, cm->subsampling_y,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
446
                                      oxcf->lag_in_frames);
John Koleszar's avatar
John Koleszar committed
447
  if (!cpi->lookahead)
448
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
449
                       "Failed to allocate lag buffers");
John Koleszar's avatar
John Koleszar committed
450

451
  if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
452
                               oxcf->width, oxcf->height,
453
                               cm->subsampling_x, cm->subsampling_y,
454
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
455
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
456
                       "Failed to allocate altref buffer");
John Koleszar's avatar
John Koleszar committed
457
}
458

459 460
static void alloc_ref_frame_buffers(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
Adrian Grange's avatar
Adrian Grange committed
461
  if (vp9_alloc_ref_frame_buffers(cm, cm->width, cm->height))
462
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
463
                       "Failed to allocate frame buffers");
John Koleszar's avatar
John Koleszar committed
464 465
}

466
static void alloc_util_frame_buffers(VP9_COMP *cpi) {
467
  VP9_COMMON *const cm = &cpi->common;
468 469 470
  if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
471
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
472
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
473
                       "Failed to allocate last frame buffer");
474

475 476 477
  if (vp9_realloc_frame_buffer(&cpi->scaled_source,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
478
                               VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
479
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
480
                       "Failed to allocate scaled source buffer");
481

482 483 484 485 486
  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,
487 488
                       "Failed to allocate scaled last source buffer");
}
489

490 491
void vp9_alloc_compressor_data(VP9_COMP *cpi) {
  VP9_COMMON *cm = &cpi->common;
492

493 494 495 496 497 498 499
  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)));
500
  }
501

502 503 504 505 506 507
  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
508 509 510

  vp9_set_mb_mi(cm, cm->width, cm->height);
  vp9_init_context_buffers(cm);
511
  init_macroblockd(cm, xd);
512

513
  if (is_spatial_svc(cpi)) {
514 515 516 517 518 519 520
    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");
  }
521 522
}

James Zern's avatar
James Zern committed
523
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
524
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
525
  vp9_rc_update_framerate(cpi);
John Koleszar's avatar
John Koleszar committed
526 527
}

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

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

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

539 540 541 542 543 544
static void init_buffer_indices(VP9_COMP *cpi) {
  cpi->lst_fb_idx = 0;
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
}

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

John Koleszar's avatar
John Koleszar committed
548
  cpi->oxcf = *oxcf;
549
  cpi->framerate = oxcf->init_framerate;
John Koleszar's avatar
John Koleszar committed
550

551 552
  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
553
  cm->color_space = UNKNOWN;
John Koleszar's avatar
John Koleszar committed
554

555 556
  cm->width = oxcf->width;
  cm->height = oxcf->height;
557
  vp9_alloc_compressor_data(cpi);
558

559 560 561 562 563
  // Spatial scalability.
  cpi->svc.number_spatial_layers = oxcf->ss_number_layers;
  // Temporal scalability.
  cpi->svc.number_temporal_layers = oxcf->ts_number_layers;

564 565
  if ((cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) ||
      (cpi->svc.number_spatial_layers > 1 && cpi->oxcf.pass == 2)) {
566
    vp9_init_layer_context(cpi);
567 568
  }

John Koleszar's avatar
John Koleszar committed
569
  // change includes all joint functionality
Dmitry Kovalev's avatar
Dmitry Kovalev committed
570
  vp9_change_config(cpi, oxcf);
John Koleszar's avatar
John Koleszar committed
571

John Koleszar's avatar
John Koleszar committed
572
  cpi->static_mb_pct = 0;
573
  cpi->ref_frame_flags = 0;
574

575
  init_buffer_indices(cpi);
576

Ronald S. Bultje's avatar
Ronald S. Bultje committed
577
  set_tile_limits(cpi);
John Koleszar's avatar
John Koleszar committed
578 579
}

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

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

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

John Koleszar's avatar
John Koleszar committed
607
  cpi->oxcf = *oxcf;
John Koleszar's avatar
John Koleszar committed
608

609
  rc->baseline_gf_interval = DEFAULT_GF_INTERVAL;
John Koleszar's avatar
John Koleszar committed
610

611 612
  cpi->refresh_golden_frame = 0;
  cpi->refresh_last_frame = 1;
613
  cm->refresh_frame_context = 1;
614
  cm->reset_frame_context = 0;
John Koleszar's avatar
John Koleszar committed
615

616
  vp9_reset_segment_features(&cm->seg);
617
  vp9_set_high_precision_mv(cpi, 0);
John Koleszar's avatar
John Koleszar committed
618

John Koleszar's avatar
John Koleszar committed
619 620
  {
    int i;
John Koleszar's avatar
John Koleszar committed
621

Paul Wilkins's avatar
Paul Wilkins committed
622
    for (i = 0; i < MAX_SEGMENTS; i++)
John Koleszar's avatar
John Koleszar committed
623 624
      cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
  }
625
  cpi->encode_breakout = cpi->oxcf.encode_breakout;
John Koleszar's avatar
John Koleszar committed
626

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

629 630
  // Under a configuration change, where maximum_buffer_size may change,
  // keep buffer level clipped to the maximum allowed buffer size.
631 632
  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
633 634

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

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

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

643 644
  cm->display_width = cpi->oxcf.width;
  cm->display_height = cpi->oxcf.height;
John Koleszar's avatar
John Koleszar committed
645

646 647
  if (cpi->initial_width) {
    // Increasing the size of the frame beyond the first seen frame, or some
Adrian Grange's avatar
Adrian Grange committed
648
    // otherwise signaled maximum size, is not supported.
649 650 651
    // TODO(jkoleszar): exit gracefully.
    assert(cm->width <= cpi->initial_width);
    assert(cm->height <= cpi->initial_height);
John Koleszar's avatar
John Koleszar committed
652
  }
653
  update_frame_size(cpi);
John Koleszar's avatar
John Koleszar committed
654

655
  if ((cpi->svc.number_temporal_layers > 1 &&
656
      cpi->oxcf.rc_mode == VPX_CBR) ||
657
      (cpi->svc.number_spatial_layers > 1 && cpi->oxcf.pass == 2)) {
658 659
    vp9_update_layer_context_change_config(cpi,
                                           (int)cpi->oxcf.target_bandwidth);
660 661
  }

John Koleszar's avatar
John Koleszar committed
662
  cpi->alt_ref_source = NULL;
663
  rc->is_src_frame_alt_ref = 0;
Yaowu Xu's avatar
Yaowu Xu committed
664

John Koleszar's avatar
John Koleszar committed
665
#if 0
John Koleszar's avatar
John Koleszar committed
666 667 668
  // Experimental RD Code
  cpi->frame_distortion = 0;
  cpi->last_frame_distortion = 0;
John Koleszar's avatar
John Koleszar committed
669 670
#endif

Ronald S. Bultje's avatar
Ronald S. Bultje committed
671
  set_tile_limits(cpi);
Deb Mukherjee's avatar
Deb Mukherjee committed
672 673 674

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

676
#if CONFIG_VP9_TEMPORAL_DENOISING
677 678 679 680 681
  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
682
#endif
John Koleszar's avatar
John Koleszar committed
683 684
}

685
#ifndef M_LOG2_E
John Koleszar's avatar
John Koleszar committed
686
#define M_LOG2_E 0.693147180559945309417
687
#endif
John Koleszar's avatar
John Koleszar committed
688
#define log2f(x) (log (x) / (float) M_LOG2_E)
689 690 691 692 693

static void cal_nmvjointsadcost(int *mvjointsadcost) {
  mvjointsadcost[0] = 600;
  mvjointsadcost[1] = 300;
  mvjointsadcost[2] = 300;
694
  mvjointsadcost[3] = 300;
695 696 697 698 699
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
700 701
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
702 703 704

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
705 706 707 708
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
709 710 711 712 713 714
  } while (++i <= MV_MAX);
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
715 716
  mvsadcost[0][0] = 0;
  mvsadcost[1][0] = 0;
717 718 719

  do {
    double z = 256 * (2 * (log2f(8 * i) + .6));
Dmitry Kovalev's avatar
Dmitry Kovalev committed
720 721 722 723
    mvsadcost[0][i] = (int)z;
    mvsadcost[1][i] = (int)z;
    mvsadcost[0][-i] = (int)z;
    mvsadcost[1][-i] = (int)z;
724 725 726
  } while (++i <= MV_MAX);
}

727

728
VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf) {
729
  unsigned int i, j;
730 731
  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
732

Dmitry Kovalev's avatar
Dmitry Kovalev committed
733 734
  if (!cm)
    return NULL;
John Koleszar's avatar
John Koleszar committed
735

Dmitry Kovalev's avatar
Dmitry Kovalev committed
736
  vp9_zero(*cpi);
John Koleszar's avatar
John Koleszar committed
737

John Koleszar's avatar
John Koleszar committed
738
  if (setjmp(cm->error.jmp)) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
739 740
    cm->error.setjmp = 0;
    vp9_remove_compressor(cpi);
John Koleszar's avatar
John Koleszar committed
741 742 743
    return 0;
  }

744
  cm->error.setjmp = 1;
John Koleszar's avatar
John Koleszar committed
745

Yaowu Xu's avatar
Yaowu Xu committed
746
  vp9_rtcd();
John Koleszar's avatar
John Koleszar committed
747

748 749
  cpi->use_svc = 0;

Dmitry Kovalev's avatar
Dmitry Kovalev committed
750
  init_config(cpi, oxcf);
751
  vp9_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
752

Dmitry Kovalev's avatar
Dmitry Kovalev committed
753
  cm->current_video_frame = 0;
754 755
  cpi->skippable_frame = 0;

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

760 761 762 763
  // Create a complexity map used for rd adjustment
  CHECK_MEM_ERROR(cm, cpi->complexity_map,
                  vpx_calloc(cm->mi_rows * cm->mi_cols, 1));

764
  // Create a map used for cyclic background refresh.
765 766
  CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
                  vp9_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
767

John Koleszar's avatar
John Koleszar committed
768 769
  // And a place holder structure is the coding context
  // for use if we want to save and restore it