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

11
#include <limits.h>
Jingning Han's avatar
Jingning Han committed
12 13 14
#include <math.h>
#include <stdio.h>

Yaowu Xu's avatar
Yaowu Xu committed
15
#include "./aom_config.h"
Jingning Han's avatar
Jingning Han committed
16

17
#include "av1/common/alloccommon.h"
18
#if CONFIG_CLPF
19
#include "av1/common/clpf.h"
20
#endif
Yaowu Xu's avatar
Yaowu Xu committed
21
#if CONFIG_DERING
22
#include "av1/common/dering.h"
Yaowu Xu's avatar
Yaowu Xu committed
23
#endif  // CONFIG_DERING
24 25 26 27 28
#include "av1/common/filter.h"
#include "av1/common/idct.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
#include "av1/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
29

30 31 32 33
#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/aq_variance.h"
#include "av1/encoder/bitstream.h"
34
#if CONFIG_ANS
35
#include "av1/encoder/buf_ans.h"
36
#endif
37 38 39 40 41 42 43 44
#include "av1/encoder/context_tree.h"
#include "av1/encoder/encodeframe.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/encoder.h"
#include "av1/encoder/ethread.h"
#include "av1/encoder/firstpass.h"
#include "av1/encoder/mbgraph.h"
#include "av1/encoder/picklpf.h"
45
#if CONFIG_LOOP_RESTORATION
46
#include "av1/encoder/pickrst.h"
47
#endif  // CONFIG_LOOP_RESTORATION
48 49 50 51 52 53
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/rd.h"
#include "av1/encoder/resize.h"
#include "av1/encoder/segmentation.h"
#include "av1/encoder/speed_features.h"
#include "av1/encoder/temporal_filter.h"
Jingning Han's avatar
Jingning Han committed
54

Yaowu Xu's avatar
Yaowu Xu committed
55 56 57
#include "./av1_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_scale_rtcd.h"
58
#include "aom_dsp/psnr.h"
59
#if CONFIG_INTERNAL_STATS
60
#include "aom_dsp/ssim.h"
61
#endif
Yaowu Xu's avatar
Yaowu Xu committed
62 63
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/aom_filter.h"
Jingning Han's avatar
Jingning Han committed
64
#include "aom_ports/aom_timer.h"
65 66
#include "aom_ports/mem.h"
#include "aom_ports/system_state.h"
Yaowu Xu's avatar
Yaowu Xu committed
67
#include "aom_scale/aom_scale.h"
68
#include "aom_util/debug_util.h"
69

Jingning Han's avatar
Jingning Han committed
70 71 72
#define AM_SEGMENT_ID_INACTIVE 7
#define AM_SEGMENT_ID_ACTIVE 0

73 74 75 76 77 78 79 80
#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */

#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.
Jingning Han's avatar
Jingning Han committed
81 82 83 84 85 86 87 88 89
// #define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file = NULL;
#endif
#ifdef OUTPUT_YUV_SKINMAP
FILE *yuv_skinmap_file = NULL;
#endif
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
90
#define FILE_NAME_LEN 100
Jingning Han's avatar
Jingning Han committed
91 92 93 94 95 96 97 98
#endif

#if 0
FILE *framepsnr;
FILE *kf_list;
FILE *keyfile;
#endif

Yaowu Xu's avatar
Yaowu Xu committed
99
static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Jingning Han's avatar
Jingning Han committed
100 101 102 103 104 105 106 107 108 109 110 111
  switch (mode) {
    case NORMAL:
      *hr = 1;
      *hs = 1;
      break;
    case FOURFIVE:
      *hr = 4;
      *hs = 5;
      break;
    case THREEFIVE:
      *hr = 3;
      *hs = 5;
112
      break;
Jingning Han's avatar
Jingning Han committed
113 114 115
    case ONETWO:
      *hr = 1;
      *hs = 2;
116
      break;
Jingning Han's avatar
Jingning Han committed
117 118 119
    default:
      *hr = 1;
      *hs = 1;
120
      assert(0);
Jingning Han's avatar
Jingning Han committed
121 122 123 124 125 126
      break;
  }
}

// Mark all inactive blocks as active. Other segmentation features may be set
// so memset cannot be used, instead only inactive blocks should be reset.
Yaowu Xu's avatar
Yaowu Xu committed
127
static void suppress_active_map(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
128 129 130 131 132 133 134 135
  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;
}

Yaowu Xu's avatar
Yaowu Xu committed
136
static void apply_active_map(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
  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);

  if (frame_is_intra_only(&cpi->common)) {
    cpi->active_map.enabled = 0;
    cpi->active_map.update = 1;
  }

  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];
Yaowu Xu's avatar
Yaowu Xu committed
153 154 155
      av1_enable_segmentation(seg);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
156 157
      // 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.
Yaowu Xu's avatar
Yaowu Xu committed
158 159
      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
                      -MAX_LOOP_FILTER);
Jingning Han's avatar
Jingning Han committed
160
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
161 162
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
163 164 165 166 167 168 169 170 171
      if (seg->enabled) {
        seg->update_data = 1;
        seg->update_map = 1;
      }
    }
    cpi->active_map.update = 0;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
172 173
int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
  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;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
199 200
int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
201 202
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
      new_map_16x16) {
203
    unsigned char *const seg_map_8x8 = cpi->segmentation_map;
Jingning Han's avatar
Jingning Han committed
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
    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;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
224
void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Jingning Han's avatar
Jingning Han committed
225 226
  MACROBLOCK *const mb = &cpi->td.mb;
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

#if CONFIG_REF_MV
  if (cpi->common.allow_high_precision_mv) {
    int i;
    for (i = 0; i < NMV_CONTEXTS; ++i) {
      mb->mv_cost_stack[i] = mb->nmvcost_hp[i];
      mb->mvsadcost = mb->nmvsadcost_hp;
    }
  } else {
    int i;
    for (i = 0; i < NMV_CONTEXTS; ++i) {
      mb->mv_cost_stack[i] = mb->nmvcost[i];
      mb->mvsadcost = mb->nmvsadcost;
    }
  }
#else
Jingning Han's avatar
Jingning Han committed
243 244
  if (cpi->common.allow_high_precision_mv) {
    mb->mvcost = mb->nmvcost_hp;
245
    mb->mvsadcost = mb->nmvcost_hp;
Jingning Han's avatar
Jingning Han committed
246 247
  } else {
    mb->mvcost = mb->nmvcost;
248
    mb->mvsadcost = mb->nmvcost;
Jingning Han's avatar
Jingning Han committed
249
  }
250
#endif
Jingning Han's avatar
Jingning Han committed
251 252
}

Yaowu Xu's avatar
Yaowu Xu committed
253
static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
254
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
255
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
256 257
    return BLOCK_64X64;

Yaowu Xu's avatar
Yaowu Xu committed
258
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
259 260
    return BLOCK_128X128;

Yaowu Xu's avatar
Yaowu Xu committed
261
  assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
262 263 264 265 266 267 268 269 270 271 272 273 274 275

  assert(IMPLIES(cpi->common.tile_cols > 1,
                 cpi->common.tile_width % MAX_MIB_SIZE == 0));
  assert(IMPLIES(cpi->common.tile_rows > 1,
                 cpi->common.tile_height % MAX_MIB_SIZE == 0));

  // TODO(any): Possibly could improve this with a heuristic.
  return BLOCK_128X128;
#else
  (void)cpi;
  return BLOCK_64X64;
#endif  //  CONFIG_EXT_PARTITION
}

Yaowu Xu's avatar
Yaowu Xu committed
276 277
static void setup_frame(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
278 279 280 281 282 283
  // 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 (frame_is_intra_only(cm) || cm->error_resilient_mode) {
Yaowu Xu's avatar
Yaowu Xu committed
284
    av1_setup_past_independence(cm);
Jingning Han's avatar
Jingning Han committed
285
  } else {
286 287 288 289 290 291 292
#if CONFIG_EXT_REFS
    const GF_GROUP *gf_group = &cpi->twopass.gf_group;
    if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
      cm->frame_context_idx = EXT_ARF_FRAME;
    else if (cpi->refresh_alt_ref_frame)
      cm->frame_context_idx = ARF_FRAME;
#else
293
    if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
294
#endif
295 296 297 298 299 300 301 302 303 304
    else if (cpi->rc.is_src_frame_alt_ref)
      cm->frame_context_idx = OVERLAY_FRAME;
    else if (cpi->refresh_golden_frame)
      cm->frame_context_idx = GLD_FRAME;
#if CONFIG_EXT_REFS
    else if (cpi->refresh_bwd_ref_frame)
      cm->frame_context_idx = BRF_FRAME;
#endif
    else
      cm->frame_context_idx = REGULAR_FRAME;
Jingning Han's avatar
Jingning Han committed
305 306 307
  }

  if (cm->frame_type == KEY_FRAME) {
Yunqing Wang's avatar
Yunqing Wang committed
308
    cpi->refresh_golden_frame = 1;
Jingning Han's avatar
Jingning Han committed
309
    cpi->refresh_alt_ref_frame = 1;
Yaowu Xu's avatar
Yaowu Xu committed
310
    av1_zero(cpi->interp_filter_selected);
Jingning Han's avatar
Jingning Han committed
311 312
  } else {
    *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xu's avatar
Yaowu Xu committed
313
    av1_zero(cpi->interp_filter_selected[0]);
Jingning Han's avatar
Jingning Han committed
314
  }
315

Geza Lore's avatar
Geza Lore committed
316 317
  cpi->vaq_refresh = 0;

318
  set_sb_size(cm, select_sb_size(cpi));
Jingning Han's avatar
Jingning Han committed
319 320
}

Yaowu Xu's avatar
Yaowu Xu committed
321
static void av1_enc_setup_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
  int i;
  cm->mi = cm->mip + cm->mi_stride + 1;
  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
  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)
    memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));

  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;

  memset(cm->mi_grid_base, 0,
         cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
}

Yaowu Xu's avatar
Yaowu Xu committed
339 340
static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
  cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
341
  if (!cm->mip) return 1;
Yaowu Xu's avatar
Yaowu Xu committed
342
  cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
343
  if (!cm->prev_mip) return 1;
Jingning Han's avatar
Jingning Han committed
344 345
  cm->mi_alloc_size = mi_size;

Yaowu Xu's avatar
Yaowu Xu committed
346
  cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
347 348
  if (!cm->mi_grid_base) return 1;
  cm->prev_mi_grid_base =
Yaowu Xu's avatar
Yaowu Xu committed
349
      (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
350
  if (!cm->prev_mi_grid_base) return 1;
Jingning Han's avatar
Jingning Han committed
351 352 353 354

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
355 356
static void av1_enc_free_mi(AV1_COMMON *cm) {
  aom_free(cm->mip);
Jingning Han's avatar
Jingning Han committed
357
  cm->mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
358
  aom_free(cm->prev_mip);
Jingning Han's avatar
Jingning Han committed
359
  cm->prev_mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
360
  aom_free(cm->mi_grid_base);
Jingning Han's avatar
Jingning Han committed
361
  cm->mi_grid_base = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
362
  aom_free(cm->prev_mi_grid_base);
Jingning Han's avatar
Jingning Han committed
363 364 365
  cm->prev_mi_grid_base = NULL;
}

Yaowu Xu's avatar
Yaowu Xu committed
366
static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
  // Current mip will be the prev_mip for the next frame.
  MODE_INFO **temp_base = cm->prev_mi_grid_base;
  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;

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

Yaowu Xu's avatar
Yaowu Xu committed
383
void av1_initialize_enc(void) {
Jingning Han's avatar
Jingning Han committed
384 385 386
  static volatile int init_done = 0;

  if (!init_done) {
Yaowu Xu's avatar
Yaowu Xu committed
387 388 389 390 391 392 393 394
    av1_rtcd();
    aom_dsp_rtcd();
    aom_scale_rtcd();
    av1_init_intra_predictors();
    av1_init_me_luts();
    av1_rc_init_minq_luts();
    av1_entropy_mv_init();
    av1_encode_token_init();
395
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
396
    av1_init_wedge_masks();
397
#endif
Jingning Han's avatar
Jingning Han committed
398 399 400 401
    init_done = 1;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
402 403
static void dealloc_compressor_data(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
404
  int i;
Jingning Han's avatar
Jingning Han committed
405

Yaowu Xu's avatar
Yaowu Xu committed
406
  aom_free(cpi->mbmi_ext_base);
Jingning Han's avatar
Jingning Han committed
407 408
  cpi->mbmi_ext_base = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
409
  aom_free(cpi->tile_data);
Jingning Han's avatar
Jingning Han committed
410 411 412
  cpi->tile_data = NULL;

  // Delete sementation map
Yaowu Xu's avatar
Yaowu Xu committed
413
  aom_free(cpi->segmentation_map);
Jingning Han's avatar
Jingning Han committed
414
  cpi->segmentation_map = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
415
  aom_free(cpi->coding_context.last_frame_seg_map_copy);
Jingning Han's avatar
Jingning Han committed
416 417
  cpi->coding_context.last_frame_seg_map_copy = NULL;

418 419
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
420 421 422 423
    aom_free(cpi->nmv_costs[i][0]);
    aom_free(cpi->nmv_costs[i][1]);
    aom_free(cpi->nmv_costs_hp[i][0]);
    aom_free(cpi->nmv_costs_hp[i][1]);
424 425 426 427 428 429 430
    cpi->nmv_costs[i][0] = NULL;
    cpi->nmv_costs[i][1] = NULL;
    cpi->nmv_costs_hp[i][0] = NULL;
    cpi->nmv_costs_hp[i][1] = NULL;
  }
#endif

Yaowu Xu's avatar
Yaowu Xu committed
431 432
  aom_free(cpi->nmvcosts[0]);
  aom_free(cpi->nmvcosts[1]);
Jingning Han's avatar
Jingning Han committed
433 434 435
  cpi->nmvcosts[0] = NULL;
  cpi->nmvcosts[1] = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
436 437
  aom_free(cpi->nmvcosts_hp[0]);
  aom_free(cpi->nmvcosts_hp[1]);
Jingning Han's avatar
Jingning Han committed
438 439 440
  cpi->nmvcosts_hp[0] = NULL;
  cpi->nmvcosts_hp[1] = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
441 442
  aom_free(cpi->nmvsadcosts[0]);
  aom_free(cpi->nmvsadcosts[1]);
Jingning Han's avatar
Jingning Han committed
443 444 445
  cpi->nmvsadcosts[0] = NULL;
  cpi->nmvsadcosts[1] = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
446 447
  aom_free(cpi->nmvsadcosts_hp[0]);
  aom_free(cpi->nmvsadcosts_hp[1]);
Jingning Han's avatar
Jingning Han committed
448 449 450
  cpi->nmvsadcosts_hp[0] = NULL;
  cpi->nmvsadcosts_hp[1] = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
451
  av1_cyclic_refresh_free(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
452 453
  cpi->cyclic_refresh = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
454
  aom_free(cpi->active_map.map);
Jingning Han's avatar
Jingning Han committed
455 456
  cpi->active_map.map = NULL;

457
  // Free up-sampled reference buffers.
458
  for (i = 0; i < (REF_FRAMES + 1); i++)
Yaowu Xu's avatar
Yaowu Xu committed
459
    aom_free_frame_buffer(&cpi->upsampled_ref_bufs[i].buf);
460

Yaowu Xu's avatar
Yaowu Xu committed
461 462
  av1_free_ref_frame_buffers(cm->buffer_pool);
  av1_free_context_buffers(cm);
Jingning Han's avatar
Jingning Han committed
463

Yaowu Xu's avatar
Yaowu Xu committed
464
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
465
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
466 467
  aom_free_frame_buffer(&cpi->last_frame_db);
  av1_free_restoration_buffers(cm);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
468
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
469 470 471 472
  aom_free_frame_buffer(&cpi->scaled_source);
  aom_free_frame_buffer(&cpi->scaled_last_source);
  aom_free_frame_buffer(&cpi->alt_ref_buffer);
  av1_lookahead_destroy(cpi->lookahead);
Jingning Han's avatar
Jingning Han committed
473

Yaowu Xu's avatar
Yaowu Xu committed
474
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
475 476
  cpi->tile_tok[0][0] = 0;

Yaowu Xu's avatar
Yaowu Xu committed
477 478
  av1_free_pc_tree(&cpi->td);
  av1_free_var_tree(&cpi->td);
479

hui su's avatar
hui su committed
480
  if (cpi->common.allow_screen_content_tools)
Yaowu Xu's avatar
Yaowu Xu committed
481
    aom_free(cpi->td.mb.palette_buffer);
hui su's avatar
hui su committed
482

Jingning Han's avatar
Jingning Han committed
483
  if (cpi->source_diff_var != NULL) {
Yaowu Xu's avatar
Yaowu Xu committed
484
    aom_free(cpi->source_diff_var);
Jingning Han's avatar
Jingning Han committed
485 486
    cpi->source_diff_var = NULL;
  }
487
#if CONFIG_ANS
Yaowu Xu's avatar
Yaowu Xu committed
488
  av1_buf_ans_free(&cpi->buf_ans);
489
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
490 491
}

Yaowu Xu's avatar
Yaowu Xu committed
492
static void save_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
493
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
494
  AV1_COMMON *cm = &cpi->common;
495 496 497
#if CONFIG_REF_MV
  int i;
#endif
Jingning Han's avatar
Jingning Han committed
498

499
// Stores a snapshot of key state variables which can subsequently be
Yaowu Xu's avatar
Yaowu Xu committed
500 501
// restored with a call to av1_restore_coding_context. These functions are
// intended for use in a re-code loop in av1_compress_frame where the
502
// quantizer value is adjusted between loop iterations.
503 504
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
505
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
506 507 508 509 510 511 512 513 514 515
    memcpy(cc->nmv_costs[i][0], cpi->nmv_costs[i][0],
           MV_VALS * sizeof(*cpi->nmv_costs[i][0]));
    memcpy(cc->nmv_costs[i][1], cpi->nmv_costs[i][1],
           MV_VALS * sizeof(*cpi->nmv_costs[i][1]));
    memcpy(cc->nmv_costs_hp[i][0], cpi->nmv_costs_hp[i][0],
           MV_VALS * sizeof(*cpi->nmv_costs_hp[i][0]));
    memcpy(cc->nmv_costs_hp[i][1], cpi->nmv_costs_hp[i][1],
           MV_VALS * sizeof(*cpi->nmv_costs_hp[i][1]));
  }
#else
Yaowu Xu's avatar
Yaowu Xu committed
516
  av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
517
#endif
Jingning Han's avatar
Jingning Han committed
518 519 520 521 522 523 524 525 526 527

  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]));

528 529
  memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map,
         (cm->mi_rows * cm->mi_cols));
Jingning Han's avatar
Jingning Han committed
530

Yaowu Xu's avatar
Yaowu Xu committed
531 532
  av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
  av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
Jingning Han's avatar
Jingning Han committed
533 534 535 536

  cc->fc = *cm->fc;
}

Yaowu Xu's avatar
Yaowu Xu committed
537
static void restore_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
538
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
539
  AV1_COMMON *cm = &cpi->common;
540 541 542
#if CONFIG_REF_MV
  int i;
#endif
Jingning Han's avatar
Jingning Han committed
543

544
// Restore key state variables to the snapshot state stored in the
Yaowu Xu's avatar
Yaowu Xu committed
545
// previous call to av1_save_coding_context.
546 547
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
548
    av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
549 550 551 552 553 554 555 556 557 558
    memcpy(cpi->nmv_costs[i][0], cc->nmv_costs[i][0],
           MV_VALS * sizeof(*cc->nmv_costs[i][0]));
    memcpy(cpi->nmv_costs[i][1], cc->nmv_costs[i][1],
           MV_VALS * sizeof(*cc->nmv_costs[i][1]));
    memcpy(cpi->nmv_costs_hp[i][0], cc->nmv_costs_hp[i][0],
           MV_VALS * sizeof(*cc->nmv_costs_hp[i][0]));
    memcpy(cpi->nmv_costs_hp[i][1], cc->nmv_costs_hp[i][1],
           MV_VALS * sizeof(*cc->nmv_costs_hp[i][1]));
  }
#else
Yaowu Xu's avatar
Yaowu Xu committed
559
  av1_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
560
#endif
Jingning Han's avatar
Jingning Han committed
561 562 563 564 565 566 567 568

  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]));

569
  memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy,
Jingning Han's avatar
Jingning Han committed
570 571
         (cm->mi_rows * cm->mi_cols));

Yaowu Xu's avatar
Yaowu Xu committed
572 573
  av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
  av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
Jingning Han's avatar
Jingning Han committed
574 575 576 577

  *cm->fc = cc->fc;
}

Yaowu Xu's avatar
Yaowu Xu committed
578 579
static void configure_static_seg_features(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
  const RATE_CONTROL *const rc = &cpi->rc;
  struct segmentation *const seg = &cm->seg;

  int high_q = (int)(rc->avg_q > 48.0);
  int qi_delta;

  // Disable and clear down for KF
  if (cm->frame_type == KEY_FRAME) {
    // Clear down the global segmentation map
    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
    seg->update_map = 0;
    seg->update_data = 0;
    cpi->static_mb_pct = 0;

    // Disable segmentation
Yaowu Xu's avatar
Yaowu Xu committed
595
    av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
596 597

    // Clear down the segment features.
Yaowu Xu's avatar
Yaowu Xu committed
598
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
599 600 601 602 603 604 605 606 607
  } else if (cpi->refresh_alt_ref_frame) {
    // If this is an alt ref frame
    // Clear down the global segmentation map
    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
    seg->update_map = 0;
    seg->update_data = 0;
    cpi->static_mb_pct = 0;

    // Disable segmentation and individual segment features by default
Yaowu Xu's avatar
Yaowu Xu committed
608 609
    av1_disable_segmentation(seg);
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
610 611 612

    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
Yaowu Xu's avatar
Yaowu Xu committed
613
    av1_update_mbgraph_stats(cpi);
Jingning Han's avatar
Jingning Han committed
614 615 616 617 618 619 620

    // If segmentation was enabled set those features needed for the
    // arf itself.
    if (seg->enabled) {
      seg->update_map = 1;
      seg->update_data = 1;

621
      qi_delta =
Yaowu Xu's avatar
Yaowu Xu committed
622 623 624
          av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Jingning Han's avatar
Jingning Han committed
625

Yaowu Xu's avatar
Yaowu Xu committed
626 627
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642

      // Where relevant assume segment data is delta data
      seg->abs_delta = SEGMENT_DELTADATA;
    }
  } else if (seg->enabled) {
    // All other frames if segmentation has been enabled

    // First normal frame in a valid gf or alt ref group
    if (rc->frames_since_golden == 0) {
      // Set up segment features for normal frames in an arf group
      if (rc->source_alt_ref_active) {
        seg->update_map = 0;
        seg->update_data = 1;
        seg->abs_delta = SEGMENT_DELTADATA;

Yaowu Xu's avatar
Yaowu Xu committed
643 644 645 646
        qi_delta =
            av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
        av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Jingning Han's avatar
Jingning Han committed
647

Yaowu Xu's avatar
Yaowu Xu committed
648 649
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
650 651 652

        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xu's avatar
Yaowu Xu committed
653 654 655
          av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
          av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
          av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
656 657 658 659 660
        }
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

Yaowu Xu's avatar
Yaowu Xu committed
661
        av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
662 663 664 665 666 667

        memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);

        seg->update_map = 0;
        seg->update_data = 0;

Yaowu Xu's avatar
Yaowu Xu committed
668
        av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
669 670 671 672 673 674 675
      }
    } else if (rc->is_src_frame_alt_ref) {
      // Special case where we are coding over the top of a previous
      // alt ref frame.
      // Segment coding disabled for compred testing

      // Enable ref frame features for segment 0 as well
Yaowu Xu's avatar
Yaowu Xu committed
676 677
      av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
      av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Jingning Han's avatar
Jingning Han committed
678 679

      // All mbs should use ALTREF_FRAME
Yaowu Xu's avatar
Yaowu Xu committed
680 681 682 683
      av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
      av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
      av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
      av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Jingning Han's avatar
Jingning Han committed
684 685 686

      // Skip all MBs if high Q (0,0 mv and skip coeffs)
      if (high_q) {
Yaowu Xu's avatar
Yaowu Xu committed
687 688
        av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
689 690 691 692 693 694 695 696 697 698 699 700 701
      }
      // Enable data update
      seg->update_data = 1;
    } else {
      // All other frames.

      // No updates.. leave things as they are.
      seg->update_map = 0;
      seg->update_data = 0;
    }
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
702 703
static void update_reference_segmentation_map(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
704 705 706 707 708 709 710 711 712 713 714 715 716 717
  MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
  uint8_t *cache_ptr = cm->last_frame_seg_map;
  int row, col;

  for (row = 0; row < cm->mi_rows; row++) {
    MODE_INFO **mi_8x8 = mi_8x8_ptr;
    uint8_t *cache = cache_ptr;
    for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
      cache[0] = mi_8x8[0]->mbmi.segment_id;
    mi_8x8_ptr += cm->mi_stride;
    cache_ptr += cm->mi_cols;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
718 719 720
static void alloc_raw_frame_buffers(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  const AV1EncoderConfig *oxcf = &cpi->oxcf;
Jingning Han's avatar
Jingning Han committed
721 722

  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
723 724 725 726
    cpi->lookahead = av1_lookahead_init(oxcf->width, oxcf->height,
                                        cm->subsampling_x, cm->subsampling_y,
#if CONFIG_AOM_HIGHBITDEPTH
                                        cm->use_highbitdepth,
Jingning Han's avatar
Jingning Han committed
727
#endif
Yaowu Xu's avatar
Yaowu Xu committed
728
                                        oxcf->lag_in_frames);
Jingning Han's avatar
Jingning Han committed
729
  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
730
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
731 732 733
                       "Failed to allocate lag buffers");

  // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xu's avatar
Yaowu Xu committed
734
  if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Jingning Han's avatar
Jingning Han committed
735
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
736
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
737 738
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
739
                               AOM_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
Jingning Han's avatar
Jingning Han committed
740
                               NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
741
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
742 743 744
                       "Failed to allocate altref buffer");
}

Yaowu Xu's avatar
Yaowu Xu committed
745 746 747
static void alloc_util_frame_buffers(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
748
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
749
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
750 751
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
752
                               AOM_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
Jingning Han's avatar
Jingning Han committed
753
                               NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
754
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
755 756
                       "Failed to allocate last frame buffer");

Debargha Mukherjee's avatar
Debargha Mukherjee committed
757
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
758
  if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
759
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
760
#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
761 762
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
763
                               AOM_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
764
                               NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
765
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
766 767 768
                       "Failed to allocate last frame deblocked buffer");
#endif  // CONFIG_LOOP_RESTORATION

Yaowu Xu's avatar
Yaowu Xu committed
769
  if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
770
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
771
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
772 773
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
774
                               AOM_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
Jingning Han's avatar
Jingning Han committed
775
                               NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
776
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
777 778
                       "Failed to allocate scaled source buffer");

Yaowu Xu's avatar
Yaowu Xu committed
779
  if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
780
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
781
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
782 783
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
784
                               AOM_ENC_BORDER_IN_PIXELS, cm->byte_alignment,
Jingning Han's avatar
Jingning Han committed
785
                               NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
786
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
787 788 789
                       "Failed to allocate scaled last source buffer");
}

Yaowu Xu's avatar
Yaowu Xu committed
790 791
static int alloc_context_buffers_ext(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
792 793
  int mi_size = cm->mi_cols * cm->mi_rows;

Yaowu Xu's avatar
Yaowu Xu committed
794
  cpi->mbmi_ext_base = aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base));
795
  if (!cpi->mbmi_ext_base) return 1;
Jingning Han's avatar
Jingning Han committed
796 797 798 799

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
800 801
void av1_alloc_compressor_data(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
802

Yaowu Xu's avatar
Yaowu Xu committed
803
  av1_alloc_context_buffers(cm, cm->width, cm->height);
Jingning Han's avatar
Jingning Han committed
804 805 806

  alloc_context_buffers_ext(cpi);

Yaowu Xu's avatar
Yaowu Xu committed
807
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
808 809 810 811

  {
    unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
    CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xu's avatar
Yaowu Xu committed
812
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
813
#if CONFIG_ANS
Yaowu Xu's avatar
Yaowu Xu committed
814
    av1_buf_ans_alloc(&cpi->buf_ans, cm, tokens);
815
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
816 817
  }

Yaowu Xu's avatar
Yaowu Xu committed
818
  av1_setup_pc_tree(&cpi->common, &cpi->td);
Jingning Han's avatar
Jingning Han committed
819 820
}

Yaowu Xu's avatar
Yaowu Xu committed
821
void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Jingning Han's avatar
Jingning Han committed
822
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
Yaowu Xu's avatar
Yaowu Xu committed
823
  av1_rc_update_framerate(cpi);
Jingning Han's avatar
Jingning Han committed
824 825
}

Yaowu Xu's avatar
Yaowu Xu committed
826 827
static void set_tile_info(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
828

829
#if CONFIG_EXT_TILE
830
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
831
  if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
832
    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
833
    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
834
    cm->tile_width <<= MAX_MIB_SIZE_LOG2;
835
    cm->tile_height <<= MAX_MIB_SIZE_LOG2;
836
  } else {
837
    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
838
    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
839
    cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
840 841
    cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
  }
842
#else
843
  cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
844
  cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
845
  cm->tile_width <<= MAX_MIB_SIZE_LOG2;
846 847
  cm->tile_height <<= MAX_MIB_SIZE_LOG2;
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
848

Yaowu Xu's avatar
Yaowu Xu committed
849 850
  cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
  cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
851

852 853 854
  assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
  assert(cm->tile_height >> MAX_MIB_SIZE <= 32);

855 856
  // Get the number of tiles
  cm->tile_cols = 1;
857
  while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
858 859

  cm->tile_rows = 1;
860
  while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
861
#else
Jingning Han's avatar
Jingning Han committed
862
  int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xu's avatar
Yaowu Xu committed
863
  av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Jingning Han's avatar
Jingning Han committed
864

865 866
  cm->log2_tile_cols =
      clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
Yunqing Wang's avatar
Yunqing Wang committed
867
  cm->log2_tile_rows = cpi->oxcf.tile_rows;
868 869 870 871

  cm->tile_cols = 1 << cm->log2_tile_cols;
  cm->tile_rows = 1 << cm->log2_tile_rows;

872 873 874 875 876 877
  cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
  cm->tile_width >>= cm->log2_tile_cols;
  cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
  cm->tile_height >>= cm->log2_tile_rows;

  // round to integer multiples of max superblock size
878
  cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
879
  cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
880
#endif  // CONFIG_EXT_TILE
Jingning Han's avatar
Jingning Han committed
881 882
}

Yaowu Xu's avatar
Yaowu Xu committed
883 884
static void update_frame_size(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
885 886
  MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;

Yaowu Xu's avatar
Yaowu Xu committed
887 888 889
  av1_set_mb_mi(cm, cm->width, cm->height);
  av1_init_context_buffers(cm);
  av1_init_macroblockd(cm, xd, NULL);
Jingning Han's avatar
Jingning Han committed
890 891 892
  memset(cpi->mbmi_ext_base, 0,
         cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));

893
  set_tile_info(cpi);
Jingning Han's avatar
Jingning Han committed
894 895
}

Yaowu Xu's avatar
Yaowu Xu committed
896
static void init_buffer_indices(AV1_COMP *cpi) {
897
#if CONFIG_EXT_REFS
898 899 900 901
  int fb_idx;
  for (fb_idx = 0; fb_idx < LAST_REF_FRAMES; ++fb_idx)
    cpi->lst_fb_idxes[fb_idx] = fb_idx;
  cpi->gld_fb_idx = LAST_REF_FRAMES;
902 903
  cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
  cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
904 905
  for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
    cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
906
#else
907
  cpi->lst_fb_idx = 0;
Jingning Han's avatar
Jingning Han committed
908 909
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
910
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
911 912
}

Yaowu Xu's avatar
Yaowu Xu committed
913 914
static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
915 916 917 918 919 920

  cpi->oxcf = *oxcf;
  cpi->framerate = oxcf->init_framerate;

  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
Yaowu Xu's avatar
Yaowu Xu committed
921
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
922 923 924
  cm->use_highbitdepth = oxcf->use_highbitdepth;
#endif
  cm->color_space = oxcf->color_space;
925
  cm->color_range = oxcf->color_range;
Jingning Han's avatar
Jingning Han committed
926 927 928

  cm->width = oxcf->width;
  cm->height = oxcf->height;
Yaowu Xu's avatar
Yaowu Xu committed
929
  av1_alloc_compressor_data(cpi);
Jingning Han's avatar
Jingning Han committed
930 931 932 933 934

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

  // change includes all joint functionality
Yaowu Xu's avatar
Yaowu Xu committed
935
  av1_change_config(cpi, oxcf);
Jingning Han's avatar
Jingning Han committed
936 937 938 939 940 941 942 943

  cpi->static_mb_pct = 0;
  cpi->ref_frame_flags = 0;

  init_buffer_indices(cpi);
}

static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xu's avatar
Yaowu Xu committed
944
                                const AV1EncoderConfig *oxcf) {
Jingning Han's avatar
Jingning Han committed
945 946 947 948 949 950
  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;
951 952 953 954
  rc->optimal_buffer_level =
      (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
  rc->maximum_buffer_size =
      (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
Jingning Han's avatar
Jingning Han committed
955 956
}

Yaowu Xu's avatar
Yaowu Xu committed
957
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
958
#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994