encoder.c 207 KB
Newer Older
Jingning Han's avatar
Jingning Han committed
1
/*
2
 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jingning Han's avatar
Jingning Han committed
3
 *
4
5
6
7
8
9
 * This source code is subject to the terms of the BSD 2 Clause License and
 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
 * was not distributed with this source code in the LICENSE file, you can
 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
 * Media Patent License 1.0 was not distributed with this source code in the
 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Jingning Han's avatar
Jingning Han committed
10
11
 */

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

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

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

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

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

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

78
79
80
81
82
83
84
85
#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */

#define ALTREF_HIGH_PRECISION_MV 1     // Whether to use high precision mv
                                       //  for altref computation.
#define HIGH_PRECISION_MV_QTHRESH 200  // Q threshold for high precision
                                       // mv. Choose a very high value for
                                       // now so that HIGH_PRECISION is always
                                       // chosen.
Jingning Han's avatar
Jingning Han committed
86
87
88
89
90
91
92
93
94
// #define OUTPUT_YUV_REC
#ifdef OUTPUT_YUV_DENOISED
FILE *yuv_denoised_file = NULL;
#endif
#ifdef OUTPUT_YUV_SKINMAP
FILE *yuv_skinmap_file = NULL;
#endif
#ifdef OUTPUT_YUV_REC
FILE *yuv_rec_file;
95
#define FILE_NAME_LEN 100
Jingning Han's avatar
Jingning Han committed
96
97
98
99
100
101
102
103
#endif

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

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

Yaowu Xu's avatar
Yaowu Xu committed
108
static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Jingning Han's avatar
Jingning Han committed
109
110
111
112
113
114
115
116
117
118
119
120
  switch (mode) {
    case NORMAL:
      *hr = 1;
      *hs = 1;
      break;
    case FOURFIVE:
      *hr = 4;
      *hs = 5;
      break;
    case THREEFIVE:
      *hr = 3;
      *hs = 5;
121
      break;
Jingning Han's avatar
Jingning Han committed
122
123
124
    case ONETWO:
      *hr = 1;
      *hs = 2;
125
      break;
Jingning Han's avatar
Jingning Han committed
126
127
128
    default:
      *hr = 1;
      *hs = 1;
129
      assert(0);
Jingning Han's avatar
Jingning Han committed
130
131
132
133
134
135
      break;
  }
}

// Mark all inactive blocks as active. Other segmentation features may be set
// so memset cannot be used, instead only inactive blocks should be reset.
Yaowu Xu's avatar
Yaowu Xu committed
136
static void suppress_active_map(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
137
138
139
140
141
142
143
144
  unsigned char *const seg_map = cpi->segmentation_map;
  int i;
  if (cpi->active_map.enabled || cpi->active_map.update)
    for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
      if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
        seg_map[i] = AM_SEGMENT_ID_ACTIVE;
}

Yaowu Xu's avatar
Yaowu Xu committed
145
static void apply_active_map(AV1_COMP *cpi) {
Jingning Han's avatar
Jingning Han committed
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  struct segmentation *const seg = &cpi->common.seg;
  unsigned char *const seg_map = cpi->segmentation_map;
  const unsigned char *const active_map = cpi->active_map.map;
  int i;

  assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);

  if (frame_is_intra_only(&cpi->common)) {
    cpi->active_map.enabled = 0;
    cpi->active_map.update = 1;
  }

  if (cpi->active_map.update) {
    if (cpi->active_map.enabled) {
      for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
        if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
Yaowu Xu's avatar
Yaowu Xu committed
162
163
164
      av1_enable_segmentation(seg);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
      av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
165
166
      // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
      // filter level being zero regardless of the value of seg->abs_delta.
Yaowu Xu's avatar
Yaowu Xu committed
167
168
      av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
                      -MAX_LOOP_FILTER);
Jingning Han's avatar
Jingning Han committed
169
    } else {
Yaowu Xu's avatar
Yaowu Xu committed
170
171
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
      av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
172
173
174
175
176
177
178
179
180
      if (seg->enabled) {
        seg->update_data = 1;
        seg->update_map = 1;
      }
    }
    cpi->active_map.update = 0;
  }
}

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

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

Yaowu Xu's avatar
Yaowu Xu committed
233
void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Jingning Han's avatar
Jingning Han committed
234
235
  MACROBLOCK *const mb = &cpi->td.mb;
  cpi->common.allow_high_precision_mv = allow_high_precision_mv;
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

#if CONFIG_REF_MV
  if (cpi->common.allow_high_precision_mv) {
    int i;
    for (i = 0; i < NMV_CONTEXTS; ++i) {
      mb->mv_cost_stack[i] = mb->nmvcost_hp[i];
      mb->mvsadcost = mb->nmvsadcost_hp;
    }
  } else {
    int i;
    for (i = 0; i < NMV_CONTEXTS; ++i) {
      mb->mv_cost_stack[i] = mb->nmvcost[i];
      mb->mvsadcost = mb->nmvsadcost;
    }
  }
#else
Jingning Han's avatar
Jingning Han committed
252
253
  if (cpi->common.allow_high_precision_mv) {
    mb->mvcost = mb->nmvcost_hp;
254
    mb->mvsadcost = mb->nmvcost_hp;
Jingning Han's avatar
Jingning Han committed
255
256
  } else {
    mb->mvcost = mb->nmvcost;
257
    mb->mvsadcost = mb->nmvcost;
Jingning Han's avatar
Jingning Han committed
258
  }
259
#endif
Jingning Han's avatar
Jingning Han committed
260
261
}

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

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

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

  assert(IMPLIES(cpi->common.tile_cols > 1,
                 cpi->common.tile_width % MAX_MIB_SIZE == 0));
  assert(IMPLIES(cpi->common.tile_rows > 1,
                 cpi->common.tile_height % MAX_MIB_SIZE == 0));

  // TODO(any): Possibly could improve this with a heuristic.
  return BLOCK_128X128;
#else
  (void)cpi;
  return BLOCK_64X64;
#endif  //  CONFIG_EXT_PARTITION
}

Yaowu Xu's avatar
Yaowu Xu committed
285
286
static void setup_frame(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
287
288
289
290
291
292
  // Set up entropy context depending on frame type. The decoder mandates
  // the use of the default context, index 0, for keyframes and inter
  // frames where the error_resilient_mode or intra_only flag is set. For
  // other inter-frames the encoder currently uses only two contexts;
  // context 1 for ALTREF frames and context 0 for the others.
  if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
Yaowu Xu's avatar
Yaowu Xu committed
293
    av1_setup_past_independence(cm);
Jingning Han's avatar
Jingning Han committed
294
  } else {
295
296
297
298
299
300
301
#if CONFIG_EXT_REFS
    const GF_GROUP *gf_group = &cpi->twopass.gf_group;
    if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
      cm->frame_context_idx = EXT_ARF_FRAME;
    else if (cpi->refresh_alt_ref_frame)
      cm->frame_context_idx = ARF_FRAME;
#else
302
    if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
303
#endif  // CONFIG_EXT_REFS
304
305
306
307
308
309
310
    else if (cpi->rc.is_src_frame_alt_ref)
      cm->frame_context_idx = OVERLAY_FRAME;
    else if (cpi->refresh_golden_frame)
      cm->frame_context_idx = GLD_FRAME;
#if CONFIG_EXT_REFS
    else if (cpi->refresh_bwd_ref_frame)
      cm->frame_context_idx = BRF_FRAME;
Zoe Liu's avatar
Zoe Liu committed
311
#endif  // CONFIG_EXT_REFS
312
313
    else
      cm->frame_context_idx = REGULAR_FRAME;
Jingning Han's avatar
Jingning Han committed
314
315
316
  }

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
330
static void av1_enc_setup_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
  int i;
  cm->mi = cm->mip + cm->mi_stride + 1;
  memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
  cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
  // Clear top border row
  memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
  // Clear left border column
  for (i = 1; i < cm->mi_rows + 1; ++i)
    memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));

  cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
  cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;

  memset(cm->mi_grid_base, 0,
         cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
}

Yaowu Xu's avatar
Yaowu Xu committed
348
349
static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
  cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
350
  if (!cm->mip) return 1;
Yaowu Xu's avatar
Yaowu Xu committed
351
  cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
352
  if (!cm->prev_mip) return 1;
Jingning Han's avatar
Jingning Han committed
353
354
  cm->mi_alloc_size = mi_size;

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

  return 0;
}

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

Yaowu Xu's avatar
Yaowu Xu committed
375
static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Jingning Han's avatar
Jingning Han committed
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
  // Current mip will be the prev_mip for the next frame.
  MODE_INFO **temp_base = cm->prev_mi_grid_base;
  MODE_INFO *temp = cm->prev_mip;
  cm->prev_mip = cm->mip;
  cm->mip = temp;

  // Update the upper left visible macroblock ptrs.
  cm->mi = cm->mip + cm->mi_stride + 1;
  cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;

  cm->prev_mi_grid_base = cm->mi_grid_base;
  cm->mi_grid_base = temp_base;
  cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
  cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
}

Yaowu Xu's avatar
Yaowu Xu committed
392
void av1_initialize_enc(void) {
Jingning Han's avatar
Jingning Han committed
393
394
395
  static volatile int init_done = 0;

  if (!init_done) {
Yaowu Xu's avatar
Yaowu Xu committed
396
397
398
399
400
401
402
403
    av1_rtcd();
    aom_dsp_rtcd();
    aom_scale_rtcd();
    av1_init_intra_predictors();
    av1_init_me_luts();
    av1_rc_init_minq_luts();
    av1_entropy_mv_init();
    av1_encode_token_init();
404
#if CONFIG_EXT_INTER
Yaowu Xu's avatar
Yaowu Xu committed
405
    av1_init_wedge_masks();
406
#endif
Jingning Han's avatar
Jingning Han committed
407
408
409
410
    init_done = 1;
  }
}

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

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

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

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

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
452
  aom_free_frame_buffer(&cpi->last_frame_uf);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
453
#if CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
454
  av1_free_restoration_buffers(cm);
455
456
457
458
  aom_free_frame_buffer(&cpi->last_frame_db);
  aom_free_frame_buffer(&cpi->trial_frame_rst);
  aom_free(cpi->extra_rstbuf);
  av1_free_restoration_struct(&cpi->rst_search);
Debargha Mukherjee's avatar
Debargha Mukherjee committed
459
#endif  // CONFIG_LOOP_RESTORATION
Yaowu Xu's avatar
Yaowu Xu committed
460
461
462
463
  aom_free_frame_buffer(&cpi->scaled_source);
  aom_free_frame_buffer(&cpi->scaled_last_source);
  aom_free_frame_buffer(&cpi->alt_ref_buffer);
  av1_lookahead_destroy(cpi->lookahead);
Jingning Han's avatar
Jingning Han committed
464

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

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

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

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

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

492
// Stores a snapshot of key state variables which can subsequently be
Yaowu Xu's avatar
Yaowu Xu committed
493
494
// restored with a call to av1_restore_coding_context. These functions are
// intended for use in a re-code loop in av1_compress_frame where the
495
// quantizer value is adjusted between loop iterations.
496
497
#if CONFIG_REF_MV
  for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xu's avatar
Yaowu Xu committed
498
    av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
499
500
    av1_copy(cc->nmv_costs, cpi->nmv_costs);
    av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
501
502
  }
#else
Yaowu Xu's avatar
Yaowu Xu committed
503
  av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
504
#endif
Jingning Han's avatar
Jingning Han committed
505

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

Yaowu Xu's avatar
Yaowu Xu committed
509
510
  av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
  av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
Jingning Han's avatar
Jingning Han committed
511
512
513
514

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
537
538
  av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
  av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
Jingning Han's avatar
Jingning Han committed
539
540
541
542

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

Yaowu Xu's avatar
Yaowu Xu committed
543
544
static void configure_static_seg_features(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
  const RATE_CONTROL *const rc = &cpi->rc;
  struct segmentation *const seg = &cm->seg;

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

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

    // Disable segmentation
Yaowu Xu's avatar
Yaowu Xu committed
560
    av1_disable_segmentation(seg);
Jingning Han's avatar
Jingning Han committed
561
562

    // Clear down the segment features.
Yaowu Xu's avatar
Yaowu Xu committed
563
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
564
565
566
567
568
569
570
571
572
  } else if (cpi->refresh_alt_ref_frame) {
    // If this is an alt ref frame
    // Clear down the global segmentation map
    memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
    seg->update_map = 0;
    seg->update_data = 0;
    cpi->static_mb_pct = 0;

    // Disable segmentation and individual segment features by default
Yaowu Xu's avatar
Yaowu Xu committed
573
574
    av1_disable_segmentation(seg);
    av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
575
576
577

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

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

586
      qi_delta =
Yaowu Xu's avatar
Yaowu Xu committed
587
588
589
          av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
      av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Jingning Han's avatar
Jingning Han committed
590

Yaowu Xu's avatar
Yaowu Xu committed
591
592
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
      av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607

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

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

Yaowu Xu's avatar
Yaowu Xu committed
608
609
610
611
        qi_delta =
            av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
        av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Jingning Han's avatar
Jingning Han committed
612

Yaowu Xu's avatar
Yaowu Xu committed
613
614
        av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
        av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Jingning Han's avatar
Jingning Han committed
615
616
617

        // Segment coding disabled for compred testing
        if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xu's avatar
Yaowu Xu committed
618
619
620
          av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
          av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
          av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
621
622
623
624
625
        }
      } else {
        // Disable segmentation and clear down features if alt ref
        // is not active for this group

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
633
        av1_clearall_segfeatures(seg);
Jingning Han's avatar
Jingning Han committed
634
635
636
637
638
639
640
      }
    } else if (rc->is_src_frame_alt_ref) {
      // Special case where we are coding over the top of a previous
      // alt ref frame.
      // Segment coding disabled for compred testing

      // Enable ref frame features for segment 0 as well
Yaowu Xu's avatar
Yaowu Xu committed
641
642
      av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
      av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Jingning Han's avatar
Jingning Han committed
643
644

      // All mbs should use ALTREF_FRAME
Yaowu Xu's avatar
Yaowu Xu committed
645
646
647
648
      av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
      av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
      av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
      av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Jingning Han's avatar
Jingning Han committed
649
650
651

      // Skip all MBs if high Q (0,0 mv and skip coeffs)
      if (high_q) {
Yaowu Xu's avatar
Yaowu Xu committed
652
653
        av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
        av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Jingning Han's avatar
Jingning Han committed
654
655
656
657
658
659
660
661
662
663
664
665
666
      }
      // Enable data update
      seg->update_data = 1;
    } else {
      // All other frames.

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

Yaowu Xu's avatar
Yaowu Xu committed
667
668
static void update_reference_segmentation_map(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
  uint8_t *cache_ptr = cm->last_frame_seg_map;
  int row, col;

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

Yaowu Xu's avatar
Yaowu Xu committed
683
684
685
static void alloc_raw_frame_buffers(AV1_COMP *cpi) {
  AV1_COMMON *cm = &cpi->common;
  const AV1EncoderConfig *oxcf = &cpi->oxcf;
Jingning Han's avatar
Jingning Han committed
686
687

  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
688
689
690
691
    cpi->lookahead = av1_lookahead_init(oxcf->width, oxcf->height,
                                        cm->subsampling_x, cm->subsampling_y,
#if CONFIG_AOM_HIGHBITDEPTH
                                        cm->use_highbitdepth,
Jingning Han's avatar
Jingning Han committed
692
#endif
Yaowu Xu's avatar
Yaowu Xu committed
693
                                        oxcf->lag_in_frames);
Jingning Han's avatar
Jingning Han committed
694
  if (!cpi->lookahead)
Yaowu Xu's avatar
Yaowu Xu committed
695
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
696
697
698
                       "Failed to allocate lag buffers");

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

Yaowu Xu's avatar
Yaowu Xu committed
710
711
712
static void alloc_util_frame_buffers(AV1_COMP *cpi) {
  AV1_COMMON *const cm = &cpi->common;
  if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
Jingning Han's avatar
Jingning Han committed
713
                               cm->subsampling_x, cm->subsampling_y,
Yaowu Xu's avatar
Yaowu Xu committed
714
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
715
716
                               cm->use_highbitdepth,
#endif
Yaowu Xu's avatar
Yaowu Xu committed
717
718
                               AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
                               NULL, NULL))
Yaowu Xu's avatar
Yaowu Xu committed
719
    aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Jingning Han's avatar
Jingning Han committed
720
721
                       "Failed to allocate last frame buffer");

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

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

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

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

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

  return 0;
}

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

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

  alloc_context_buffers_ext(cpi);

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

  {
    unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
    CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xu's avatar
Yaowu Xu committed
792
                    aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
793
#if CONFIG_ANS
Alex Converse's avatar
Alex Converse committed
794
    aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, tokens);
795
#endif  // CONFIG_ANS
Jingning Han's avatar
Jingning Han committed
796
797
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Yaowu Xu's avatar
Yaowu Xu committed
880
static void init_buffer_indices(AV1_COMP *cpi) {
881
#if CONFIG_EXT_REFS
882
883
884
885
  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;
886
887
  cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
  cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
888
889
  for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
    cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
890
#else
891
  cpi->lst_fb_idx = 0;
Jingning Han's avatar
Jingning Han committed
892
893
  cpi->gld_fb_idx = 1;
  cpi->alt_fb_idx = 2;
894
#endif  // CONFIG_EXT_REFS
Jingning Han's avatar
Jingning Han committed
895
896
}

Yaowu Xu's avatar
Yaowu Xu committed
897
898
static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
  AV1_COMMON *const cm = &cpi->common;
Jingning Han's avatar
Jingning Han committed
899
900
901
902
903
904

  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
905
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
906
907
908
  cm->use_highbitdepth = oxcf->use_highbitdepth;
#endif
  cm->color_space = oxcf->color_space;
909
  cm->color_range = oxcf->color_range;
Jingning Han's avatar
Jingning Han committed
910
911
912

  cm->width = oxcf->width;
  cm->height = oxcf->height;
Yaowu Xu's avatar
Yaowu Xu committed
913
  av1_alloc_compressor_data(cpi);
Jingning Han's avatar
Jingning Han committed
914
915
916
917
918

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

  // change includes all joint functionality
Yaowu Xu's avatar
Yaowu Xu committed
919
  av1_change_config(cpi, oxcf);
Jingning Han's avatar
Jingning Han committed
920
921
922
923
924
925
926
927

  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
928
                                const AV1EncoderConfig *oxcf) {
Jingning Han's avatar
Jingning Han committed
929
930
931
932
933
934
  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;
935
936
937
938
  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
939
940
}

Yaowu Xu's avatar
Yaowu Xu committed
941
#if CONFIG_AOM_HIGHBITDEPTH
Jingning Han's avatar
Jingning Han committed
942
#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
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
  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;                          \
  }                                                                      \
For faster browsing, not all history is shown. View entire blame