vp9_encoder.c 149 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
#include <math.h>
#include <stdio.h>
#include <limits.h>

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

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

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

56 57
#define AM_SEGMENT_ID_INACTIVE 7
#define AM_SEGMENT_ID_ACTIVE 0
58

59 60
#define SHARP_FILTER_QTHRESH 0          /* Q threshold for 8-tap sharp filter */

Jim Bankoski's avatar
Jim Bankoski committed
61 62 63 64 65 66
#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.
John Koleszar's avatar
John Koleszar committed
67
// #define OUTPUT_YUV_REC
John Koleszar's avatar
John Koleszar committed
68

69
#ifdef OUTPUT_YUV_DENOISED
70
FILE *yuv_denoised_file = NULL;
71
#endif
Marco's avatar
Marco committed
72 73 74
#ifdef OUTPUT_YUV_SKINMAP
FILE *yuv_skinmap_file = NULL;
#endif
75 76 77
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
#endif
John Koleszar's avatar
John Koleszar committed
78 79 80

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

85
static INLINE void Scale2Ratio(VPX_SCALING mode, int *hr, int *hs) {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
  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;
  }
}

111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
// Mark all inactive blocks as active. Other segmentation features may be set
// so memset cannot be used, instead only inactive blocks should be reset.
void vp9_suppress_active_map(VP9_COMP *cpi) {
  unsigned char *const seg_map = cpi->segmentation_map;
  int i;
  if (cpi->active_map.enabled || cpi->active_map.update)
    for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
      if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
        seg_map[i] = AM_SEGMENT_ID_ACTIVE;
}

void vp9_apply_active_map(VP9_COMP *cpi) {
  struct segmentation *const seg = &cpi->common.seg;
  unsigned char *const seg_map = cpi->segmentation_map;
  const unsigned char *const active_map = cpi->active_map.map;
  int i;

  assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);

130 131 132 133 134
  if (frame_is_intra_only(&cpi->common)) {
    cpi->active_map.enabled = 0;
    cpi->active_map.update = 1;
  }

135 136 137 138 139 140
  if (cpi->active_map.update) {
    if (cpi->active_map.enabled) {
      for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
        if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
      vp9_enable_segmentation(seg);
      vp9_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
141 142 143 144 145
      vp9_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
      // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
      // filter level being zero regardless of the value of seg->abs_delta.
      vp9_set_segdata(seg, AM_SEGMENT_ID_INACTIVE,
                      SEG_LVL_ALT_LF, -MAX_LOOP_FILTER);
146 147
    } else {
      vp9_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
148
      vp9_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
      if (seg->enabled) {
        seg->update_data = 1;
        seg->update_map = 1;
      }
    }
    cpi->active_map.update = 0;
  }
}

int vp9_set_active_map(VP9_COMP* cpi,
                       unsigned char* new_map_16x16,
                       int rows,
                       int cols) {
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
    unsigned char *const active_map_8x8 = cpi->active_map.map;
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
    cpi->active_map.update = 1;
    if (new_map_16x16) {
      int r, c;
      for (r = 0; r < mi_rows; ++r) {
        for (c = 0; c < mi_cols; ++c) {
          active_map_8x8[r * mi_cols + c] =
              new_map_16x16[(r >> 1) * cols + (c >> 1)]
                  ? AM_SEGMENT_ID_ACTIVE
                  : AM_SEGMENT_ID_INACTIVE;
        }
      }
      cpi->active_map.enabled = 1;
    } else {
      cpi->active_map.enabled = 0;
    }
    return 0;
  } else {
    return -1;
  }
}

187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
int vp9_get_active_map(VP9_COMP* cpi,
                       unsigned char* new_map_16x16,
                       int rows,
                       int cols) {
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
      new_map_16x16) {
    unsigned char* const seg_map_8x8 = cpi->segmentation_map;
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
    vpx_memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
    if (cpi->active_map.enabled) {
      int r, c;
      for (r = 0; r < mi_rows; ++r) {
        for (c = 0; c < mi_cols; ++c) {
          // Cyclic refresh segments are considered active despite not having
          // AM_SEGMENT_ID_ACTIVE
          new_map_16x16[(r >> 1) * cols + (c >> 1)] |=
              seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
        }
      }
    }
    return 0;
  } else {
    return -1;
  }
}

214
void vp9_set_high_precision_mv(VP9_COMP *cpi, int allow_high_precision_mv) {
215
  MACROBLOCK *const mb = &cpi->td.mb;
Deb Mukherjee's avatar
Deb Mukherjee committed
216
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
217
  if (cpi->common.allow_high_precision_mv) {
218 219 220 221 222 223 224
    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
225

226 227 228 229 230 231 232
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.
233 234 235 236 237 238 239
  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;
  }

240
  if (cm->frame_type == KEY_FRAME) {
241
    if (!is_two_pass_svc(cpi))
242
      cpi->refresh_golden_frame = 1;
243
    cpi->refresh_alt_ref_frame = 1;
244
    vp9_zero(cpi->interp_filter_selected);
245
  } else {
246
    *cm->fc = cm->frame_contexts[cm->frame_context_idx];
247
    vp9_zero(cpi->interp_filter_selected[0]);
248 249 250
  }
}

251 252 253 254 255 256 257 258 259 260
static void vp9_enc_setup_mi(VP9_COMMON *cm) {
  int i;
  cm->mi = cm->mip + cm->mi_stride + 1;
  vpx_memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
  cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
  // Clear top border row
  vpx_memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
  // Clear left border column
  for (i = 1; i < cm->mi_rows + 1; ++i)
    vpx_memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
261 262 263 264 265 266

  cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
  cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;

  vpx_memset(cm->mi_grid_base, 0,
             cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
267 268 269 270 271 272 273 274 275 276
}

static int vp9_enc_alloc_mi(VP9_COMMON *cm, int mi_size) {
  cm->mip = vpx_calloc(mi_size, sizeof(*cm->mip));
  if (!cm->mip)
    return 1;
  cm->prev_mip = vpx_calloc(mi_size, sizeof(*cm->prev_mip));
  if (!cm->prev_mip)
    return 1;
  cm->mi_alloc_size = mi_size;
277 278 279 280 281 282 283 284

  cm->mi_grid_base = (MODE_INFO **)vpx_calloc(mi_size, sizeof(MODE_INFO*));
  if (!cm->mi_grid_base)
    return 1;
  cm->prev_mi_grid_base = (MODE_INFO **)vpx_calloc(mi_size, sizeof(MODE_INFO*));
  if (!cm->prev_mi_grid_base)
    return 1;

285 286 287 288 289 290 291 292
  return 0;
}

static void vp9_enc_free_mi(VP9_COMMON *cm) {
  vpx_free(cm->mip);
  cm->mip = NULL;
  vpx_free(cm->prev_mip);
  cm->prev_mip = NULL;
293 294 295 296
  vpx_free(cm->mi_grid_base);
  cm->mi_grid_base = NULL;
  vpx_free(cm->prev_mi_grid_base);
  cm->prev_mi_grid_base = NULL;
297 298 299 300
}

static void vp9_swap_mi_and_prev_mi(VP9_COMMON *cm) {
  // Current mip will be the prev_mip for the next frame.
301
  MODE_INFO **temp_base = cm->prev_mi_grid_base;
302 303 304 305 306 307 308
  MODE_INFO *temp = cm->prev_mip;
  cm->prev_mip = cm->mip;
  cm->mip = temp;

  // Update the upper left visible macroblock ptrs.
  cm->mi = cm->mip + cm->mi_stride + 1;
  cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
309 310 311 312 313

  cm->prev_mi_grid_base = cm->mi_grid_base;
  cm->mi_grid_base = temp_base;
  cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
  cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
314 315
}

316
void vp9_initialize_enc(void) {
317
  static volatile int init_done = 0;
John Koleszar's avatar
John Koleszar committed
318 319

  if (!init_done) {
320
    vp9_rtcd();
321
    vpx_scale_rtcd();
322
    vp9_init_intra_predictors();
323
    vp9_init_me_luts();
324
    vp9_rc_init_minq_luts();
325
    vp9_entropy_mv_init();
326
    vp9_temporal_filter_init();
John Koleszar's avatar
John Koleszar committed
327 328
    init_done = 1;
  }
John Koleszar's avatar
John Koleszar committed
329 330
}

331
static void dealloc_compressor_data(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
332
  VP9_COMMON *const cm = &cpi->common;
333
  int i;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
334

335 336
  vpx_free(cpi->tile_data);
  cpi->tile_data = NULL;
337

338
  // Delete sementation map
John Koleszar's avatar
John Koleszar committed
339
  vpx_free(cpi->segmentation_map);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
340
  cpi->segmentation_map = NULL;
John Koleszar's avatar
John Koleszar committed
341
  vpx_free(cpi->coding_context.last_frame_seg_map_copy);
Dmitry Kovalev's avatar
Dmitry Kovalev committed
342
  cpi->coding_context.last_frame_seg_map_copy = NULL;
John Koleszar's avatar
John Koleszar committed
343

Jingning Han's avatar
Jingning Han committed
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363
  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;

364 365 366
  vp9_cyclic_refresh_free(cpi->cyclic_refresh);
  cpi->cyclic_refresh = NULL;

367 368 369
  vpx_free(cpi->active_map.map);
  cpi->active_map.map = NULL;

370 371 372 373
  vp9_free_ref_frame_buffers(cm->buffer_pool);
#if CONFIG_VP9_POSTPROC
  vp9_free_postproc_buffers(cm);
#endif
374
  vp9_free_context_buffers(cm);
John Koleszar's avatar
John Koleszar committed
375

376 377
  vp9_free_frame_buffer(&cpi->last_frame_uf);
  vp9_free_frame_buffer(&cpi->scaled_source);
378
  vp9_free_frame_buffer(&cpi->scaled_last_source);
379
  vp9_free_frame_buffer(&cpi->alt_ref_buffer);
380
  vp9_lookahead_destroy(cpi->lookahead);
John Koleszar's avatar
John Koleszar committed
381

382 383
  vpx_free(cpi->tile_tok[0][0]);
  cpi->tile_tok[0][0] = 0;
John Koleszar's avatar
John Koleszar committed
384

385
  vp9_free_pc_tree(&cpi->td);
386

387 388 389 390 391 392
  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;
  }
393 394 395 396 397

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

399 400 401 402 403
  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]));
404 405 406

  vp9_free_frame_buffer(&cpi->svc.empty_frame.img);
  vpx_memset(&cpi->svc.empty_frame, 0, sizeof(cpi->svc.empty_frame));
John Koleszar's avatar
John Koleszar committed
407 408
}

409 410 411 412 413 414 415 416
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.
417
  vp9_copy(cc->nmvjointcost,  cpi->td.mb.nmvjointcost);
Jingning Han's avatar
Jingning Han committed
418

James Zern's avatar
James Zern committed
419 420 421 422 423 424 425 426
  memcpy(cc->nmvcosts[0], cpi->nmvcosts[0],
         MV_VALS * sizeof(*cpi->nmvcosts[0]));
  memcpy(cc->nmvcosts[1], cpi->nmvcosts[1],
         MV_VALS * sizeof(*cpi->nmvcosts[1]));
  memcpy(cc->nmvcosts_hp[0], cpi->nmvcosts_hp[0],
         MV_VALS * sizeof(*cpi->nmvcosts_hp[0]));
  memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1],
         MV_VALS * sizeof(*cpi->nmvcosts_hp[1]));
427 428 429

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

James Zern's avatar
James Zern committed
430 431
  memcpy(cpi->coding_context.last_frame_seg_map_copy,
         cm->last_frame_seg_map, (cm->mi_rows * cm->mi_cols));
432 433 434 435

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

436
  cc->fc = *cm->fc;
437 438 439 440 441 442 443 444
}

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.
445
  vp9_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
Jingning Han's avatar
Jingning Han committed
446

James Zern's avatar
James Zern committed
447 448 449 450 451 452
  memcpy(cpi->nmvcosts[0], cc->nmvcosts[0], MV_VALS * sizeof(*cc->nmvcosts[0]));
  memcpy(cpi->nmvcosts[1], cc->nmvcosts[1], MV_VALS * sizeof(*cc->nmvcosts[1]));
  memcpy(cpi->nmvcosts_hp[0], cc->nmvcosts_hp[0],
         MV_VALS * sizeof(*cc->nmvcosts_hp[0]));
  memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1],
         MV_VALS * sizeof(*cc->nmvcosts_hp[1]));
453 454 455

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

James Zern's avatar
James Zern committed
456 457 458
  memcpy(cm->last_frame_seg_map,
         cpi->coding_context.last_frame_seg_map_copy,
         (cm->mi_rows * cm->mi_cols));
459 460 461 462

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

463
  *cm->fc = cc->fc;
464 465
}

466
static void configure_static_seg_features(VP9_COMP *cpi) {
Dmitry Kovalev's avatar
Dmitry Kovalev committed
467
  VP9_COMMON *const cm = &cpi->common;
468
  const RATE_CONTROL *const rc = &cpi->rc;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
469
  struct segmentation *const seg = &cm->seg;
470

471
  int high_q = (int)(rc->avg_q > 48.0);
John Koleszar's avatar
John Koleszar committed
472
  int qi_delta;
473

John Koleszar's avatar
John Koleszar committed
474 475 476
  // Disable and clear down for KF
  if (cm->frame_type == KEY_FRAME) {
    // Clear down the global segmentation map
477
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
478 479
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
480
    cpi->static_mb_pct = 0;
481

John Koleszar's avatar
John Koleszar committed
482
    // Disable segmentation
483
    vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
484

John Koleszar's avatar
John Koleszar committed
485
    // Clear down the segment features.
486
    vp9_clearall_segfeatures(seg);
487 488
  } else if (cpi->refresh_alt_ref_frame) {
    // If this is an alt ref frame
John Koleszar's avatar
John Koleszar committed
489
    // Clear down the global segmentation map
490
    vpx_memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
491 492
    seg->update_map = 0;
    seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
493
    cpi->static_mb_pct = 0;
Paul Wilkins's avatar
Paul Wilkins committed
494

John Koleszar's avatar
John Koleszar committed
495
    // Disable segmentation and individual segment features by default
496
    vp9_disable_segmentation(seg);
497
    vp9_clearall_segfeatures(seg);
Paul Wilkins's avatar
Paul Wilkins committed
498

John Koleszar's avatar
John Koleszar committed
499 500
    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
501
    vp9_update_mbgraph_stats(cpi);
Paul Wilkins's avatar
Paul Wilkins committed
502

John Koleszar's avatar
John Koleszar committed
503 504
    // If segmentation was enabled set those features needed for the
    // arf itself.
505 506 507
    if (seg->enabled) {
      seg->update_map = 1;
      seg->update_data = 1;
Paul Wilkins's avatar
Paul Wilkins committed
508

509 510
      qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875,
                                    cm->bit_depth);
511
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
512
      vp9_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Paul Wilkins's avatar
Paul Wilkins committed
513

514 515
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
516

John Koleszar's avatar
John Koleszar committed
517
      // Where relevant assume segment data is delta data
518
      seg->abs_delta = SEGMENT_DELTADATA;
519
    }
520
  } else if (seg->enabled) {
521 522
    // All other frames if segmentation has been enabled

John Koleszar's avatar
John Koleszar committed
523
    // First normal frame in a valid gf or alt ref group
524
    if (rc->frames_since_golden == 0) {
Paul Wilkins's avatar
Paul Wilkins committed
525
      // Set up segment features for normal frames in an arf group
526
      if (rc->source_alt_ref_active) {
527 528 529
        seg->update_map = 0;
        seg->update_data = 1;
        seg->abs_delta = SEGMENT_DELTADATA;
Paul Wilkins's avatar
Paul Wilkins committed
530

531 532
        qi_delta = vp9_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125,
                                      cm->bit_depth);
533
        vp9_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
534
        vp9_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Paul Wilkins's avatar
Paul Wilkins committed
535

536 537
        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
538

John Koleszar's avatar
John Koleszar committed
539 540
        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
541 542 543
          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
544
        }
545 546 547 548
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

549
        vp9_disable_segmentation(seg);
Paul Wilkins's avatar
Paul Wilkins committed
550

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

553 554
        seg->update_map = 0;
        seg->update_data = 0;
Paul Wilkins's avatar
Paul Wilkins committed
555

556
        vp9_clearall_segfeatures(seg);
John Koleszar's avatar
John Koleszar committed
557
      }
558
    } else if (rc->is_src_frame_alt_ref) {
559 560 561
      // 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
562

Paul Wilkins's avatar
Paul Wilkins committed
563
      // Enable ref frame features for segment 0 as well
564 565
      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
566

Paul Wilkins's avatar
Paul Wilkins committed
567
      // All mbs should use ALTREF_FRAME
568 569 570 571
      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
572

Paul Wilkins's avatar
Paul Wilkins committed
573
      // Skip all MBs if high Q (0,0 mv and skip coeffs)
John Koleszar's avatar
John Koleszar committed
574
      if (high_q) {
575 576
        vp9_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        vp9_enable_segfeature(seg, 1, SEG_LVL_SKIP);
John Koleszar's avatar
John Koleszar committed
577
      }
Adrian Grange's avatar
Adrian Grange committed
578
      // Enable data update
579
      seg->update_data = 1;
580 581 582
    } else {
      // All other frames.

John Koleszar's avatar
John Koleszar committed
583
      // No updates.. leave things as they are.
584 585
      seg->update_map = 0;
      seg->update_data = 0;
John Koleszar's avatar
John Koleszar committed
586 587
    }
  }
588 589
}

590
static void update_reference_segmentation_map(VP9_COMP *cpi) {
Ronald S. Bultje's avatar
Ronald S. Bultje committed
591
  VP9_COMMON *const cm = &cpi->common;
592
  MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
593
  uint8_t *cache_ptr = cm->last_frame_seg_map;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
594 595
  int row, col;

596
  for (row = 0; row < cm->mi_rows; row++) {
597
    MODE_INFO **mi_8x8 = mi_8x8_ptr;
Dmitry Kovalev's avatar
Dmitry Kovalev committed
598
    uint8_t *cache = cache_ptr;
599
    for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
600
      cache[0] = mi_8x8[0]->mbmi.segment_id;
601
    mi_8x8_ptr += cm->mi_stride;
602
    cache_ptr += cm->mi_cols;
Ronald S. Bultje's avatar
Ronald S. Bultje committed
603 604 605
  }
}

606
static void alloc_raw_frame_buffers(VP9_COMP *cpi) {
607
  VP9_COMMON *cm = &cpi->common;
608
  const VP9EncoderConfig *oxcf = &cpi->oxcf;
609

610 611 612
  if (!cpi->lookahead)
    cpi->lookahead = vp9_lookahead_init(oxcf->width, oxcf->height,
                                        cm->subsampling_x, cm->subsampling_y,
613 614 615
#if CONFIG_VP9_HIGHBITDEPTH
                                      cm->use_highbitdepth,
#endif
Dmitry Kovalev's avatar
Dmitry Kovalev committed
616
                                      oxcf->lag_in_frames);
John Koleszar's avatar
John Koleszar committed
617
  if (!cpi->lookahead)
618
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
619
                       "Failed to allocate lag buffers");
John Koleszar's avatar
John Koleszar committed
620

621
  // TODO(agrange) Check if ARF is enabled and skip allocation if not.
622
  if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
Dmitry Kovalev's avatar
Dmitry Kovalev committed
623
                               oxcf->width, oxcf->height,
624
                               cm->subsampling_x, cm->subsampling_y,
625 626 627
#if CONFIG_VP9_HIGHBITDEPTH
                               cm->use_highbitdepth,
#endif
628 629
                               VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
                               NULL, NULL, NULL))
630
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
John Koleszar's avatar
John Koleszar committed
631
                       "Failed to allocate altref buffer");
John Koleszar's avatar
John Koleszar committed
632
}
633

634
static void alloc_util_frame_buffers(VP9_COMP *cpi) {
635
  VP9_COMMON *const cm = &cpi->common;
636 637 638
  if (vp9_realloc_frame_buffer(&cpi->last_frame_uf,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
639 640 641
#if CONFIG_VP9_HIGHBITDEPTH
                               cm->use_highbitdepth,
#endif
642 643
                               VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
                               NULL, NULL, NULL))
644
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
645
                       "Failed to allocate last frame buffer");
646

647 648 649
  if (vp9_realloc_frame_buffer(&cpi->scaled_source,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
650 651 652
#if CONFIG_VP9_HIGHBITDEPTH
                               cm->use_highbitdepth,
#endif
653 654
                               VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
                               NULL, NULL, NULL))
655
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
656
                       "Failed to allocate scaled source buffer");
657

658 659 660
  if (vp9_realloc_frame_buffer(&cpi->scaled_last_source,
                               cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
661 662 663
#if CONFIG_VP9_HIGHBITDEPTH
                               cm->use_highbitdepth,
#endif
664 665
                               VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
                               NULL, NULL, NULL))
666
    vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
667 668
                       "Failed to allocate scaled last source buffer");
}
669

670 671
void vp9_alloc_compressor_data(VP9_COMP *cpi) {
  VP9_COMMON *cm = &cpi->common;
672

673 674
  vp9_alloc_context_buffers(cm, cm->width, cm->height);

675
  vpx_free(cpi->tile_tok[0][0]);
676 677 678

  {
    unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
679 680
    CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
        vpx_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
681
  }
682

683
  vp9_setup_pc_tree(&cpi->common, &cpi->td);
684 685 686 687
}

static void update_frame_size(VP9_COMP *cpi) {
  VP9_COMMON *const cm = &cpi->common;
688
  MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
Adrian Grange's avatar
Adrian Grange committed
689 690 691

  vp9_set_mb_mi(cm, cm->width, cm->height);
  vp9_init_context_buffers(cm);
692
  init_macroblockd(cm, xd);
693

694
  if (is_two_pass_svc(cpi)) {
695 696 697
    if (vp9_realloc_frame_buffer(&cpi->alt_ref_buffer,
                                 cm->width, cm->height,
                                 cm->subsampling_x, cm->subsampling_y,
698 699 700
#if CONFIG_VP9_HIGHBITDEPTH
                                 cm->use_highbitdepth,
#endif
701 702
                                 VP9_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
                                 NULL, NULL, NULL))
703 704 705
      vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
                         "Failed to reallocate alt_ref_buffer");
  }
706 707
}

James Zern's avatar
James Zern committed
708
void vp9_new_framerate(VP9_COMP *cpi, double framerate) {
709
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
710
  vp9_rc_update_framerate(cpi);
John Koleszar's avatar
John Koleszar committed
711 712
}

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

Dmitry Kovalev's avatar
Dmitry Kovalev committed
716 717
  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);
718

719 720 721 722 723 724 725 726
  if (is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING) {
    cm->log2_tile_cols = 0;
    cm->log2_tile_rows = 0;
  } else {
    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;
  }
727
}
728

729 730 731 732 733 734
static void init_buffer_indices(VP9_COMP *cpi) {
  cpi->lst_fb_idx = 0;
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
}

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

John Koleszar's avatar
John Koleszar committed
738
  cpi->oxcf = *oxcf;
739
  cpi->framerate = oxcf->init_framerate;
John Koleszar's avatar
John Koleszar committed
740

741 742
  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
743 744 745
#if CONFIG_VP9_HIGHBITDEPTH
  cm->use_highbitdepth = oxcf->use_highbitdepth;
#endif
746
  cm->color_space = oxcf->color_space;
John Koleszar's avatar
John Koleszar committed
747

748 749
  cm->width = oxcf->width;
  cm->height = oxcf->height;
750
  vp9_alloc_compressor_data(cpi);
751

752 753 754
  // Single thread case: use counts in common.
  cpi->td.counts = &cm->counts;

755 756 757 758 759
  // Spatial scalability.
  cpi->svc.number_spatial_layers = oxcf->ss_number_layers;
  // Temporal scalability.
  cpi->svc.number_temporal_layers = oxcf->ts_number_layers;

760
  if ((cpi->svc.number_temporal_layers > 1 && cpi->oxcf.rc_mode == VPX_CBR) ||
761 762
      ((cpi->svc.number_temporal_layers > 1 ||
        cpi->svc.number_spatial_layers > 1) &&
763
       cpi->oxcf.pass != 1)) {
764
    vp9_init_layer_context(cpi);
765 766
  }

John Koleszar's avatar
John Koleszar committed
767
  // change includes all joint functionality
Dmitry Kovalev's avatar
Dmitry Kovalev committed
768
  vp9_change_config(cpi, oxcf);
John Koleszar's avatar
John Koleszar committed
769

John Koleszar's avatar
John Koleszar committed
770
  cpi->static_mb_pct = 0;
771
  cpi->ref_frame_flags = 0;
772

773
  init_buffer_indices(cpi);
John Koleszar's avatar
John Koleszar committed
774 775
}

Dmitry Kovalev's avatar
Dmitry Kovalev committed
776 777 778 779 780 781 782 783 784 785 786 787 788 789
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;
}

790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
#if CONFIG_VP9_HIGHBITDEPTH
#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
    cpi->fn_ptr[BT].sdf = SDF; \
    cpi->fn_ptr[BT].sdaf = SDAF; \
    cpi->fn_ptr[BT].vf = VF; \
    cpi->fn_ptr[BT].svf = SVF; \
    cpi->fn_ptr[BT].svaf = SVAF; \
    cpi->fn_ptr[BT].sdx3f = SDX3F; \
    cpi->fn_ptr[BT].sdx8f = SDX8F; \
    cpi->fn_ptr[BT].sdx4df = SDX4DF;

#define MAKE_BFP_SAD_WRAPPER(fnname) \
static unsigned int fnname##_bits8(const uint8_t *src_ptr, \
                                   int source_stride, \
                                   const uint8_t *ref_ptr, \
                                   int ref_stride) {  \
  return fnname(src_ptr, source_stride, ref_ptr, ref_stride); \
} \
static unsigned int fnname##_bits10(const uint8_t *src_ptr, \
                                    int source_stride, \
                                    const uint8_t *ref_ptr, \
                                    int ref_stride) {  \
  return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2; \
} \
static unsigned int fnname##_bits12(const uint8_t *src_ptr, \
                                    int source_stride, \
                                    const uint8_t *ref_ptr, \
                                    int ref_stride) {  \
  return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4; \
}

#define MAKE_BFP_SADAVG_WRAPPER(fnname) static unsigned int \
fnname##_bits8(const uint8_t *src_ptr, \
               int source_stride, \
               const uint8_t *ref_ptr, \
               int ref_stride, \
               const uint8_t *second_pred) {  \
  return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred); \
} \
static unsigned int fnname##_bits10(const uint8_t *src_ptr, \
                                    int source_stride, \
                                    const uint8_t *ref_ptr, \
                                    int ref_stride, \
                                    const uint8_t *second_pred) {  \
  return fnname(src_ptr, source_stride, ref_ptr, ref_stride, \
                second_pred) >> 2; \
} \
static unsigned int fnname##_bits12(const uin