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

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

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

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

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

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

Jingning Han's avatar
Jingning Han committed
73
74
75
#define AM_SEGMENT_ID_INACTIVE 7
#define AM_SEGMENT_ID_ACTIVE 0

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
175
176
int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
    unsigned char *const active_map_8x8 = cpi->active_map.map;
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
    cpi->active_map.update = 1;
    if (new_map_16x16) {
      int r, c;
      for (r = 0; r < mi_rows; ++r) {
        for (c = 0; c < mi_cols; ++c) {
          active_map_8x8[r * mi_cols + c] =
              new_map_16x16[(r >> 1) * cols + (c >> 1)]
                  ? AM_SEGMENT_ID_ACTIVE
                  : AM_SEGMENT_ID_INACTIVE;
        }
      }
      cpi->active_map.enabled = 1;
    } else {
      cpi->active_map.enabled = 0;
    }
    return 0;
  } else {
    return -1;
  }
}

Yaowu Xu's avatar
Yaowu Xu committed
202
203
int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
                       int cols) {
Jingning Han's avatar
Jingning Han committed
204
205
  if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
      new_map_16x16) {
206
    unsigned char *const seg_map_8x8 = cpi->segmentation_map;
Jingning Han's avatar
Jingning Han committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
    const int mi_rows = cpi->common.mi_rows;
    const int mi_cols = cpi->common.mi_cols;
    memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
    if (cpi->active_map.enabled) {
      int r, c;
      for (r = 0; r < mi_rows; ++r) {
        for (c = 0; c < mi_cols; ++c) {
          // Cyclic refresh segments are considered active despite not having
          // AM_SEGMENT_ID_ACTIVE
          new_map_16x16[(r >> 1) * cols + (c >> 1)] |=
              seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
        }
      }
    }
    return 0;
  } else {
    return -1;
  }
}

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
261
  if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
262
263
    return BLOCK_128X128;

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

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

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

Geza Lore's avatar
Geza Lore committed
319
320
  cpi->vaq_refresh = 0;

321
  set_sb_size(cm, select_sb_size(cpi));
Jingning Han's avatar
Jingning Han committed
322
323
}

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

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

  return 0;
}

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
412
  aom_free(cpi->tile_data);
Jingning Han's avatar
Jingning Han committed
413
414
415
  cpi->tile_data = NULL;

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

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
454
  av1_cyclic_refresh_free(cpi->cyclic_refresh);
Jingning Han's avatar
Jingning Han committed
455
456
  cpi->cyclic_refresh = NULL;

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

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

Yaowu Xu's avatar
Yaowu Xu committed
464
465
  av1_free_ref_frame_buffers(cm->buffer_pool);
  av1_free_context_buffers(cm);
Jingning Han's avatar
Jingning Han committed
466

Yaowu Xu's avatar
Yaowu Xu committed
467
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
468
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
469
470
  aom_free_frame_buffer(&cpi->last_frame_db);
  av1_free_restoration_buffers(cm);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
471
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
472
473
474
475
  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
476

Yaowu Xu's avatar
Yaowu Xu committed
477
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
478
479
  cpi->tile_tok[0][0] = 0;

Yaowu Xu's avatar
Yaowu Xu committed
480
481
  av1_free_pc_tree(&cpi->td);
  av1_free_var_tree(&cpi->td);
482

hui su's avatar
hui su committed
483
  if (cpi->common.allow_screen_content_tools)
Yaowu Xu's avatar
Yaowu Xu committed
484
    aom_free(cpi->td.mb.palette_buffer);
hui su's avatar
hui su committed
485

Jingning Han's avatar
Jingning Han committed
486
  if (cpi->source_diff_var != NULL) {
Yaowu Xu's avatar
Yaowu Xu committed
487
    aom_free(cpi->source_diff_var);
Jingning Han's avatar
Jingning Han committed
488
489
    cpi->source_diff_var = NULL;
  }
490
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
491
  aom_buf_ans_free(&cpi->buf_ans);
492
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
493
494
}

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

502
// Stores a snapshot of key state variables which can subsequently be
Yaowu Xu's avatar
Yaowu Xu committed
503
504
// 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
505
// quantizer value is adjusted between loop iterations.
506
507
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
508
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
509
510
511
512
513
514
515
516
517
518
    memcpy(cc->nmv_costs[i][0], cpi->nmv_costs[i][0],
           MV_VALS * sizeof(*cpi->nmv_costs[i][0]));
    memcpy(cc->nmv_costs[i][1], cpi->nmv_costs[i][1],
           MV_VALS * sizeof(*cpi->nmv_costs[i][1]));
    memcpy(cc->nmv_costs_hp[i][0], cpi->nmv_costs_hp[i][0],
           MV_VALS * sizeof(*cpi->nmv_costs_hp[i][0]));
    memcpy(cc->nmv_costs_hp[i][1], cpi->nmv_costs_hp[i][1],
           MV_VALS * sizeof(*cpi->nmv_costs_hp[i][1]));
  }
#else
Yaowu Xu's avatar
Yaowu Xu committed
519
  av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
520
#endif
Jingning Han's avatar
Jingning Han committed
521
522
523
524
525
526
527
528
529
530

  memcpy(cc->nmvcosts[0], cpi->nmvcosts[0],
         MV_VALS * sizeof(*cpi->nmvcosts[0]));
  memcpy(cc->nmvcosts[1], cpi->nmvcosts[1],
         MV_VALS * sizeof(*cpi->nmvcosts[1]));
  memcpy(cc->nmvcosts_hp[0], cpi->nmvcosts_hp[0],
         MV_VALS * sizeof(*cpi->nmvcosts_hp[0]));
  memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1],
         MV_VALS * sizeof(*cpi->nmvcosts_hp[1]));

531
532
  memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map,
         (cm->mi_rows * cm->mi_cols));
Jingning Han's avatar
Jingning Han committed
533

Yaowu Xu's avatar
Yaowu Xu committed
534
535
  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
536
537
538
539

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

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

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

  memcpy(cpi->nmvcosts[0], cc->nmvcosts[0], MV_VALS * sizeof(*cc->nmvcosts[0]));
  memcpy(cpi->nmvcosts[1], cc->nmvcosts[1], MV_VALS * sizeof(*cc->nmvcosts[1]));
  memcpy(cpi->nmvcosts_hp[0], cc->nmvcosts_hp[0],
         MV_VALS * sizeof(*cc->nmvcosts_hp[0]));
  memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1],
         MV_VALS * sizeof(*cc->nmvcosts_hp[1]));

572
  memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy,
Jingning Han's avatar
Jingning Han committed
573
574
         (cm->mi_rows * cm->mi_cols));

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

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

Yaowu Xu's avatar
Yaowu Xu committed
581
582
static void configure_static_seg_features(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  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
598
    av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
599
600

    // Clear down the segment features.
Yaowu Xu's avatar
Yaowu Xu committed
601
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
602
603
604
605
606
607
608
609
610
  } 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
611
612
    av1_disable_segmentation(seg);
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
613
614
615

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

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

624
      qi_delta =
Yaowu Xu's avatar
Yaowu Xu committed
625
626
627
          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
628

Yaowu Xu's avatar
Yaowu Xu committed
629
630
      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
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

      // 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
646
647
648
649
        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
650

Yaowu Xu's avatar
Yaowu Xu committed
651
652
        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
653
654
655

        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xu's avatar
Yaowu Xu committed
656
657
658
          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
659
660
661
662
663
        }
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

Yaowu Xu's avatar
Yaowu Xu committed
664
        av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
665
666
667
668
669
670

        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
671
        av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
672
673
674
675
676
677
678
      }
    } 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
679
680
      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
681
682

      // All mbs should use ALTREF_FRAME
Yaowu Xu's avatar
Yaowu Xu committed
683
684
685
686
      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
687
688
689

      // Skip all MBs if high Q (0,0 mv and skip coeffs)
      if (high_q) {
Yaowu Xu's avatar
Yaowu Xu committed
690
691
        av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
692
693
694
695
696
697
698
699
700
701
702
703
704
      }
      // 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
705
706
static void update_reference_segmentation_map(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
707
708
709
710
711
712
713
714
715
716
717
718
719
720
  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
721
722
723
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
724
725

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

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

Yaowu Xu's avatar
Yaowu Xu committed
748
749
750
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
751
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
752
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
753
754
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
755
756
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
757
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
758
759
                       "Failed to allocate last frame buffer");

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

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

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

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

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

  return 0;
}

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

Yaowu Xu's avatar
Yaowu Xu committed
806
  av1_alloc_context_buffers(cm, cm->width, cm->height);
Jingning Han's avatar
Jingning Han committed
807
808
809

  alloc_context_buffers_ext(cpi);

Yaowu Xu's avatar
Yaowu Xu committed
810
  aom_free(cpi->tile_tok[0][0]);
Jingning Han's avatar
Jingning Han committed
811
812
813
814

  {
    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
815
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
816
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
817
    aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, tokens);
818
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
819
820
  }

Yaowu Xu's avatar
Yaowu Xu committed
821
  av1_setup_pc_tree(&cpi->common, &cpi->td);
Jingning Han's avatar
Jingning Han committed
822
823
}

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
852
853
  cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
  cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
854

855
856
857
  assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
  assert(cm->tile_height >> MAX_MIB_SIZE <= 32);

858
859
  // Get the number of tiles
  cm->tile_cols = 1;
860
  while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
861
862

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

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

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

875
876
877
878
879
880
  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
881
  cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
882
  cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
883
#endif  // CONFIG_EXT_TILE
Jingning Han's avatar
Jingning Han committed
884
885
}

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

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

896
  set_tile_info(cpi);
Jingning Han's avatar
Jingning Han committed
897
898
}

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

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

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

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

  cm->width = oxcf->width;
  cm->height = oxcf->height;
Yaowu Xu's avatar
Yaowu Xu committed
932
  av1_alloc_compressor_data(cpi);
Jingning Han's avatar
Jingning Han committed
933
934
935
936
937

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

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

  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
947
                                const AV1EncoderConfig *oxcf) {
Jingning Han's avatar
Jingning Han committed
948
949
950
951
952
953
  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;
954
955
956
957
  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
958
959
}

Yaowu Xu's avatar
Yaowu Xu committed
960
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
961
#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
  cpi->fn_ptr[BT].sdf = SDF;                                           \
  cpi->fn_ptr[BT].sdaf = SDAF;                                         \
  cpi->fn_ptr[BT].vf = VF;                                             \
  cpi->fn_ptr[BT].svf = SVF;                                           \
  cpi->fn_ptr[BT].svaf = SVAF;                                         \
  cpi->fn_ptr[BT].sdx3f = SDX3F;                                       \
  cpi->fn_ptr[BT].sdx8f = SDX8F;                                       \
  cpi->fn_ptr[BT].sdx4df = SDX4DF;

#define MAKE_BFP_SAD_WRAPPER(fnname)                                           \
  static unsigned int fnname##_bits8(const uint8_t *src_ptr,                   \
                                     int source_stride,                        \
                                     const uint8_t *ref_ptr, int ref_stride) { \
    return fnname(src_ptr, source_stride, ref_ptr, ref_stride);                \
  }                                                                            \
  static unsigned int fnname##_bits10(                                         \
      const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
      int ref_stride) {                                                        \
    return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2;           \
  }                                                                            \
  static unsigned int fnname##_bits12(                                         \
      const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
      int ref_stride) {                                                        \
    return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4;           \
  }

#define MAKE_BFP_SADAVG_WRAPPER(fnname)                                        \
  static unsigned int fnname##_bits8(                                          \
      const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
      int ref_stride, const uint8_t *second_pred) {                            \
    return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred);   \
  }                                                                            \
  static unsigned int fnname##_bits10(                                         \
      const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
      int ref_stride, const uint8_t *second_pred) {                            \
    return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
           2;                                                                  \
  }                                                                            \
  static unsigned int fnname##_bits12(                                         \
      const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr,       \
      int ref_stride, const uint8_t *second_pred) {                            \
    return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
           4;                                                                  \
  }

#define MAKE_BFP_SAD3_WRAPPER(fnname)                                    \
  static void fnname##_bits8(const uint8_t *src_ptr, int source_stride,  \
                             const uint8_t *ref_ptr, int ref_stride,     \
                             unsigned int *sad_array) {                  \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);      \
  }                                                                      \
  static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
                              const uint8_t *ref_ptr, int ref_stride,    \
                              unsigned int *sad_array) {                 \
    int i;                                                               \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);      \
    for (i = 0; i < 3; i++) sad_array[i] >>= 2;                          \
  }                                                                      \
  static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
                              const uint8_t *ref_ptr, int ref_stride,    \
                              unsigned int *sad_array) {                 \
    int i;                                                               \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);      \
    for (i = 0; i < 3; i++) sad_array[i] >>= 4;                          \
  }

#define MAKE_BFP_SAD8_WRAPPER(fnname)                                    \
  static void fnname##_bits8(const uint8_t *src_ptr, int source_stride,  \
                             const uint8_t *ref_ptr, int ref_stride,     \
                             unsigned int *sad_array) {                  \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);      \
  }                                                                      \
  static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
                              const uint8_t *ref_ptr, int ref_stride,    \
                              unsigned int *sad_array) {                 \
    int i;                                                               \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);      \
    for (i = 0; i < 8; i++) sad_array[i] >>= 2;                          \
  }                                                                      \
  static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
                              const uint8_t *ref_ptr, int ref_stride,    \
                              unsigned int *sad_array) {                 \
    int i;                                                               \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);      \
    for (i = 0; i < 8; i++) sad_array[i] >>= 4;                          \
  }
#define MAKE_BFP_SAD4D_WRAPPER(fnname)                                        \
  static void fnname##_bits8(const uint8_t *src_ptr, int source_stride,       \
                             const uint8_t *const ref_ptr[], int ref_stride,  \
                             unsigned int *sad_array) {                       \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);           \
  }                                                                           \
  static void fnname##_bits10(const uint8_t *src_ptr, int source_stride,      \
                              const uint8_t *const ref_ptr[], int ref_stride, \
                              unsigned int *sad_array) {                      \
    int i;                                                                    \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);           \
    for (i = 0; i < 4; i++) sad_array[i] >>= 2;                               \
  }                                                                           \
  static void fnname##_bits12(const uint8_t *src_ptr, int source_stride,      \
                              const uint8_t *const ref_ptr[], int ref_stride, \
                              unsigned int *sad_array) {                      \
    int i;                                                                    \
    fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array);           \
    for (i = 0; i < 4; i++) sad_array[i] >>= 4;                               \
  }
Jingning Han's avatar
Jingning Han committed
1068

1069
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x128)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x128_avg)
MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad128x128x3)
MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad128x128x8)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x128x4d)
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x64)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x64_avg)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x64x4d)
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x128)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x128_avg)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x128x4d)
1081
#endif  // CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x16)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x16_avg)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x16x4d)
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x32)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x32_avg)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x32x4d)
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x32)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x32_avg)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x32x4d)
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x64)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x64_avg)
MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x64x4d)
MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x32)
MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x32_avg)
MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad32x32x3)
MAKE_BFP_SAD8_WRAPPER(