encoder.c 207 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_CDEF
20
#include "av1/common/cdef.h"
21
#include "av1/common/clpf.h"
22
#endif  // CONFIG_CDEF
23
24
25
26
#include "av1/common/filter.h"
#include "av1/common/idct.h"
#include "av1/common/reconinter.h"
#include "av1/common/reconintra.h"
27
#include "av1/common/resize.h"
28
#include "av1/common/tile_common.h"
Jingning Han's avatar
Jingning Han committed
29

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

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

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

Jingning Han's avatar
Jingning Han committed
83
84
85
#define AM_SEGMENT_ID_INACTIVE 7
#define AM_SEGMENT_ID_ACTIVE 0

86
87
88
89
90
91
92
93
#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
94
95
96
97
98
99
100
101
102
// #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;
103
#define FILE_NAME_LEN 100
Jingning Han's avatar
Jingning Han committed
104
105
106
107
108
109
110
111
#endif

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

Luc Trudeau's avatar
Luc Trudeau committed
112
113
114
115
#if CONFIG_CFL
CFL_CTX NULL_CFL;
#endif

116
117
118
119
#if CONFIG_INTERNAL_STATS
typedef enum { Y, U, V, ALL } STAT_TYPE;
#endif  // CONFIG_INTERNAL_STATS

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

Yaowu Xu's avatar
Yaowu Xu committed
193
194
int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
195
196
197
198
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
    unsigned char *const active_map_8x8 = cpi->active_map.map;
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
199
200
    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
201
202
203
204
205
206
    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] =
207
              new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)]
Jingning Han's avatar
Jingning Han committed
208
209
210
211
212
213
214
215
216
217
218
219
220
221
                  ? 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
222
223
int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
224
225
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
      new_map_16x16) {
226
    unsigned char *const seg_map_8x8 = cpi->segmentation_map;
Jingning Han's avatar
Jingning Han committed
227
228
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
229
230
231
    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
232
233
234
235
236
237
238
    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
239
          new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)] |=
Jingning Han's avatar
Jingning Han committed
240
241
242
243
244
245
246
247
248
249
              seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
        }
      }
    }
    return 0;
  } else {
    return -1;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
250
void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Jingning Han's avatar
Jingning Han committed
251
252
  MACROBLOCK *const mb = &cpi->td.mb;
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
253
254
255
256
257
258
259
260
261
262
263
264

  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];
    }
  } else {
    int i;
    for (i = 0; i < NMV_CONTEXTS; ++i) {
      mb->mv_cost_stack[i] = mb->nmvcost[i];
    }
  }
Jingning Han's avatar
Jingning Han committed
265
266
}

Yaowu Xu's avatar
Yaowu Xu committed
267
static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
268
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
269
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
270
271
    return BLOCK_64X64;

Yaowu Xu's avatar
Yaowu Xu committed
272
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
273
274
    return BLOCK_128X128;

Yaowu Xu's avatar
Yaowu Xu committed
275
  assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
276
277
278
279
280
281
282
283
284
285
286
287
288
289

  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
}

Zoe Liu's avatar
Zoe Liu committed
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#ifdef CONFIG_COLLECT_REF_FRAME_STATS
static void collect_ref_frame_stats() {
  AV1_COMMON *const cm = &cpi->common;
  ThreadData *td = &cpi->td;
  FRAME_COUNTS *const counts = td->counts;
  int i, j;

  printf(" %d,", cm->frame_context_idx);

  for (i = 0; i < COMP_INTER_CONTEXTS; ++i) {
    // 0: single ref i.e. !has_second_ref(mbmi)
    // 1: comp ref i.e. has_second_ref(mbmi)
    printf(" %u,", counts->comp_inter[i][0]);
  }

  for (i = 0; i < COMP_REF_TYPE_CONTEXTS; ++i) {
    // 0: UNIDIR_COMP_REFERENCE
    // 1: BIDIR_COMP_REFERENCE
    printf(" %u,", counts->comp_ref_type[i][0]);
  }

  // {LAST, LAST2}, {LAST, GOLDEN}, and {BWDREF, ALTREF}
  for (i = 0; i < UNI_COMP_REF_CONTEXTS; ++i) {
    for (j = 0; j < (UNIDIR_COMP_REFS - 1); ++j)
      printf(" %u,", counts->uni_comp_ref[i][j][0]);
  }

  // Single ref stats
  for (i = 0; i < REF_CONTEXTS; ++i) {
    for (j = 0; j < (SINGLE_REFS - 1); ++j)
      printf(" %u,", counts->single_ref[i][j][0]);
  }

  // Comp ref stats
  for (i = 0; i < REF_CONTEXTS; ++i) {
    for (j = 0; j < (FWD_REFS - 1); ++j)
      printf(" %u,", counts->comp_ref[i][j][0]);
  }
  for (i = 0; i < REF_CONTEXTS; ++i) {
    for (j = 0; j < (BWD_REFS - 1); ++j)
      printf(" %u,", counts->comp_bwdref[i][j][0]);
  }

  printf("\n");
}
#endif  // CONFIG_COLLECT_REF_FRAME_STATS

Yaowu Xu's avatar
Yaowu Xu committed
337
338
static void setup_frame(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
339
340
341
342
343
344
  // 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
345
    av1_setup_past_independence(cm);
Jingning Han's avatar
Jingning Han committed
346
  } else {
347
348
349
350
351
352
353
#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
354
    if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
355
#endif  // CONFIG_EXT_REFS
356
357
358
359
360
361
362
    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
363
#endif  // CONFIG_EXT_REFS
364
365
    else
      cm->frame_context_idx = REGULAR_FRAME;
Jingning Han's avatar
Jingning Han committed
366
367
368
  }

  if (cm->frame_type == KEY_FRAME) {
Yunqing Wang's avatar
Yunqing Wang committed
369
    cpi->refresh_golden_frame = 1;
Jingning Han's avatar
Jingning Han committed
370
    cpi->refresh_alt_ref_frame = 1;
Yaowu Xu's avatar
Yaowu Xu committed
371
    av1_zero(cpi->interp_filter_selected);
Jingning Han's avatar
Jingning Han committed
372
373
  } else {
    *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xu's avatar
Yaowu Xu committed
374
    av1_zero(cpi->interp_filter_selected[0]);
Jingning Han's avatar
Jingning Han committed
375
  }
376
#if CONFIG_EXT_REFS
377
#if CONFIG_ONE_SIDED_COMPOUND  // No change to bitstream
378
379
380
381
382
383
  if (cpi->sf.recode_loop == DISALLOW_RECODE) {
    cpi->refresh_bwd_ref_frame = cpi->refresh_last_frame;
    cpi->rc.is_bipred_frame = 1;
  }
#endif
#endif
384
  cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
385

Geza Lore's avatar
Geza Lore committed
386
387
  cpi->vaq_refresh = 0;

388
  set_sb_size(cm, select_sb_size(cpi));
Jingning Han's avatar
Jingning Han committed
389
390
}

Yaowu Xu's avatar
Yaowu Xu committed
391
static void av1_enc_setup_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
  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
409
410
static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
  cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
411
  if (!cm->mip) return 1;
Yaowu Xu's avatar
Yaowu Xu committed
412
  cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
413
  if (!cm->prev_mip) return 1;
Jingning Han's avatar
Jingning Han committed
414
415
  cm->mi_alloc_size = mi_size;

Yaowu Xu's avatar
Yaowu Xu committed
416
  cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
417
418
  if (!cm->mi_grid_base) return 1;
  cm->prev_mi_grid_base =
Yaowu Xu's avatar
Yaowu Xu committed
419
      (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
420
  if (!cm->prev_mi_grid_base) return 1;
Jingning Han's avatar
Jingning Han committed
421
422
423
424

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
425
426
static void av1_enc_free_mi(AV1_COMMON *cm) {
  aom_free(cm->mip);
Jingning Han's avatar
Jingning Han committed
427
  cm->mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
428
  aom_free(cm->prev_mip);
Jingning Han's avatar
Jingning Han committed
429
  cm->prev_mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
430
  aom_free(cm->mi_grid_base);
Jingning Han's avatar
Jingning Han committed
431
  cm->mi_grid_base = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
432
  aom_free(cm->prev_mi_grid_base);
Jingning Han's avatar
Jingning Han committed
433
434
435
  cm->prev_mi_grid_base = NULL;
}

Yaowu Xu's avatar
Yaowu Xu committed
436
static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
  // 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
453
void av1_initialize_enc(void) {
Jingning Han's avatar
Jingning Han committed
454
455
456
  static volatile int init_done = 0;

  if (!init_done) {
Yaowu Xu's avatar
Yaowu Xu committed
457
458
459
460
461
    av1_rtcd();
    aom_dsp_rtcd();
    aom_scale_rtcd();
    av1_init_intra_predictors();
    av1_init_me_luts();
462
#if !CONFIG_XIPHRC
Yaowu Xu's avatar
Yaowu Xu committed
463
    av1_rc_init_minq_luts();
464
#endif
Yaowu Xu's avatar
Yaowu Xu committed
465
466
    av1_entropy_mv_init();
    av1_encode_token_init();
467
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
468
    av1_init_wedge_masks();
469
#endif
Jingning Han's avatar
Jingning Han committed
470
471
472
473
    init_done = 1;
  }
}

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

Yaowu Xu's avatar
Yaowu Xu committed
477
  aom_free(cpi->mbmi_ext_base);
Jingning Han's avatar
Jingning Han committed
478
479
  cpi->mbmi_ext_base = NULL;

480
481
#if CONFIG_PVQ
  if (cpi->oxcf.pass != 1) {
Yushin Cho's avatar
Yushin Cho committed
482
483
    const int tile_cols = cm->tile_cols;
    const int tile_rows = cm->tile_rows;
484
485
486
487
488
489
490
491
492
493
    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
494
  aom_free(cpi->tile_data);
Jingning Han's avatar
Jingning Han committed
495
496
497
  cpi->tile_data = NULL;

  // Delete sementation map
Yaowu Xu's avatar
Yaowu Xu committed
498
  aom_free(cpi->segmentation_map);
Jingning Han's avatar
Jingning Han committed
499
500
  cpi->segmentation_map = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
501
  av1_cyclic_refresh_free(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
502
503
  cpi->cyclic_refresh = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
504
  aom_free(cpi->active_map.map);
Jingning Han's avatar
Jingning Han committed
505
506
  cpi->active_map.map = NULL;

507
508
509
510
511
512
513
514
515
516
517
518
519
520
#if CONFIG_MOTION_VAR
  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;
#endif

Yaowu Xu's avatar
Yaowu Xu committed
521
  av1_free_ref_frame_buffers(cm->buffer_pool);
522
523
524
#if CONFIG_LV_MAP
  av1_free_txb_buf(cpi);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
525
  av1_free_context_buffers(cm);
Jingning Han's avatar
Jingning Han committed
526

Yaowu Xu's avatar
Yaowu Xu committed
527
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
528
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
529
  av1_free_restoration_buffers(cm);
530
531
532
  aom_free_frame_buffer(&cpi->last_frame_db);
  aom_free_frame_buffer(&cpi->trial_frame_rst);
  aom_free(cpi->extra_rstbuf);
533
534
535
536
537
  {
    int i;
    for (i = 0; i < MAX_MB_PLANE; ++i)
      av1_free_restoration_struct(&cpi->rst_search[i]);
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
538
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
539
540
541
542
  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
543

Yaowu Xu's avatar
Yaowu Xu committed
544
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
545
546
  cpi->tile_tok[0][0] = 0;

Yaowu Xu's avatar
Yaowu Xu committed
547
  av1_free_pc_tree(&cpi->td);
548

549
#if CONFIG_PALETTE
hui su's avatar
hui su committed
550
  if (cpi->common.allow_screen_content_tools)
Yaowu Xu's avatar
Yaowu Xu committed
551
    aom_free(cpi->td.mb.palette_buffer);
552
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
553

554
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
555
  aom_buf_ans_free(&cpi->buf_ans);
556
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
557
558
}

Yaowu Xu's avatar
Yaowu Xu committed
559
static void save_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
560
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
561
  AV1_COMMON *cm = &cpi->common;
562
  int i;
Jingning Han's avatar
Jingning Han committed
563

Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
564
565
566
567
  // 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.
568
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
569
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
570
571
    av1_copy(cc->nmv_costs, cpi->nmv_costs);
    av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
572
  }
Jingning Han's avatar
Jingning Han committed
573

Yaowu Xu's avatar
Yaowu Xu committed
574
575
  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
576
577
578
579

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

Yaowu Xu's avatar
Yaowu Xu committed
580
static void restore_coding_context(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
581
  CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xu's avatar
Yaowu Xu committed
582
  AV1_COMMON *cm = &cpi->common;
583
  int i;
Jingning Han's avatar
Jingning Han committed
584

Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
585
586
  // Restore key state variables to the snapshot state stored in the
  // previous call to av1_save_coding_context.
587
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
588
    av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
589
590
    av1_copy(cpi->nmv_costs, cc->nmv_costs);
    av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
591
  }
Jingning Han's avatar
Jingning Han committed
592

Yaowu Xu's avatar
Yaowu Xu committed
593
594
  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
595
596
597
598

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

Yaowu Xu's avatar
Yaowu Xu committed
599
600
static void configure_static_seg_features(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
  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
616
    av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
617
618

    // Clear down the segment features.
Yaowu Xu's avatar
Yaowu Xu committed
619
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
620
621
622
623
624
625
626
627
628
  } 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
629
630
    av1_disable_segmentation(seg);
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
631
632
633

    // Scan frames from current to arf frame.
    // This function re-enables segmentation if appropriate.
Yaowu Xu's avatar
Yaowu Xu committed
634
    av1_update_mbgraph_stats(cpi);
Jingning Han's avatar
Jingning Han committed
635
636
637
638
639
640
641

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

642
      qi_delta =
Yaowu Xu's avatar
Yaowu Xu committed
643
644
645
          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
646

Yaowu Xu's avatar
Yaowu Xu committed
647
648
      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
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663

      // 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
664
665
666
667
        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
668

Yaowu Xu's avatar
Yaowu Xu committed
669
670
        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
671
672
673

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

Yaowu Xu's avatar
Yaowu Xu committed
682
        av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
683
684
685
686
687
688

        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
689
        av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
690
691
692
693
694
695
696
      }
    } 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
697
698
      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
699
700

      // All mbs should use ALTREF_FRAME
Yaowu Xu's avatar
Yaowu Xu committed
701
702
703
704
      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
705
706
707

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

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

  // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xu's avatar
Yaowu Xu committed
755
  if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Jingning Han's avatar
Jingning Han committed
756
                               cm->subsampling_x, cm->subsampling_y,
757
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
758
759
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
760
761
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
762
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
763
764
765
                       "Failed to allocate altref buffer");
}

Yaowu Xu's avatar
Yaowu Xu committed
766
767
768
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
769
                               cm->subsampling_x, cm->subsampling_y,
770
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
771
772
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
773
774
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
775
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
776
777
                       "Failed to allocate last frame buffer");

Debargha Mukherjee's avatar
Debargha Mukherjee committed
778
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
779
  if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
780
                               cm->subsampling_x, cm->subsampling_y,
781
#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
782
783
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
784
785
                               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,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
787
                       "Failed to allocate last frame deblocked buffer");
788
789
790
791
792
793
794
795
  if (aom_realloc_frame_buffer(
          &cpi->trial_frame_rst,
#if CONFIG_FRAME_SUPERRES
          cm->superres_upscaled_width, cm->superres_upscaled_height,
#else
          cm->width, cm->height,
#endif  // CONFIG_FRAME_SUPERRES
          cm->subsampling_x, cm->subsampling_y,
796
#if CONFIG_HIGHBITDEPTH
797
          cm->use_highbitdepth,
798
#endif
799
          AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL))
800
801
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
                       "Failed to allocate trial restored frame buffer");
802
  int extra_rstbuf_sz = RESTORATION_EXTBUF_SIZE;
803
  if (extra_rstbuf_sz > 0) {
Alex Converse's avatar
Alex Converse committed
804
    aom_free(cpi->extra_rstbuf);
805
    CHECK_MEM_ERROR(cm, cpi->extra_rstbuf,
Alex Converse's avatar
Alex Converse committed
806
                    (uint8_t *)aom_malloc(extra_rstbuf_sz));
807
808
809
  } else {
    cpi->extra_rstbuf = NULL;
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
810
811
#endif  // CONFIG_LOOP_RESTORATION

Yaowu Xu's avatar
Yaowu Xu committed
812
  if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
813
                               cm->subsampling_x, cm->subsampling_y,
814
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
815
816
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
817
818
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
819
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
820
821
                       "Failed to allocate scaled source buffer");

Yaowu Xu's avatar
Yaowu Xu committed
822
  if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
823
                               cm->subsampling_x, cm->subsampling_y,
824
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
825
826
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
827
828
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
829
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
830
831
832
                       "Failed to allocate scaled last source buffer");
}

833
static void alloc_context_buffers_ext(AV1_COMP *cpi) {
Yaowu Xu's avatar
Yaowu Xu committed
834
  AV1_COMMON *cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
835
836
  int mi_size = cm->mi_cols * cm->mi_rows;

837
838
  CHECK_MEM_ERROR(cm, cpi->mbmi_ext_base,
                  aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base)));
Jingning Han's avatar
Jingning Han committed
839
840
}

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

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

846
847
848
849
#if CONFIG_LV_MAP
  av1_alloc_txb_buf(cpi);
#endif

Jingning Han's avatar
Jingning Han committed
850
851
  alloc_context_buffers_ext(cpi);

Yaowu Xu's avatar
Yaowu Xu committed
852
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
853
854
855
856

  {
    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
857
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
858
859
#if CONFIG_ANS && !ANS_MAX_SYMBOLS
    aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, (int)tokens);
860
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
861
862
  }

Yaowu Xu's avatar
Yaowu Xu committed
863
  av1_setup_pc_tree(&cpi->common, &cpi->td);
Jingning Han's avatar
Jingning Han committed
864
865
}

Yaowu Xu's avatar
Yaowu Xu committed
866
void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Jingning Han's avatar
Jingning Han committed
867
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
868
869
870
871
872
#if CONFIG_XIPHRC
  if (!cpi->od_rc.cur_frame) return;
  cpi->od_rc.framerate = cpi->framerate;
  od_enc_rc_resize(&cpi->od_rc);
#else
Yaowu Xu's avatar
Yaowu Xu committed
873
  av1_rc_update_framerate(cpi);
874
#endif
Jingning Han's avatar
Jingning Han committed
875
876
}

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

Yaowu Xu's avatar
Yaowu Xu committed
903
904
  cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
  cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
905

906
907
908
  assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
  assert(cm->tile_height >> MAX_MIB_SIZE <= 32);

909
910
  // Get the number of tiles
  cm->tile_cols = 1;
911
  while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
912
913

  cm->tile_rows = 1;
914
  while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
915
#else
Jingning Han's avatar
Jingning Han committed
916
  int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xu's avatar
Yaowu Xu committed
917
  av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Jingning Han's avatar
Jingning Han committed
918

919
920
  cm->log2_tile_cols =
      clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
Yunqing Wang's avatar
Yunqing Wang committed
921
  cm->log2_tile_rows = cpi->oxcf.tile_rows;
922
923
924
925

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

926
927
928
929
930
931
  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
932
  cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
933
  cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
934
#endif  // CONFIG_EXT_TILE
935

936
937
#if CONFIG_DEPENDENT_HORZTILES
  cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles;
938
939
940
#if CONFIG_EXT_TILE
  if (cm->tile_rows <= 1) cm->dependent_horz_tiles = 0;
#else
941
  if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0;
942
#endif
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
#if CONFIG_TILE_GROUPS
  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;
    }
  }
#endif
966
967
#endif

968
#if CONFIG_LOOPFILTERING_ACROSS_TILES
969
970
  cm->loop_filter_across_tiles_enabled =
      cpi->oxcf.loop_filter_across_tiles_enabled;
971
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
Jingning Han's avatar
Jingning Han committed
972
973
}

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

Yaowu Xu's avatar
Yaowu Xu committed
978
979
  av1_set_mb_mi(cm, cm->width, cm->height);
  av1_init_context_buffers(cm);
980
981
982
  av1_init_macroblockd(cm, xd,
#if CONFIG_PVQ
                       NULL,
Luc Trudeau's avatar
Luc Trudeau committed
983
984
985
#endif
#if CONFIG_CFL
                       &NULL_CFL,
986
987
#endif
                       NULL);
Jingning Han's avatar
Jingning Han committed
988
989
990
  memset(cpi->mbmi_ext_base, 0,
         cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));

991
  set_tile_info(cpi);
Jingning Han's avatar
Jingning Han committed
992
993
}

Yaowu Xu's avatar
Yaowu Xu committed
994
static void init_buffer_indices(AV1_COMP *cpi) {
995
#if CONFIG_EXT_REFS
996
997
998
999
  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;
1000
1001
  cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
  cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
1002
1003
  for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
    cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
1004
#else
1005
  cpi->lst_fb_idx = 0;
Jingning Han's avatar
Jingning Han committed
1006
1007
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
1008
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
1009
1010
}

Yaowu Xu's avatar
Yaowu Xu committed
1011
1012
static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
1013
1014
1015
1016
1017
1018

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

  cm->profile = oxcf->profile;
  cm->bit_depth = oxcf->bit_depth;
1019
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
1020
1021
1022
  cm->use_highbitdepth = oxcf->use_highbitdepth;
#endif
  cm->color_space = oxcf->color_space;
1023
1024
1025
1026
#if CONFIG_COLORSPACE_HEADERS
  cm->transfer_function = oxcf->transfer_function;
  cm->chroma_sample_position = oxcf->chroma_sample_position;
#endif
1027
  cm->color_range = oxcf->color_range;
Jingning Han's avatar
Jingning Han committed
1028
1029
1030

  cm->width = oxcf->width;
  cm->height = oxcf->height;
Yaowu Xu's avatar
Yaowu Xu committed
1031
  av1_alloc_compressor_data(cpi);
Jingning Han's avatar
Jingning Han committed
1032
1033
1034
1035
1036

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

  // change includes all joint functionality
Yaowu Xu's avatar
Yaowu Xu committed
1037
  av1_change_config(cpi, oxcf);
Jingning Han's avatar
Jingning Han committed
1038
1039
1040
1041
1042
1043
1044
1045

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

  init_buffer_indices(cpi);
}

static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xu's avatar
Yaowu Xu committed
1046
                                const AV1EncoderConfig *oxcf) {
Jingning Han's avatar
Jingning Han committed
1047
1048
1049
1050
1051
1052
  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;
1053
1054
1055
1056
  rc->optimal_buffer_level =
      (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
  rc->maximum_buffer_size =
      (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
Jingning Han's avatar
Jingning Han committed
1057
1058
}

1059
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
1060
#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075