encoder.c 286 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
4 5 6 7 8 9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10 11
 */

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

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

18
#include "av1/common/alloccommon.h"
19
#include "av1/common/cdef.h"
20 21 22 23
#include "av1/common/filter.h"
#include "av1/common/idct.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
24
#include "av1/common/resize.h"
25
#include "av1/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
26

27 28 29 30
#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/aq_variance.h"
#include "av1/encoder/bitstream.h"
Todd Nguyen's avatar
Todd Nguyen committed
31 32 33
#if CONFIG_BGSPRITE
#include "av1/encoder/bgsprite.h"
#endif  // CONFIG_BGSPRITE
34 35 36 37
#include "av1/encoder/context_tree.h"
#include "av1/encoder/encodeframe.h"
#include "av1/encoder/encodemv.h"
#include "av1/encoder/encoder.h"
38 39 40
#if CONFIG_LV_MAP
#include "av1/encoder/encodetxb.h"
#endif
41 42
#include "av1/encoder/ethread.h"
#include "av1/encoder/firstpass.h"
43 44 45
#if CONFIG_HASH_ME
#include "av1/encoder/hash_motion.h"
#endif
46 47
#include "av1/encoder/mbgraph.h"
#include "av1/encoder/picklpf.h"
48
#if CONFIG_LOOP_RESTORATION
49
#include "av1/encoder/pickrst.h"
50
#endif  // CONFIG_LOOP_RESTORATION
51
#include "av1/encoder/random.h"
52 53 54 55 56
#include "av1/encoder/ratectrl.h"
#include "av1/encoder/rd.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
57

Yaowu Xu's avatar
Yaowu Xu committed
58 59 60
#include "./av1_rtcd.h"
#include "./aom_dsp_rtcd.h"
#include "./aom_scale_rtcd.h"
61
#include "aom_dsp/psnr.h"
62
#if CONFIG_INTERNAL_STATS
63
#include "aom_dsp/ssim.h"
64
#endif
Yaowu Xu's avatar
Yaowu Xu committed
65 66
#include "aom_dsp/aom_dsp_common.h"
#include "aom_dsp/aom_filter.h"
Jingning Han's avatar
Jingning Han committed
67
#include "aom_ports/aom_timer.h"
68 69
#include "aom_ports/mem.h"
#include "aom_ports/system_state.h"
Yaowu Xu's avatar
Yaowu Xu committed
70
#include "aom_scale/aom_scale.h"
Angie Chiang's avatar
Angie Chiang committed
71
#if CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
72
#include "aom_util/debug_util.h"
Angie Chiang's avatar
Angie Chiang committed
73
#endif  // CONFIG_BITSTREAM_DEBUG || CONFIG_MISMATCH_DEBUG
74

75 76
#if CONFIG_ENTROPY_STATS
FRAME_COUNTS aggregate_fc;
77 78
// Aggregate frame counts per frame context type
FRAME_COUNTS aggregate_fc_per_type[FRAME_CONTEXTS];
79 80
#endif  // CONFIG_ENTROPY_STATS

Jingning Han's avatar
Jingning Han committed
81 82 83
#define AM_SEGMENT_ID_INACTIVE 7
#define AM_SEGMENT_ID_ACTIVE 0

84 85 86 87 88 89
#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.
90

Jingning Han's avatar
Jingning Han committed
91 92 93 94 95 96
// #define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_SKINMAP
FILE *yuv_skinmap_file = NULL;
#endif
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
97
#define FILE_NAME_LEN 100
Jingning Han's avatar
Jingning Han committed
98 99 100 101 102 103 104 105
#endif

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

106 107 108 109
#if CONFIG_INTERNAL_STATS
typedef enum { Y, U, V, ALL } STAT_TYPE;
#endif  // CONFIG_INTERNAL_STATS

Yaowu Xu's avatar
Yaowu Xu committed
110
static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Jingning Han's avatar
Jingning Han committed
111 112 113 114 115 116 117 118 119 120 121 122
  switch (mode) {
    case NORMAL:
      *hr = 1;
      *hs = 1;
      break;
    case FOURFIVE:
      *hr = 4;
      *hs = 5;
      break;
    case THREEFIVE:
      *hr = 3;
      *hs = 5;
123
      break;
Jingning Han's avatar
Jingning Han committed
124 125 126
    case ONETWO:
      *hr = 1;
      *hs = 2;
127
      break;
Jingning Han's avatar
Jingning Han committed
128 129 130
    default:
      *hr = 1;
      *hs = 1;
131
      assert(0);
Jingning Han's avatar
Jingning Han committed
132 133 134 135 136 137
      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
138
static void suppress_active_map(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
139 140 141 142 143 144 145 146
  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
147
static void apply_active_map(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
  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
164 165
      av1_enable_segmentation(seg);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
#if CONFIG_LOOPFILTER_LEVEL
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V);

      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H,
                      -MAX_LOOP_FILTER);
      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V,
                      -MAX_LOOP_FILTER);
      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U,
                      -MAX_LOOP_FILTER);
      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V,
                      -MAX_LOOP_FILTER);
#else
Yaowu Xu's avatar
Yaowu Xu committed
181
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
182
      // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
183
      // filter level being zero.
Yaowu Xu's avatar
Yaowu Xu committed
184 185
      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
                      -MAX_LOOP_FILTER);
186
#endif  // CONFIG_LOOPFILTER_LEVEL
Jingning Han's avatar
Jingning Han committed
187
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
188
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
189 190 191 192 193 194
#if CONFIG_LOOPFILTER_LEVEL
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_H);
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_Y_V);
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_U);
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF_V);
#else
Yaowu Xu's avatar
Yaowu Xu committed
195
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
196
#endif  // CONFIG_LOOPFILTER_LEVEL
Jingning Han's avatar
Jingning Han committed
197 198 199 200 201 202 203 204 205
      if (seg->enabled) {
        seg->update_data = 1;
        seg->update_map = 1;
      }
    }
    cpi->active_map.update = 0;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
206 207
int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
208 209 210 211
  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;
212 213
    const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
    const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
Jingning Han's avatar
Jingning Han committed
214 215 216 217 218 219
    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] =
220
              new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)]
Jingning Han's avatar
Jingning Han committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234
                  ? 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
235 236
int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
237 238
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
      new_map_16x16) {
239
    unsigned char *const seg_map_8x8 = cpi->segmentation_map;
Jingning Han's avatar
Jingning Han committed
240 241
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
242 243 244
    const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
    const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;

Jingning Han's avatar
Jingning Han committed
245 246 247 248 249 250 251
    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
252
          new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)] |=
Jingning Han's avatar
Jingning Han committed
253 254 255 256 257 258 259 260 261 262
              seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
        }
      }
    }
    return 0;
  } else {
    return -1;
  }
}

RogerZhou's avatar
RogerZhou committed
263 264 265
static void set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv
#if CONFIG_AMVR
                                  ,
266
                                  int cur_frame_force_integer_mv
RogerZhou's avatar
RogerZhou committed
267 268
#endif
                                  ) {
269 270 271
  MACROBLOCK *const mb = &cpi->td.mb;
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;

RogerZhou's avatar
RogerZhou committed
272
#if CONFIG_AMVR
273 274
  const int copy_hp =
      cpi->common.allow_high_precision_mv && cur_frame_force_integer_mv == 0;
RogerZhou's avatar
RogerZhou committed
275
#else
276
  const int copy_hp = cpi->common.allow_high_precision_mv;
RogerZhou's avatar
RogerZhou committed
277
#endif
278 279 280
  int *(*src)[2] = copy_hp ? mb->nmvcost_hp : mb->nmvcost;
  for (int i = 0; i < NMV_CONTEXTS; ++i) {
    mb->mv_cost_stack[i] = src[i];
281 282 283
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
284
static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
285
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
286
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
287 288
    return BLOCK_64X64;

Yaowu Xu's avatar
Yaowu Xu committed
289
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
290 291
    return BLOCK_128X128;

Yaowu Xu's avatar
Yaowu Xu committed
292
  assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
293

294 295 296
#if !CONFIG_MAX_TILE
  // for the max_tile experiment there is no common tile_width, tile_height
  // max_tile assumes tile dimensions are in superblocks (not 64x64 units)
297 298 299 300
  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));
301
#endif
302 303 304 305 306 307 308 309 310

  // 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
311 312
static void setup_frame(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
313 314 315 316 317 318
  // 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
319
    av1_setup_past_independence(cm);
Jingning Han's avatar
Jingning Han committed
320
  } else {
321 322 323 324
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
// Just use frame context from first signaled reference frame.
// This will always be LAST_FRAME for now.
#else
325
    const GF_GROUP *gf_group = &cpi->twopass.gf_group;
Zoe Liu's avatar
Zoe Liu committed
326
    if (gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE)
327 328 329
      cm->frame_context_idx = EXT_ARF_FRAME;
    else if (cpi->refresh_alt_ref_frame)
      cm->frame_context_idx = ARF_FRAME;
330 331 332 333 334 335 336 337
    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;
    else if (cpi->refresh_bwd_ref_frame)
      cm->frame_context_idx = BRF_FRAME;
    else
      cm->frame_context_idx = REGULAR_FRAME;
338
#endif  // CONFIG_NO_FRAME_CONTEXT_SIGNALING
Jingning Han's avatar
Jingning Han committed
339 340 341
  }

  if (cm->frame_type == KEY_FRAME) {
Yunqing Wang's avatar
Yunqing Wang committed
342
    cpi->refresh_golden_frame = 1;
Jingning Han's avatar
Jingning Han committed
343
    cpi->refresh_alt_ref_frame = 1;
Yaowu Xu's avatar
Yaowu Xu committed
344
    av1_zero(cpi->interp_filter_selected);
345
    set_sb_size(cm, select_sb_size(cpi));
346 347 348
#if CONFIG_REFERENCE_BUFFER
    set_use_reference_buffer(cm, 0);
#endif  // CONFIG_REFERENCE_BUFFER
349 350 351 352 353
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
    cm->pre_fc = &cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
#else
    cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
#endif  // CONFIG_NO_FRAME_CONTEXT_SIGNALING
Jingning Han's avatar
Jingning Han committed
354
  } else {
355
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
356
    if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
357
      *cm->fc = cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
358
      cm->pre_fc = &cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
359
    } else {
360
      assert(cm->frame_refs[0].idx >= 0);
361
      *cm->fc = cm->frame_contexts[cm->frame_refs[0].idx];
362
      cm->pre_fc = &cm->frame_contexts[cm->frame_refs[0].idx];
363 364
    }
#else
Jingning Han's avatar
Jingning Han committed
365
    *cm->fc = cm->frame_contexts[cm->frame_context_idx];
366
    cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
367
#endif  // CONFIG_NO_FRAME_CONTEXT_SIGNALING
Yaowu Xu's avatar
Yaowu Xu committed
368
    av1_zero(cpi->interp_filter_selected[0]);
Jingning Han's avatar
Jingning Han committed
369
  }
370
#if !CONFIG_EXT_COMP_REFS  // No change to bitstream
371 372 373 374
  if (cpi->sf.recode_loop == DISALLOW_RECODE) {
    cpi->refresh_bwd_ref_frame = cpi->refresh_last_frame;
    cpi->rc.is_bipred_frame = 1;
  }
375
#endif  // !CONFIG_EXT_COMP_REFS
376

Geza Lore's avatar
Geza Lore committed
377
  cpi->vaq_refresh = 0;
Jingning Han's avatar
Jingning Han committed
378 379
}

380
static void enc_setup_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
  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));
}

397
static int enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
Yaowu Xu's avatar
Yaowu Xu committed
398
  cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
399
  if (!cm->mip) return 1;
Yaowu Xu's avatar
Yaowu Xu committed
400
  cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
401
  if (!cm->prev_mip) return 1;
Jingning Han's avatar
Jingning Han committed
402 403
  cm->mi_alloc_size = mi_size;

Yaowu Xu's avatar
Yaowu Xu committed
404
  cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
405 406
  if (!cm->mi_grid_base) return 1;
  cm->prev_mi_grid_base =
Yaowu Xu's avatar
Yaowu Xu committed
407
      (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
408
  if (!cm->prev_mi_grid_base) return 1;
Jingning Han's avatar
Jingning Han committed
409 410 411 412

  return 0;
}

413
static void enc_free_mi(AV1_COMMON *cm) {
Yaowu Xu's avatar
Yaowu Xu committed
414
  aom_free(cm->mip);
Jingning Han's avatar
Jingning Han committed
415
  cm->mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
416
  aom_free(cm->prev_mip);
Jingning Han's avatar
Jingning Han committed
417
  cm->prev_mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
418
  aom_free(cm->mi_grid_base);
Jingning Han's avatar
Jingning Han committed
419
  cm->mi_grid_base = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
420
  aom_free(cm->prev_mi_grid_base);
Jingning Han's avatar
Jingning Han committed
421
  cm->prev_mi_grid_base = NULL;
422
  cm->mi_alloc_size = 0;
Jingning Han's avatar
Jingning Han committed
423 424
}

425
static void swap_mi_and_prev_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
  // 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
442
void av1_initialize_enc(void) {
Jingning Han's avatar
Jingning Han committed
443 444 445
  static volatile int init_done = 0;

  if (!init_done) {
Yaowu Xu's avatar
Yaowu Xu committed
446 447 448 449 450
    av1_rtcd();
    aom_dsp_rtcd();
    aom_scale_rtcd();
    av1_init_intra_predictors();
    av1_init_me_luts();
451
#if !CONFIG_XIPHRC
Yaowu Xu's avatar
Yaowu Xu committed
452
    av1_rc_init_minq_luts();
453
#endif
Yaowu Xu's avatar
Yaowu Xu committed
454
    av1_init_wedge_masks();
Jingning Han's avatar
Jingning Han committed
455 456 457 458
    init_done = 1;
  }
}

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474
static void dealloc_context_buffers_ext(AV1_COMP *cpi) {
  if (cpi->mbmi_ext_base) {
    aom_free(cpi->mbmi_ext_base);
    cpi->mbmi_ext_base = NULL;
  }
}

static void alloc_context_buffers_ext(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  int mi_size = cm->mi_cols * cm->mi_rows;

  dealloc_context_buffers_ext(cpi);
  CHECK_MEM_ERROR(cm, cpi->mbmi_ext_base,
                  aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base)));
}

Yaowu Xu's avatar
Yaowu Xu committed
475 476
static void dealloc_compressor_data(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
477

478
  dealloc_context_buffers_ext(cpi);
Jingning Han's avatar
Jingning Han committed
479

Yaowu Xu's avatar
Yaowu Xu committed
480
  aom_free(cpi->tile_data);
Jingning Han's avatar
Jingning Han committed
481 482 483
  cpi->tile_data = NULL;

  // Delete sementation map
Yaowu Xu's avatar
Yaowu Xu committed
484
  aom_free(cpi->segmentation_map);
Jingning Han's avatar
Jingning Han committed
485 486
  cpi->segmentation_map = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
487
  av1_cyclic_refresh_free(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
488 489
  cpi->cyclic_refresh = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
490
  aom_free(cpi->active_map.map);
Jingning Han's avatar
Jingning Han committed
491 492
  cpi->active_map.map = NULL;

493 494 495 496 497 498 499 500 501 502 503 504
  aom_free(cpi->td.mb.above_pred_buf);
  cpi->td.mb.above_pred_buf = NULL;

  aom_free(cpi->td.mb.left_pred_buf);
  cpi->td.mb.left_pred_buf = NULL;

  aom_free(cpi->td.mb.wsrc_buf);
  cpi->td.mb.wsrc_buf = NULL;

  aom_free(cpi->td.mb.mask_buf);
  cpi->td.mb.mask_buf = NULL;

Jingning Han's avatar
Jingning Han committed
505 506 507 508 509
#if CONFIG_MFMV
  aom_free(cm->tpl_mvs);
  cm->tpl_mvs = NULL;
#endif

Yaowu Xu's avatar
Yaowu Xu committed
510
  av1_free_ref_frame_buffers(cm->buffer_pool);
511 512 513
#if CONFIG_LV_MAP
  av1_free_txb_buf(cpi);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
514
  av1_free_context_buffers(cm);
Jingning Han's avatar
Jingning Han committed
515

Yaowu Xu's avatar
Yaowu Xu committed
516
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
517
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
518
  av1_free_restoration_buffers(cm);
519
  aom_free_frame_buffer(&cpi->trial_frame_rst);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
520
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
521 522 523 524
  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
525

Yaowu Xu's avatar
Yaowu Xu committed
526
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
527 528
  cpi->tile_tok[0][0] = 0;

Yaowu Xu's avatar
Yaowu Xu committed
529
  av1_free_pc_tree(&cpi->td);
530

531
  aom_free(cpi->td.mb.palette_buffer);
Jingning Han's avatar
Jingning Han committed
532 533
}

Yaowu Xu's avatar
Yaowu Xu committed
534
static void save_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
535
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
536
  AV1_COMMON *cm = &cpi->common;
537
  int i;
Jingning Han's avatar
Jingning Han committed
538

Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
539 540 541 542
  // Stores a snapshot of key state variables which can subsequently be
  // 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
  // quantizer value is adjusted between loop iterations.
543 544 545 546 547 548
  for (i = 0; i < NMV_CONTEXTS; ++i) {
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
    av1_copy(cc->nmv_costs, cpi->nmv_costs);
    av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
  }

Yaowu Xu's avatar
Yaowu Xu committed
549 550
  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
551 552 553 554

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

Yaowu Xu's avatar
Yaowu Xu committed
555
static void restore_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
556
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
557
  AV1_COMMON *cm = &cpi->common;
558
  int i;
Jingning Han's avatar
Jingning Han committed
559

Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
560 561
  // Restore key state variables to the snapshot state stored in the
  // previous call to av1_save_coding_context.
562 563 564 565 566 567
  for (i = 0; i < NMV_CONTEXTS; ++i) {
    av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
    av1_copy(cpi->nmv_costs, cc->nmv_costs);
    av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
  }

Yaowu Xu's avatar
Yaowu Xu committed
568 569
  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
570 571 572 573

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

Yaowu Xu's avatar
Yaowu Xu committed
574 575
static void configure_static_seg_features(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
  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
591
    av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
592 593

    // Clear down the segment features.
Yaowu Xu's avatar
Yaowu Xu committed
594
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
595 596 597 598 599 600 601 602 603
  } 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
604 605
    av1_disable_segmentation(seg);
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
606 607 608

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

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

617
      qi_delta =
Yaowu Xu's avatar
Yaowu Xu committed
618 619
          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);
620 621 622 623 624 625 626 627 628 629 630
#if CONFIG_LOOPFILTER_LEVEL
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_H, -2);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_V, -2);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_U, -2);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_V, -2);

      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_H);
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_V);
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_U);
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_V);
#else
Yaowu Xu's avatar
Yaowu Xu committed
631
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
632 633
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
#endif  // CONFIG_LOOPFILTER_LEVEL
Jingning Han's avatar
Jingning Han committed
634

Yaowu Xu's avatar
Yaowu Xu committed
635
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Jingning Han's avatar
Jingning Han committed
636 637 638 639 640 641 642 643 644 645 646
    }
  } 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;

Yaowu Xu's avatar
Yaowu Xu committed
647 648 649 650
        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
651

652 653 654 655 656 657 658 659 660 661 662
#if CONFIG_LOOPFILTER_LEVEL
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_H, -2);
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_Y_V, -2);
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_U, -2);
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF_V, -2);

        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_H);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_Y_V);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_U);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF_V);
#else
Yaowu Xu's avatar
Yaowu Xu committed
663 664
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
665
#endif  // CONFIG_LOOPFILTER_LEVEL
Jingning Han's avatar
Jingning Han committed
666 667 668

        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xu's avatar
Yaowu Xu committed
669 670 671
          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
672 673 674 675 676
        }
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

Yaowu Xu's avatar
Yaowu Xu committed
677
        av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
678 679 680 681 682 683

        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
684
        av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
685 686 687 688 689 690 691
      }
    } 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
692 693
      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
694 695

      // All mbs should use ALTREF_FRAME
Yaowu Xu's avatar
Yaowu Xu committed
696 697 698 699
      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
700 701 702

      // Skip all MBs if high Q (0,0 mv and skip coeffs)
      if (high_q) {
Yaowu Xu's avatar
Yaowu Xu committed
703 704
        av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
705 706 707 708 709 710 711 712 713 714 715 716 717
      }
      // 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
718 719
static void update_reference_segmentation_map(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
720
  MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
Soo-Chul Han's avatar
Soo-Chul Han committed
721 722 723
#if CONFIG_SEGMENT_PRED_LAST
  uint8_t *cache_ptr = cm->current_frame_seg_map;
#else
Jingning Han's avatar
Jingning Han committed
724
  uint8_t *cache_ptr = cm->last_frame_seg_map;
Soo-Chul Han's avatar
Soo-Chul Han committed
725
#endif
Jingning Han's avatar
Jingning Han committed
726 727 728 729 730 731 732 733 734 735 736 737
  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
738 739 740
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
741 742

  if (!cpi->lookahead)
743 744 745
    cpi->lookahead = av1_lookahead_init(
        oxcf->width, oxcf->height, cm->subsampling_x, cm->subsampling_y,
        cm->use_highbitdepth, oxcf->lag_in_frames);
Jingning Han's avatar
Jingning Han committed
746
  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
747
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
748 749 750
                       "Failed to allocate lag buffers");

  // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xu's avatar
Yaowu Xu committed
751
  if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Jingning Han's avatar
Jingning Han committed
752
                               cm->subsampling_x, cm->subsampling_y,
753 754
                               cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
                               cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
755
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
756 757 758
                       "Failed to allocate altref buffer");
}

Yaowu Xu's avatar
Yaowu Xu committed
759 760 761
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
762
                               cm->subsampling_x, cm->subsampling_y,
763 764
                               cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
                               cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
765
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
766 767
                       "Failed to allocate last frame buffer");

Debargha Mukherjee's avatar
Debargha Mukherjee committed
768
#if CONFIG_LOOP_RESTORATION
769 770
  if (aom_realloc_frame_buffer(
          &cpi->trial_frame_rst,
771
#if CONFIG_HORZONLY_FRAME_SUPERRES
772 773 774
          cm->superres_upscaled_width, cm->superres_upscaled_height,
#else
          cm->width, cm->height,
775
#endif  // CONFIG_HORZONLY_FRAME_SUPERRES
776
          cm->subsampling_x, cm->subsampling_y, cm->use_highbitdepth,
777
          AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL))
778 779
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
                       "Failed to allocate trial restored frame buffer");
Debargha Mukherjee's avatar
Debargha Mukherjee committed
780 781
#endif  // CONFIG_LOOP_RESTORATION

Yaowu Xu's avatar
Yaowu Xu committed
782
  if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
783
                               cm->subsampling_x, cm->subsampling_y,
784 785
                               cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
                               cm->byte_alignment, 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
                       "Failed to allocate scaled source buffer");

Yaowu Xu's avatar
Yaowu Xu committed
789
  if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
790
                               cm->subsampling_x, cm->subsampling_y,
791 792
                               cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
                               cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
793
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
794 795 796
                       "Failed to allocate scaled last source buffer");
}

797
static void alloc_compressor_data(AV1_COMP *cpi) {
Yaowu Xu's avatar
Yaowu Xu committed
798
  AV1_COMMON *cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
799

Yaowu Xu's avatar
Yaowu Xu committed
800
  av1_alloc_context_buffers(cm, cm->width, cm->height);
Jingning Han's avatar
Jingning Han committed
801

802 803 804 805
#if CONFIG_LV_MAP
  av1_alloc_txb_buf(cpi);
#endif

Jingning Han's avatar
Jingning Han committed
806 807
  alloc_context_buffers_ext(cpi);

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

  {
811 812
    unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols,
                                          MAX_SB_SIZE_LOG2, av1_num_planes(cm));
Jingning Han's avatar
Jingning Han committed
813
    CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xu's avatar
Yaowu Xu committed
814
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
Jingning Han's avatar
Jingning Han committed
815 816
  }

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

Yaowu Xu's avatar
Yaowu Xu committed
820
void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Jingning Han's avatar
Jingning Han committed
821
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
822 823 824 825 826
#if CONFIG_XIPHRC
  if (!cpi->od_rc.cur_frame) return;
  cpi->od_rc.framerate = cpi->framerate;
  od_enc_rc_resize(&cpi->od_rc);
#else
827
  av1_rc_update_framerate(cpi, cpi->common.width, cpi->common.height);
828
#endif
Jingning Han's avatar
Jingning Han committed
829 830
}

831 832 833 834
#if CONFIG_MAX_TILE

static void set_tile_info_max_tile(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
835
  int i, start_sb;
836 837 838 839

  av1_get_tile_limits(cm);

  // configure tile columns
840
  if (cpi->oxcf.tile_width_count == 0 || cpi->oxcf.tile_height_count == 0) {
841
    cm->uniform_tile_spacing_flag = 1;
842 843
    cm->log2_tile_cols = AOMMAX(cpi->oxcf.tile_columns, cm->min_log2_tile_cols);
    cm->log2_tile_cols = AOMMIN(cm->log2_tile_cols, cm->max_log2_tile_cols);
844
  } else {
845 846
    int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->mib_size_log2);
    int sb_cols = mi_cols >> cm->mib_size_log2;
847
    int size_sb, j = 0;
848 849 850
    cm->uniform_tile_spacing_flag = 0;
    for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
      cm->tile_col_start_sb[i] = start_sb;
851 852 853
      size_sb = cpi->oxcf.tile_widths[j++];
      if (j >= cpi->oxcf.tile_width_count) j = 0;
      start_sb += AOMMIN(size_sb, MAX_TILE_WIDTH_SB);
854 855 856
    }
    cm->tile_cols = i;
    cm->tile_col_start_sb[i] = sb_cols;
857 858 859 860 861 862 863
  }
  av1_calculate_tile_cols(cm);

  // configure tile rows
  if (cm->uniform_tile_spacing_flag) {
    cm->log2_tile_rows = AOMMAX(cpi->oxcf.tile_rows, cm->min_log2_tile_rows);
    cm->log2_tile_rows = AOMMIN(cm->log2_tile_rows, cm->max_log2_tile_rows);
864
  } else {
865 866
    int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->mib_size_log2);
    int sb_rows = mi_rows >> cm->mib_size_log2;
867
    int size_sb, j = 0;
868 869
    for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
      cm->tile_row_start_sb[i] = start_sb;
870 871 872
      size_sb = cpi->oxcf.tile_heights[j++];
      if (j >= cpi->oxcf.tile_height_count) j = 0;
      start_sb += AOMMIN(size_sb, cm->max_tile_height_sb);
873 874 875
    }
    cm->tile_rows = i;
    cm->tile_row_start_sb[i] = sb_rows;
876 877 878 879 880 881
  }
  av1_calculate_tile_rows(cm);
}

#endif

Yaowu Xu's avatar
Yaowu Xu committed
882 883
static void set_tile_info(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
884
  (void)cm;
885
#if CONFIG_DEPENDENT_HORZTILES
886 887 888
  int tile_row, tile_col, num_tiles_in_tg;
  int tg_row_start, tg_col_start;
#endif
889
#if CONFIG_EXT_TILE
890
  if (cpi->oxcf.large_scale_tile) {
891
#if CONFIG_EXT_PARTITION
892 893 894 895 896 897 898 899 900 901 902 903
    if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
      cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
      cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
      cm->tile_width <<= MAX_MIB_SIZE_LOG2;
      cm->tile_height <<= MAX_MIB_SIZE_LOG2;
    } else {
      cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
      cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
      cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
      cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
    }
#else
904
    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
905
    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
906 907
    cm->tile_width <<= MAX_MIB_SIZE_LOG2;
    cm->tile_height <<= MAX_MIB_SIZE_LOG2;
908
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
909

910 911
    cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
    cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
912

Yaowu Xu's avatar
Yaowu Xu committed
913 914
    assert(cm->tile_width >> MAX_MIB_SIZE_LOG2 <= 32);
    assert(cm->tile_height >> MAX_MIB_SIZE_LOG2 <= 32);
915

916 917 918
    // Get the number of tiles
    cm->tile_cols = 1;
    while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
919

920 921
    cm->tile_rows = 1;
    while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
922 923 924 925 926 927 928 929 930 931 932
#if CONFIG_MAX_TILE
    int i;
    for (i = 0; i <= cm->tile_cols; i++) {
      cm->tile_col_start_sb[i] =
          ((i * cm->tile_width - 1) >> cm->mib_size_log2) + 1;
    }
    for (i = 0; i <= cm->tile_rows; i++) {
      cm->tile_row_start_sb[i] =
          ((i * cm->tile_height - 1) >> cm->mib_size_log2) + 1;
    }
#endif  // CONFIG_MAX_TILE
933 934
  } else {
#endif  // CONFIG_EXT_TILE
Jingning Han's avatar
Jingning Han committed
935

936 937
#if CONFIG_MAX_TILE
    set_tile_info_max_tile(cpi);
938
    (void)cm;
939 940 941 942 943 944 945
#else
  int min_log2_tile_cols, max_log2_tile_cols;
  av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);

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

947 948 949 950
  cm->tile_width =
      get_tile_size(cm->mi_cols, cm->log2_tile_cols, &cm->tile_cols);
  cm->tile_height =
      get_tile_size(cm->mi_rows, cm->log2_tile_rows, &cm->tile_rows);
951
#endif  // CONFIG_MAX_TILE
952 953
#if CONFIG_EXT_TILE
  }
954
#endif  // CONFIG_EXT_TILE
955

956 957
#if CONFIG_DEPENDENT_HORZTILES
  cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles;
958
#if CONFIG_EXT_TILE
959 960 961
  if (cm->large_scale_tile) {
    // May not needed since cpi->oxcf.dependent_horz_tiles is already adjusted.
    cm->dependent_horz_tiles = 0;
962
  } else {
963 964 965
#endif  // CONFIG_EXT_TILE
    if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0;
#if CONFIG_EXT_TILE
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
#endif  // CONFIG_EXT_TILE

#if CONFIG_EXT_TILE
  if (!cm->large_scale_tile) {
#endif  // CONFIG_EXT_TILE
    if (cpi->oxcf.mtu == 0) {
      cm->num_tg = cpi->oxcf.num_tile_groups;
    } else {
      // Use a default value for the purposes of weighting costs in probability
      // updates
      cm->num_tg = DEFAULT_MAX_NUM_TG;
    }
    num_tiles_in_tg =
        (cm->tile_cols * cm->tile_rows + cm->num_tg - 1) / cm->num_tg;
    tg_row_start = 0;
    tg_col_start = 0;
    for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
      for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
        if ((tile_row * cm->tile_cols + tile_col) % num_tiles_in_tg == 0) {
          tg_row_start = tile_row;
          tg_col_start = tile_col;
        }
        cm->tile_group_start_row[tile_row][tile_col] = tg_row_start;
        cm->tile_group_start_col[tile_row][tile_col] = tg_col_start;
991 992
      }
    }
993
#if CONFIG_EXT_TILE
994
  }
995
#endif  // CONFIG_EXT_TILE
996
#endif
997

998
#if CONFIG_LOOPFILTERING_ACROSS_TILES
999 1000 1001 1002 1003 1004
#if CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
  cm->loop_filter_across_tiles_v_enabled =
      cpi->oxcf.loop_filter_across_tiles_v_enabled;
  cm->loop_filter_across_tiles_h_enabled =
      cpi->oxcf.loop_filter_across_tiles_h_enabled;
#else
1005 1006
  cm->loop_filter_across_tiles_enabled =
      cpi->oxcf.loop_filter_across_tiles_enabled;
1007
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES_EXT
1008
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
Jingning Han's avatar
Jingning Han committed
1009 1010
}

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

Yaowu Xu's avatar
Yaowu Xu committed
1015 1016
  av1_set_mb_mi(cm, cm->width, cm->height);
  av1_init_context_buffers(cm);
1017
  av1_init_macroblockd(cm, xd, NULL);
Jingning Han's avatar
Jingning Han committed
1018 1019
  memset(cpi->mbmi_ext_base, 0,
         cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
1020
  set_tile_info(cpi);
Jingning Han's avatar
Jingning Han committed
1021 1022
}

Yaowu Xu's avatar
Yaowu Xu committed
1023
static void init_buffer_indices(AV1_COMP *cpi) {
1024 1025 1026 1027
  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;
1028
  cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
Zoe Liu's avatar
Zoe Liu committed
1029 1030
  cpi->alt2_fb_idx = LAST_REF_FRAMES + 2;
  cpi->alt_fb_idx = LAST_REF_FRAMES + 3;
1031
  cpi->ext_fb_idx = LAST_REF_FRAMES + 4;
1032 1033
  for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
    cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
RogerZhou's avatar
RogerZhou committed
1034 1035 1036 1037 1038
#if CONFIG_AMVR
  cpi->rate_index = 0;
  cpi->rate_size = 0;
  cpi->cur_poc = -1;
#endif
Jingning Han's avatar
Jingning Han committed
1039 1040
}

Yaowu Xu's avatar
Yaowu Xu committed
1041 1042
static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
1043 1044 1045 1046 1047 1048 1049

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

  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
  cm->use_highbitdepth = oxcf->use_highbitdepth;
Andrey Norkin's avatar
Andrey Norkin committed
1050 1051 1052 1053 1054
#if CONFIG_CICP
  cm->color_primaries = oxcf->color_primaries;
  cm->transfer_characteristics = oxcf->transfer_characteristics;
  cm->matrix_coefficients = oxcf->matrix_coefficients;
#else
Jingning Han's avatar
Jingning Han committed
1055
  cm->color_space = oxcf->color_space;
Andrey Norkin's avatar
Andrey Norkin committed
1056
#endif  // CONFIG_CICP
1057
#if CONFIG_COLORSPACE_HEADERS
Andrey Norkin's avatar
Andrey Norkin committed
1058
#if !CONFIG_CICP
1059
  cm->transfer_function = oxcf->transfer_function;
Andrey Norkin's avatar
Andrey Norkin committed
1060
#endif
1061 1062
  cm->chroma_sample_position = oxcf->chroma_sample_position;
#endif
1063
  cm->color_range = oxcf->color_range;
Jingning Han's avatar
Jingning Han committed
1064 1065 1066

  cm->width = oxcf->width;
  cm->height = oxcf->height;
1067
  set_sb_size(cm, select_sb_size(cpi));  // set sb size before allocations
1068
  alloc_compressor_data(cpi);
Jingning Han's avatar
Jingning Han committed
1069 1070 1071 1072 1073

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

  // change includes all joint functionality
Yaowu Xu's avatar
Yaowu Xu committed
1074
  av1_change_config(cpi, oxcf);
Jingning Han's avatar
Jingning Han committed
1075 1076 1077 1078

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

1079 1080 1081 1082
  // Reset resize pending flags
  cpi->resize_pending_width = 0;
  cpi->resize_pending_height = 0;

Jingning Han's avatar
Jingning Han committed
1083 1084 1085 1086
  init_buffer_indices(cpi);
}

static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xu's avatar
Yaowu Xu committed
1087
                                const AV1EncoderConfig *oxcf) {
Jingning Han's avatar
Jingning Han committed
1088 1089 1090 1091 1092 1093
  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;
1094 1095 1096 1097