encoder.c 208 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
#if CONFIG_CLPF
Steinar Midtskogen's avatar
Steinar Midtskogen committed
20
#include "aom/aom_image.h"
21
#include "av1/common/clpf.h"
22
#include "av1/encoder/clpf_rdo.h"
23
#endif
Yaowu Xu's avatar
Yaowu Xu committed
24
#if CONFIG_DERING
25
#include "av1/common/dering.h"
Yaowu Xu's avatar
Yaowu Xu committed
26
#endif  // CONFIG_DERING
27 28 29 30 31
#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
32

33 34 35 36
#include "av1/encoder/aq_complexity.h"
#include "av1/encoder/aq_cyclicrefresh.h"
#include "av1/encoder/aq_variance.h"
#include "av1/encoder/bitstream.h"
37
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
38
#include "aom_dsp/buf_ans.h"
39
#endif
40 41 42 43 44 45 46 47
#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"
48
#if CONFIG_LOOP_RESTORATION
49
#include "av1/encoder/pickrst.h"
50
#endif  // CONFIG_LOOP_RESTORATION
51 52 53 54 55 56
#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
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"
71
#if CONFIG_BITSTREAM_DEBUG
72
#include "aom_util/debug_util.h"
73
#endif  // CONFIG_BITSTREAM_DEBUG
74

Jingning Han's avatar
Jingning Han committed
75 76 77
#define AM_SEGMENT_ID_INACTIVE 7
#define AM_SEGMENT_ID_ACTIVE 0

78 79 80 81 82 83 84 85
#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
86 87 88 89 90 91 92 93 94
// #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;
95
#define FILE_NAME_LEN 100
Jingning Han's avatar
Jingning Han committed
96 97 98 99 100 101 102 103
#endif

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
181 182
int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
  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
208 209
int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
210 211
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
      new_map_16x16) {
212
    unsigned char *const seg_map_8x8 = cpi->segmentation_map;
Jingning Han's avatar
Jingning Han committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
    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
233
void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Jingning Han's avatar
Jingning Han committed
234 235
  MACROBLOCK *const mb = &cpi->td.mb;
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251

#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
252 253
  if (cpi->common.allow_high_precision_mv) {
    mb->mvcost = mb->nmvcost_hp;
254
    mb->mvsadcost = mb->nmvcost_hp;
Jingning Han's avatar
Jingning Han committed
255 256
  } else {
    mb->mvcost = mb->nmvcost;
257
    mb->mvsadcost = mb->nmvcost;
Jingning Han's avatar
Jingning Han committed
258
  }
259
#endif
Jingning Han's avatar
Jingning Han committed
260 261
}

Yaowu Xu's avatar
Yaowu Xu committed
262
static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
263
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
264
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
265 266
    return BLOCK_64X64;

Yaowu Xu's avatar
Yaowu Xu committed
267
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
268 269
    return BLOCK_128X128;

Yaowu Xu's avatar
Yaowu Xu committed
270
  assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
271 272 273 274 275 276 277 278 279 280 281 282 283 284

  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
285 286
static void setup_frame(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
287 288 289 290 291 292
  // 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
293
    av1_setup_past_independence(cm);
Jingning Han's avatar
Jingning Han committed
294
  } else {
295 296 297 298 299 300 301
#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
302
    if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
303
#endif  // CONFIG_EXT_REFS
304 305 306 307 308 309 310
    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;
Zoe Liu's avatar
Zoe Liu committed
311
#endif  // CONFIG_EXT_REFS
312 313
    else
      cm->frame_context_idx = REGULAR_FRAME;
Jingning Han's avatar
Jingning Han committed
314 315 316
  }

  if (cm->frame_type == KEY_FRAME) {
Yunqing Wang's avatar
Yunqing Wang committed
317
    cpi->refresh_golden_frame = 1;
Jingning Han's avatar
Jingning Han committed
318
    cpi->refresh_alt_ref_frame = 1;
Yaowu Xu's avatar
Yaowu Xu committed
319
    av1_zero(cpi->interp_filter_selected);
Jingning Han's avatar
Jingning Han committed
320 321
  } else {
    *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xu's avatar
Yaowu Xu committed
322
    av1_zero(cpi->interp_filter_selected[0]);
Jingning Han's avatar
Jingning Han committed
323
  }
324

Geza Lore's avatar
Geza Lore committed
325 326
  cpi->vaq_refresh = 0;

327
  set_sb_size(cm, select_sb_size(cpi));
Jingning Han's avatar
Jingning Han committed
328 329
}

Yaowu Xu's avatar
Yaowu Xu committed
330
static void av1_enc_setup_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
  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
348 349
static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
  cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
350
  if (!cm->mip) return 1;
Yaowu Xu's avatar
Yaowu Xu committed
351
  cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
352
  if (!cm->prev_mip) return 1;
Jingning Han's avatar
Jingning Han committed
353 354
  cm->mi_alloc_size = mi_size;

Yaowu Xu's avatar
Yaowu Xu committed
355
  cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
356 357
  if (!cm->mi_grid_base) return 1;
  cm->prev_mi_grid_base =
Yaowu Xu's avatar
Yaowu Xu committed
358
      (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
359
  if (!cm->prev_mi_grid_base) return 1;
Jingning Han's avatar
Jingning Han committed
360 361 362 363

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
364 365
static void av1_enc_free_mi(AV1_COMMON *cm) {
  aom_free(cm->mip);
Jingning Han's avatar
Jingning Han committed
366
  cm->mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
367
  aom_free(cm->prev_mip);
Jingning Han's avatar
Jingning Han committed
368
  cm->prev_mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
369
  aom_free(cm->mi_grid_base);
Jingning Han's avatar
Jingning Han committed
370
  cm->mi_grid_base = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
371
  aom_free(cm->prev_mi_grid_base);
Jingning Han's avatar
Jingning Han committed
372 373 374
  cm->prev_mi_grid_base = NULL;
}

Yaowu Xu's avatar
Yaowu Xu committed
375
static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391
  // 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
392
void av1_initialize_enc(void) {
Jingning Han's avatar
Jingning Han committed
393 394 395
  static volatile int init_done = 0;

  if (!init_done) {
Yaowu Xu's avatar
Yaowu Xu committed
396 397 398 399 400 401 402 403
    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();
404
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
405
    av1_init_wedge_masks();
406
#endif
Jingning Han's avatar
Jingning Han committed
407 408 409 410
    init_done = 1;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
411 412
static void dealloc_compressor_data(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
413
  int i;
Jingning Han's avatar
Jingning Han committed
414

Yaowu Xu's avatar
Yaowu Xu committed
415
  aom_free(cpi->mbmi_ext_base);
Jingning Han's avatar
Jingning Han committed
416 417
  cpi->mbmi_ext_base = NULL;

418 419 420 421 422 423 424 425 426 427 428 429 430 431
#if CONFIG_PVQ
  if (cpi->oxcf.pass != 1) {
    const int tile_cols = 1 << cm->log2_tile_cols;
    const int tile_rows = 1 << cm->log2_tile_rows;
    int tile_col, tile_row;

    for (tile_row = 0; tile_row < tile_rows; ++tile_row)
      for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
        TileDataEnc *tile_data =
            &cpi->tile_data[tile_row * tile_cols + tile_col];
        aom_free(tile_data->pvq_q.buf);
      }
  }
#endif
Yaowu Xu's avatar
Yaowu Xu committed
432
  aom_free(cpi->tile_data);
Jingning Han's avatar
Jingning Han committed
433 434 435
  cpi->tile_data = NULL;

  // Delete sementation map
Yaowu Xu's avatar
Yaowu Xu committed
436
  aom_free(cpi->segmentation_map);
Jingning Han's avatar
Jingning Han committed
437 438
  cpi->segmentation_map = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
439
  av1_cyclic_refresh_free(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
440 441
  cpi->cyclic_refresh = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
442
  aom_free(cpi->active_map.map);
Jingning Han's avatar
Jingning Han committed
443 444
  cpi->active_map.map = NULL;

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

Yaowu Xu's avatar
Yaowu Xu committed
449 450
  av1_free_ref_frame_buffers(cm->buffer_pool);
  av1_free_context_buffers(cm);
Jingning Han's avatar
Jingning Han committed
451

Yaowu Xu's avatar
Yaowu Xu committed
452
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
453
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
454
  av1_free_restoration_buffers(cm);
455 456 457 458
  aom_free_frame_buffer(&cpi->last_frame_db);
  aom_free_frame_buffer(&cpi->trial_frame_rst);
  aom_free(cpi->extra_rstbuf);
  av1_free_restoration_struct(&cpi->rst_search);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
459
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
460 461 462 463
  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
464

Yaowu Xu's avatar
Yaowu Xu committed
465
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
466 467
  cpi->tile_tok[0][0] = 0;

Yaowu Xu's avatar
Yaowu Xu committed
468 469
  av1_free_pc_tree(&cpi->td);
  av1_free_var_tree(&cpi->td);
470

471
#if CONFIG_PALETTE
hui su's avatar
hui su committed
472
  if (cpi->common.allow_screen_content_tools)
Yaowu Xu's avatar
Yaowu Xu committed
473
    aom_free(cpi->td.mb.palette_buffer);
474
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
475

Jingning Han's avatar
Jingning Han committed
476
  if (cpi->source_diff_var != NULL) {
Yaowu Xu's avatar
Yaowu Xu committed
477
    aom_free(cpi->source_diff_var);
Jingning Han's avatar
Jingning Han committed
478 479
    cpi->source_diff_var = NULL;
  }
480
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
481
  aom_buf_ans_free(&cpi->buf_ans);
482
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
483 484
}

Yaowu Xu's avatar
Yaowu Xu committed
485
static void save_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
486
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
487
  AV1_COMMON *cm = &cpi->common;
488 489 490
#if CONFIG_REF_MV
  int i;
#endif
Jingning Han's avatar
Jingning Han committed
491

492
// Stores a snapshot of key state variables which can subsequently be
Yaowu Xu's avatar
Yaowu Xu committed
493 494
// 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
495
// quantizer value is adjusted between loop iterations.
496 497
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
498
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
499 500
    av1_copy(cc->nmv_costs, cpi->nmv_costs);
    av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
501 502
  }
#else
Yaowu Xu's avatar
Yaowu Xu committed
503
  av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
504
#endif
Jingning Han's avatar
Jingning Han committed
505

506 507
  av1_copy(cc->nmvcosts, cpi->nmvcosts);
  av1_copy(cc->nmvcosts_hp, cpi->nmvcosts_hp);
Jingning Han's avatar
Jingning Han committed
508

Yaowu Xu's avatar
Yaowu Xu committed
509 510
  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
511 512 513 514

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

Yaowu Xu's avatar
Yaowu Xu committed
515
static void restore_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
516
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
517
  AV1_COMMON *cm = &cpi->common;
518 519 520
#if CONFIG_REF_MV
  int i;
#endif
Jingning Han's avatar
Jingning Han committed
521

522
// Restore key state variables to the snapshot state stored in the
Yaowu Xu's avatar
Yaowu Xu committed
523
// previous call to av1_save_coding_context.
524 525
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
526
    av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
527 528
    av1_copy(cpi->nmv_costs, cc->nmv_costs);
    av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
529 530
  }
#else
Yaowu Xu's avatar
Yaowu Xu committed
531
  av1_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
532
#endif
Jingning Han's avatar
Jingning Han committed
533

534 535
  av1_copy(cpi->nmvcosts, cc->nmvcosts);
  av1_copy(cpi->nmvcosts_hp, cc->nmvcosts_hp);
Jingning Han's avatar
Jingning Han committed
536

Yaowu Xu's avatar
Yaowu Xu committed
537 538
  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
539 540 541 542

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

Yaowu Xu's avatar
Yaowu Xu committed
543 544
static void configure_static_seg_features(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
545 546 547 548 549 550 551 552 553 554 555 556 557 558 559
  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
560
    av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
561 562

    // Clear down the segment features.
Yaowu Xu's avatar
Yaowu Xu committed
563
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
564 565 566 567 568 569 570 571 572
  } 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
573 574
    av1_disable_segmentation(seg);
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
575 576 577

    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
Yaowu Xu's avatar
Yaowu Xu committed
578
    av1_update_mbgraph_stats(cpi);
Jingning Han's avatar
Jingning Han committed
579 580 581 582 583 584 585

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

586
      qi_delta =
Yaowu Xu's avatar
Yaowu Xu committed
587 588 589
          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
590

Yaowu Xu's avatar
Yaowu Xu committed
591 592
      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
593 594 595 596 597 598 599 600 601 602 603 604 605 606 607

      // 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
608 609 610 611
        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
612

Yaowu Xu's avatar
Yaowu Xu committed
613 614
        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
615 616 617

        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xu's avatar
Yaowu Xu committed
618 619 620
          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
621 622 623 624 625
        }
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

Yaowu Xu's avatar
Yaowu Xu committed
626
        av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
627 628 629 630 631 632

        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
633
        av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
634 635 636 637 638 639 640
      }
    } 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
641 642
      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
643 644

      // All mbs should use ALTREF_FRAME
Yaowu Xu's avatar
Yaowu Xu committed
645 646 647 648
      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
649 650 651

      // Skip all MBs if high Q (0,0 mv and skip coeffs)
      if (high_q) {
Yaowu Xu's avatar
Yaowu Xu committed
652 653
        av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
654 655 656 657 658 659 660 661 662 663 664 665 666
      }
      // 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
667 668
static void update_reference_segmentation_map(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
669 670 671 672 673 674 675 676 677 678 679 680 681 682
  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
683 684 685
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
686 687

  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
688 689 690 691
    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
692
#endif
Yaowu Xu's avatar
Yaowu Xu committed
693
                                        oxcf->lag_in_frames);
Jingning Han's avatar
Jingning Han committed
694
  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
695
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
696 697 698
                       "Failed to allocate lag buffers");

  // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xu's avatar
Yaowu Xu committed
699
  if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Jingning Han's avatar
Jingning Han committed
700
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
701
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
702 703
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
704 705
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
706
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
707 708 709
                       "Failed to allocate altref buffer");
}

Yaowu Xu's avatar
Yaowu Xu committed
710 711 712
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
713
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
714
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
715 716
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
717 718
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
719
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
720 721
                       "Failed to allocate last frame buffer");

Debargha Mukherjee's avatar
Debargha Mukherjee committed
722
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
723
  if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
724
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
725
#if CONFIG_AOM_HIGHBITDEPTH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
726 727
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
728 729
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
730
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
731
                       "Failed to allocate last frame deblocked buffer");
732 733 734 735 736 737 738 739 740 741
  if (aom_realloc_frame_buffer(&cpi->trial_frame_rst, cm->width, cm->height,
                               cm->subsampling_x, cm->subsampling_y,
#if CONFIG_AOM_HIGHBITDEPTH
                               cm->use_highbitdepth,
#endif
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
                       "Failed to allocate trial restored frame buffer");
  cpi->extra_rstbuf = (uint8_t *)aom_realloc(
742
      cpi->extra_rstbuf, RESTORATION_TILEPELS_MAX * sizeof(int32_t));
743
  if (!cpi->extra_rstbuf)
744
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
745 746
                       "Failed to allocate extra rstbuf for restoration");
  av1_alloc_restoration_struct(&cpi->rst_search, cm->width, cm->height);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
747 748
#endif  // CONFIG_LOOP_RESTORATION

Yaowu Xu's avatar
Yaowu Xu committed
749
  if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
750
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
751
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
752 753
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
754 755
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
756
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
757 758
                       "Failed to allocate scaled source buffer");

Yaowu Xu's avatar
Yaowu Xu committed
759
  if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
760
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
761
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
762 763
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
764 765
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
766
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
767 768 769
                       "Failed to allocate scaled last source buffer");
}

Yaowu Xu's avatar
Yaowu Xu committed
770 771
static int alloc_context_buffers_ext(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
772 773
  int mi_size = cm->mi_cols * cm->mi_rows;

Yaowu Xu's avatar
Yaowu Xu committed
774
  cpi->mbmi_ext_base = aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base));
775
  if (!cpi->mbmi_ext_base) return 1;
Jingning Han's avatar
Jingning Han committed
776 777 778 779

  return 0;
}

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

Yaowu Xu's avatar
Yaowu Xu committed
783
  av1_alloc_context_buffers(cm, cm->width, cm->height);
Jingning Han's avatar
Jingning Han committed
784 785 786

  alloc_context_buffers_ext(cpi);

Yaowu Xu's avatar
Yaowu Xu committed
787
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
788 789 790 791

  {
    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
792
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
793
#if CONFIG_ANS
794 795
    aom_buf_ans_alloc(&cpi->buf_ans, &cm->error,
                      ANS_MAX_SYMBOLS ? ANS_MAX_SYMBOLS : tokens);
796
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
797 798
  }

Yaowu Xu's avatar
Yaowu Xu committed
799
  av1_setup_pc_tree(&cpi->common, &cpi->td);
Jingning Han's avatar
Jingning Han committed
800 801
}

Yaowu Xu's avatar
Yaowu Xu committed
802
void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Jingning Han's avatar
Jingning Han committed
803
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
Yaowu Xu's avatar
Yaowu Xu committed
804
  av1_rc_update_framerate(cpi);
Jingning Han's avatar
Jingning Han committed
805 806
}

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

810
#if CONFIG_EXT_TILE
811
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
812
  if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
813
    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
814
    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
815
    cm->tile_width <<= MAX_MIB_SIZE_LOG2;
816
    cm->tile_height <<= MAX_MIB_SIZE_LOG2;
817
  } else {
818
    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
819
    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
820
    cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
821 822
    cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
  }
823
#else
824
  cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
825
  cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
826
  cm->tile_width <<= MAX_MIB_SIZE_LOG2;
827 828
  cm->tile_height <<= MAX_MIB_SIZE_LOG2;
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
829

Yaowu Xu's avatar
Yaowu Xu committed
830 831
  cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
  cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
832

833 834 835
  assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
  assert(cm->tile_height >> MAX_MIB_SIZE <= 32);

836 837
  // Get the number of tiles
  cm->tile_cols = 1;
838
  while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
839 840

  cm->tile_rows = 1;
841
  while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
842
#else
Jingning Han's avatar
Jingning Han committed
843
  int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xu's avatar
Yaowu Xu committed
844
  av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Jingning Han's avatar
Jingning Han committed
845

846 847
  cm->log2_tile_cols =
      clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
Yunqing Wang's avatar
Yunqing Wang committed
848
  cm->log2_tile_rows = cpi->oxcf.tile_rows;
849 850 851 852

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

853 854 855 856 857 858
  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
859
  cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
860
  cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
861
#endif  // CONFIG_EXT_TILE
Jingning Han's avatar
Jingning Han committed
862 863
}

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

Yaowu Xu's avatar
Yaowu Xu committed
868 869
  av1_set_mb_mi(cm, cm->width, cm->height);
  av1_init_context_buffers(cm);
870 871 872 873 874
  av1_init_macroblockd(cm, xd,
#if CONFIG_PVQ
                       NULL,
#endif
                       NULL);
Jingning Han's avatar
Jingning Han committed
875 876 877
  memset(cpi->mbmi_ext_base, 0,
         cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));

878
  set_tile_info(cpi);
Jingning Han's avatar
Jingning Han committed
879 880
}

Yaowu Xu's avatar
Yaowu Xu committed
881
static void init_buffer_indices(AV1_COMP *cpi) {
882
#if CONFIG_EXT_REFS
883 884 885 886
  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;
887 888
  cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
  cpi->alt_fb_idx = LAST_REF_FRAMES + 2;