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

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

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

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

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

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

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

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

#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
247
248
  if (cpi->common.allow_high_precision_mv) {
    mb->mvcost = mb->nmvcost_hp;
249
    mb->mvsadcost = mb->nmvcost_hp;
Jingning Han's avatar
Jingning Han committed
250
251
  } else {
    mb->mvcost = mb->nmvcost;
252
    mb->mvsadcost = mb->nmvcost;
Jingning Han's avatar
Jingning Han committed
253
  }
254
#endif
Jingning Han's avatar
Jingning Han committed
255
256
}

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

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

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

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

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

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

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

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

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

  return 0;
}

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

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

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

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

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

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

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

422
423
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
424
425
426
427
    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]);
428
429
430
431
432
433
434
    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
435
436
  aom_free(cpi->nmvcosts[0]);
  aom_free(cpi->nmvcosts[1]);
Jingning Han's avatar
Jingning Han committed
437
438
439
  cpi->nmvcosts[0] = NULL;
  cpi->nmvcosts[1] = NULL;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  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]));

532
533
  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
534

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

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

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

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

  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]));

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

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

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

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

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

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

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

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

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

      // 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
647
648
649
650
        qi_delta =
            av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
        av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Jingning Han's avatar
Jingning Han committed
651

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

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

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

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

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

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

  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
727
728
729
730
    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
731
#endif
Yaowu Xu's avatar
Yaowu Xu committed
732
                                        oxcf->lag_in_frames);
Jingning Han's avatar
Jingning Han committed
733
  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
734
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
735
736
737
                       "Failed to allocate lag buffers");

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

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

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

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

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

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

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

  return 0;
}

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

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

  alloc_context_buffers_ext(cpi);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
891
892
893
  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
894
895
896
  memset(cpi->mbmi_ext_base, 0,
         cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));

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

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

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

  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
925
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
926
927
928
  cm->use_highbitdepth = oxcf->use_highbitdepth;
#endif
  cm->color_space = oxcf->color_space;
929
  cm->color_range = oxcf->color_range;
Jingning Han's avatar
Jingning Han committed
930
931
932

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
961
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
962
#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
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
1068
  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
1069

1070
#if CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
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)
1082
#endif  // CONFIG_EXT_PARTITION
Yaowu Xu's avatar
Yaowu Xu committed
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
1137
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