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

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

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

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

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

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

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

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

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

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

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

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

  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
264
265
}

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

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

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

  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
289
290
static void setup_frame(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
291
292
293
294
295
296
  // 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
297
    av1_setup_past_independence(cm);
Jingning Han's avatar
Jingning Han committed
298
  } else {
299
300
301
302
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
// Just use frame context from first signaled reference frame.
// This will always be LAST_FRAME for now.
#else
303
304
#if CONFIG_EXT_REFS
    const GF_GROUP *gf_group = &cpi->twopass.gf_group;
Zoe Liu's avatar
Zoe Liu committed
305
306
307
#if CONFIG_ALTREF2
    if (gf_group->update_type[gf_group->index] == INTNL_ARF_UPDATE)
#else  // !CONFIG_ALTREF2
308
    if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
Zoe Liu's avatar
Zoe Liu committed
309
#endif  // CONFIG_ALTREF2
310
311
312
      cm->frame_context_idx = EXT_ARF_FRAME;
    else if (cpi->refresh_alt_ref_frame)
      cm->frame_context_idx = ARF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
313
#else   // !CONFIG_EXT_REFS
314
    if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
315
#endif  // CONFIG_EXT_REFS
316
317
318
319
320
321
322
    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
323
#endif  // CONFIG_EXT_REFS
324
325
    else
      cm->frame_context_idx = REGULAR_FRAME;
326
#endif  // CONFIG_NO_FRAME_CONTEXT_SIGNALING
Jingning Han's avatar
Jingning Han committed
327
328
329
  }

  if (cm->frame_type == KEY_FRAME) {
Yunqing Wang's avatar
Yunqing Wang committed
330
    cpi->refresh_golden_frame = 1;
Jingning Han's avatar
Jingning Han committed
331
    cpi->refresh_alt_ref_frame = 1;
Yaowu Xu's avatar
Yaowu Xu committed
332
    av1_zero(cpi->interp_filter_selected);
Jingning Han's avatar
Jingning Han committed
333
  } else {
334
335
336
337
338
339
340
341
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
    if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
        cm->frame_refs[0].idx < 0) {
      *cm->fc = cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
    } else {
      *cm->fc = cm->frame_contexts[cm->frame_refs[0].idx];
    }
#else
Jingning Han's avatar
Jingning Han committed
342
    *cm->fc = cm->frame_contexts[cm->frame_context_idx];
343
#endif  // CONFIG_NO_FRAME_CONTEXT_SIGNALING
Yaowu Xu's avatar
Yaowu Xu committed
344
    av1_zero(cpi->interp_filter_selected[0]);
Jingning Han's avatar
Jingning Han committed
345
  }
346
#if CONFIG_EXT_REFS
347
#if CONFIG_ONE_SIDED_COMPOUND  // No change to bitstream
348
349
350
351
352
353
  if (cpi->sf.recode_loop == DISALLOW_RECODE) {
    cpi->refresh_bwd_ref_frame = cpi->refresh_last_frame;
    cpi->rc.is_bipred_frame = 1;
  }
#endif
#endif
354
#if CONFIG_NO_FRAME_CONTEXT_SIGNALING
355
356
  if (frame_is_intra_only(cm) || cm->error_resilient_mode ||
      cm->frame_refs[0].idx < 0) {
357
358
359
    // use default frame context values
    cm->pre_fc = &cm->frame_contexts[FRAME_CONTEXT_DEFAULTS];
  } else {
360
    *cm->fc = cm->frame_contexts[cm->frame_refs[0].idx];
361
362
363
    cm->pre_fc = &cm->frame_contexts[cm->frame_refs[0].idx];
  }
#else
364
  cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
365
#endif  // CONFIG_NO_FRAME_CONTEXT_SIGNALING
366

Geza Lore's avatar
Geza Lore committed
367
368
  cpi->vaq_refresh = 0;

369
  set_sb_size(cm, select_sb_size(cpi));
Jingning Han's avatar
Jingning Han committed
370
371
}

Yaowu Xu's avatar
Yaowu Xu committed
372
static void av1_enc_setup_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  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
389
390
static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
  cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
391
  if (!cm->mip) return 1;
Yaowu Xu's avatar
Yaowu Xu committed
392
  cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
393
  if (!cm->prev_mip) return 1;
Jingning Han's avatar
Jingning Han committed
394
395
  cm->mi_alloc_size = mi_size;

Yaowu Xu's avatar
Yaowu Xu committed
396
  cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
397
398
  if (!cm->mi_grid_base) return 1;
  cm->prev_mi_grid_base =
Yaowu Xu's avatar
Yaowu Xu committed
399
      (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
400
  if (!cm->prev_mi_grid_base) return 1;
Jingning Han's avatar
Jingning Han committed
401
402
403
404

  return 0;
}

Yaowu Xu's avatar
Yaowu Xu committed
405
406
static void av1_enc_free_mi(AV1_COMMON *cm) {
  aom_free(cm->mip);
Jingning Han's avatar
Jingning Han committed
407
  cm->mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
408
  aom_free(cm->prev_mip);
Jingning Han's avatar
Jingning Han committed
409
  cm->prev_mip = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
410
  aom_free(cm->mi_grid_base);
Jingning Han's avatar
Jingning Han committed
411
  cm->mi_grid_base = NULL;
Yaowu Xu's avatar
Yaowu Xu committed
412
  aom_free(cm->prev_mi_grid_base);
Jingning Han's avatar
Jingning Han committed
413
414
415
  cm->prev_mi_grid_base = NULL;
}

Yaowu Xu's avatar
Yaowu Xu committed
416
static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
  // 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
433
void av1_initialize_enc(void) {
Jingning Han's avatar
Jingning Han committed
434
435
436
  static volatile int init_done = 0;

  if (!init_done) {
Yaowu Xu's avatar
Yaowu Xu committed
437
438
439
440
441
    av1_rtcd();
    aom_dsp_rtcd();
    aom_scale_rtcd();
    av1_init_intra_predictors();
    av1_init_me_luts();
442
#if !CONFIG_XIPHRC
Yaowu Xu's avatar
Yaowu Xu committed
443
    av1_rc_init_minq_luts();
444
#endif
Yaowu Xu's avatar
Yaowu Xu committed
445
446
    av1_entropy_mv_init();
    av1_encode_token_init();
447
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
448
    av1_init_wedge_masks();
449
#endif
Jingning Han's avatar
Jingning Han committed
450
451
452
453
    init_done = 1;
  }
}

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

Yaowu Xu's avatar
Yaowu Xu committed
457
  aom_free(cpi->mbmi_ext_base);
Jingning Han's avatar
Jingning Han committed
458
459
  cpi->mbmi_ext_base = NULL;

460
461
#if CONFIG_PVQ
  if (cpi->oxcf.pass != 1) {
Yushin Cho's avatar
Yushin Cho committed
462
463
    const int tile_cols = cm->tile_cols;
    const int tile_rows = cm->tile_rows;
464
465
466
467
468
469
470
471
472
473
    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
474
  aom_free(cpi->tile_data);
Jingning Han's avatar
Jingning Han committed
475
476
477
  cpi->tile_data = NULL;

  // Delete sementation map
Yaowu Xu's avatar
Yaowu Xu committed
478
  aom_free(cpi->segmentation_map);
Jingning Han's avatar
Jingning Han committed
479
480
  cpi->segmentation_map = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
481
  av1_cyclic_refresh_free(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
482
483
  cpi->cyclic_refresh = NULL;

Yaowu Xu's avatar
Yaowu Xu committed
484
  aom_free(cpi->active_map.map);
Jingning Han's avatar
Jingning Han committed
485
486
  cpi->active_map.map = NULL;

487
488
489
490
491
492
493
494
495
496
497
498
499
500
#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
501
  av1_free_ref_frame_buffers(cm->buffer_pool);
502
503
504
#if CONFIG_LV_MAP
  av1_free_txb_buf(cpi);
#endif
Yaowu Xu's avatar
Yaowu Xu committed
505
  av1_free_context_buffers(cm);
Jingning Han's avatar
Jingning Han committed
506

Yaowu Xu's avatar
Yaowu Xu committed
507
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
508
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
509
  av1_free_restoration_buffers(cm);
510
511
512
  aom_free_frame_buffer(&cpi->last_frame_db);
  aom_free_frame_buffer(&cpi->trial_frame_rst);
  aom_free(cpi->extra_rstbuf);
513
514
515
516
517
  {
    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
518
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
519
520
521
522
  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
523

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

Yaowu Xu's avatar
Yaowu Xu committed
527
  av1_free_pc_tree(&cpi->td);
528

529
#if CONFIG_PALETTE
530
  aom_free(cpi->td.mb.palette_buffer);
531
#endif  // CONFIG_PALETTE
hui su's avatar
hui su committed
532

533
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
534
  aom_buf_ans_free(&cpi->buf_ans);
535
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
536
537
}

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

Sebastien Alaiwan's avatar
Sebastien Alaiwan committed
543
544
545
546
  // 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.
547
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
548
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
549
550
    av1_copy(cc->nmv_costs, cpi->nmv_costs);
    av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
551
  }
Jingning Han's avatar
Jingning Han committed
552

Yaowu Xu's avatar
Yaowu Xu committed
553
554
  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
555
556
557
558

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

Yaowu Xu's avatar
Yaowu Xu committed
559
static void restore_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
  // Restore key state variables to the snapshot state stored in the
  // previous call to av1_save_coding_context.
566
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
567
    av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
568
569
    av1_copy(cpi->nmv_costs, cc->nmv_costs);
    av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
570
  }
Jingning Han's avatar
Jingning Han committed
571

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Debargha Mukherjee's avatar
Debargha Mukherjee committed
757
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
758
  if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
759
                               cm->subsampling_x, cm->subsampling_y,
760
#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee's avatar
Debargha Mukherjee committed
761
762
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
763
764
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
765
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Debargha Mukherjee's avatar
Debargha Mukherjee committed
766
                       "Failed to allocate last frame deblocked buffer");
767
768
769
770
771
772
773
774
  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,
775
#if CONFIG_HIGHBITDEPTH
776
          cm->use_highbitdepth,
777
#endif
778
          AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL))
779
780
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
                       "Failed to allocate trial restored frame buffer");
781
  int extra_rstbuf_sz = RESTORATION_EXTBUF_SIZE;
782
  if (extra_rstbuf_sz > 0) {
Alex Converse's avatar
Alex Converse committed
783
    aom_free(cpi->extra_rstbuf);
784
    CHECK_MEM_ERROR(cm, cpi->extra_rstbuf,
Alex Converse's avatar
Alex Converse committed
785
                    (uint8_t *)aom_malloc(extra_rstbuf_sz));
786
787
788
  } else {
    cpi->extra_rstbuf = NULL;
  }
Debargha Mukherjee's avatar
Debargha Mukherjee committed
789
790
#endif  // CONFIG_LOOP_RESTORATION

Yaowu Xu's avatar
Yaowu Xu committed
791
  if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
792
                               cm->subsampling_x, cm->subsampling_y,
793
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
794
795
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
796
797
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
798
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
799
800
                       "Failed to allocate scaled source buffer");

Yaowu Xu's avatar
Yaowu Xu committed
801
  if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
802
                               cm->subsampling_x, cm->subsampling_y,
803
#if CONFIG_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
804
805
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
806
807
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
808
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
809
810
811
                       "Failed to allocate scaled last source buffer");
}

812
static void alloc_context_buffers_ext(AV1_COMP *cpi) {
Yaowu Xu's avatar
Yaowu Xu committed
813
  AV1_COMMON *cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
814
815
  int mi_size = cm->mi_cols * cm->mi_rows;

816
817
  CHECK_MEM_ERROR(cm, cpi->mbmi_ext_base,
                  aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base)));
Jingning Han's avatar
Jingning Han committed
818
819
}

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

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

825
826
827
828
#if CONFIG_LV_MAP
  av1_alloc_txb_buf(cpi);
#endif

Jingning Han's avatar
Jingning Han committed
829
830
  alloc_context_buffers_ext(cpi);

Yaowu Xu's avatar
Yaowu Xu committed
831
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
832
833
834
835

  {
    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
836
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
837
838
#if CONFIG_ANS && !ANS_MAX_SYMBOLS
    aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, (int)tokens);
839
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
840
841
  }

Yaowu Xu's avatar
Yaowu Xu committed
842
  av1_setup_pc_tree(&cpi->common, &cpi->td);
Jingning Han's avatar
Jingning Han committed
843
844
}

Yaowu Xu's avatar
Yaowu Xu committed
845
void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Jingning Han's avatar
Jingning Han committed
846
  cpi->framerate = framerate < 0.1 ? 30 : framerate;
847
848
849
850
851
#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
852
  av1_rc_update_framerate(cpi);
853
#endif
Jingning Han's avatar
Jingning Han committed
854
855
}

Yaowu Xu's avatar
Yaowu Xu committed
856
857
static void set_tile_info(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
858
#if CONFIG_DEPENDENT_HORZTILES
859
860
861
  int tile_row, tile_col, num_tiles_in_tg;
  int tg_row_start, tg_col_start;
#endif
862
#if CONFIG_EXT_TILE
863
  if (cpi->oxcf.large_scale_tile) {
864
#if CONFIG_EXT_PARTITION
865
866
867
868
869
870
871
872
873
874
875
876
    if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
      cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
      cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
      cm->tile_width <<= MAX_MIB_SIZE_LOG2;
      cm->tile_height <<= MAX_MIB_SIZE_LOG2;
    } else {
      cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
      cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
      cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
      cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
    }
#else
877
    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
878
    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
879
880
    cm->tile_width <<= MAX_MIB_SIZE_LOG2;
    cm->tile_height <<= MAX_MIB_SIZE_LOG2;
881
#endif  // CONFIG_EXT_PARTITION
Jingning Han's avatar
Jingning Han committed
882

883
884
    cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
    cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
885

886
887
    assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
    assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
888

889
890
891
    // Get the number of tiles
    cm->tile_cols = 1;
    while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
892

893
894
895
896
897
898
    cm->tile_rows = 1;
    while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
  } else {
#endif  // CONFIG_EXT_TILE
    int min_log2_tile_cols, max_log2_tile_cols;
    av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Jingning Han's avatar
Jingning Han committed
899

900
901
902
    cm->log2_tile_cols =
        clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
    cm->log2_tile_rows = cpi->oxcf.tile_rows;
903

904
905
    cm->tile_cols = 1 << cm->log2_tile_cols;
    cm->tile_rows = 1 << cm->log2_tile_rows;
906

907
908
909
910
    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;
911

912
913
914
915
916
    // round to integer multiples of max superblock size
    cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
    cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
#if CONFIG_EXT_TILE
  }
917
#endif  // CONFIG_EXT_TILE
918

919
920
#if CONFIG_DEPENDENT_HORZTILES
  cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles;
921
#if CONFIG_EXT_TILE
922
923
924
  if (cm->large_scale_tile) {
    // May not needed since cpi->oxcf.dependent_horz_tiles is already adjusted.
    cm->dependent_horz_tiles = 0;
925
  } else {
926
927
928
#endif  // CONFIG_EXT_TILE
    if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0;
#if CONFIG_EXT_TILE
929
  }
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
#endif  // CONFIG_EXT_TILE

#if CONFIG_EXT_TILE
  if (!cm->large_scale_tile) {
#endif  // CONFIG_EXT_TILE
    if (cpi->oxcf.mtu == 0) {
      cm->num_tg = cpi->oxcf.num_tile_groups;
    } else {
      // Use a default value for the purposes of weighting costs in probability
      // updates
      cm->num_tg = DEFAULT_MAX_NUM_TG;
    }
    num_tiles_in_tg =
        (cm->tile_cols * cm->tile_rows + cm->num_tg - 1) / cm->num_tg;
    tg_row_start = 0;
    tg_col_start = 0;
    for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
      for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
        if ((tile_row * cm->tile_cols + tile_col) % num_tiles_in_tg == 0) {
          tg_row_start = tile_row;
          tg_col_start = tile_col;
        }
        cm->tile_group_start_row[tile_row][tile_col] = tg_row_start;
        cm->tile_group_start_col[tile_row][tile_col] = tg_col_start;
954
955
      }
    }
956
#if CONFIG_EXT_TILE
957
  }
958
#endif  // CONFIG_EXT_TILE
959
#endif
960

961
#if CONFIG_LOOPFILTERING_ACROSS_TILES
962
963
  cm->loop_filter_across_tiles_enabled =
      cpi->oxcf.loop_filter_across_tiles_enabled;
964
#endif  // CONFIG_LOOPFILTERING_ACROSS_TILES
Jingning Han's avatar
Jingning Han committed
965
966
}

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

Yaowu Xu's avatar
Yaowu Xu committed
971
972
  av1_set_mb_mi(cm, cm->width, cm->height);
  av1_init_context_buffers(cm);
973
974
975
  av1_init_macroblockd(cm, xd,
#if CONFIG_PVQ
                       NULL,
Luc Trudeau's avatar
Luc Trudeau committed
976
977
978
#endif
#if CONFIG_CFL
                       &NULL_CFL,
979
980
#endif
                       NULL);
Jingning Han's avatar
Jingning Han committed
981
982
983
  memset(cpi->mbmi_ext_base, 0,
         cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));

984
  set_tile_info(cpi);
Jingning Han's avatar
Jingning Han committed
985
986
}

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

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

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

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

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

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

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

  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
1044