blob: 3fbf6cf290d727c3132bcad174543eba5e81d3ac [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include <limits.h>
12#include <math.h>
13#include <stdio.h>
14
Yaowu Xuf883b422016-08-30 14:01:10 -070015#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070016
17#include "av1/common/alloccommon.h"
18#if CONFIG_CLPF
19#include "av1/common/clpf.h"
Steinar Midtskogend06588a2016-05-06 13:48:20 +020020#include "av1/encoder/clpf_rdo.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#endif
22#if CONFIG_DERING
23#include "av1/common/dering.h"
24#endif // CONFIG_DERING
25#include "av1/common/filter.h"
26#include "av1/common/idct.h"
27#include "av1/common/reconinter.h"
28#include "av1/common/reconintra.h"
29#include "av1/common/tile_common.h"
30
31#include "av1/encoder/aq_complexity.h"
32#include "av1/encoder/aq_cyclicrefresh.h"
33#include "av1/encoder/aq_variance.h"
34#include "av1/encoder/bitstream.h"
35#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -070036#include "aom_dsp/buf_ans.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070037#endif
38#include "av1/encoder/context_tree.h"
39#include "av1/encoder/encodeframe.h"
40#include "av1/encoder/encodemv.h"
41#include "av1/encoder/encoder.h"
42#include "av1/encoder/ethread.h"
43#include "av1/encoder/firstpass.h"
44#include "av1/encoder/mbgraph.h"
45#include "av1/encoder/picklpf.h"
46#if CONFIG_LOOP_RESTORATION
47#include "av1/encoder/pickrst.h"
48#endif // CONFIG_LOOP_RESTORATION
49#include "av1/encoder/ratectrl.h"
50#include "av1/encoder/rd.h"
51#include "av1/encoder/resize.h"
52#include "av1/encoder/segmentation.h"
53#include "av1/encoder/speed_features.h"
54#include "av1/encoder/temporal_filter.h"
55
Yaowu Xuf883b422016-08-30 14:01:10 -070056#include "./av1_rtcd.h"
57#include "./aom_dsp_rtcd.h"
58#include "./aom_scale_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070059#include "aom_dsp/psnr.h"
60#if CONFIG_INTERNAL_STATS
61#include "aom_dsp/ssim.h"
62#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070063#include "aom_dsp/aom_dsp_common.h"
64#include "aom_dsp/aom_filter.h"
Jingning Han1aab8182016-06-03 11:09:06 -070065#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070066#include "aom_ports/mem.h"
67#include "aom_ports/system_state.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070068#include "aom_scale/aom_scale.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070069#if CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070070#include "aom_util/debug_util.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070071#endif // CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070072
73#define AM_SEGMENT_ID_INACTIVE 7
74#define AM_SEGMENT_ID_ACTIVE 0
75
76#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
77
78#define ALTREF_HIGH_PRECISION_MV 1 // Whether to use high precision mv
79 // for altref computation.
80#define HIGH_PRECISION_MV_QTHRESH 200 // Q threshold for high precision
81 // mv. Choose a very high value for
82 // now so that HIGH_PRECISION is always
83 // chosen.
84// #define OUTPUT_YUV_REC
85#ifdef OUTPUT_YUV_DENOISED
86FILE *yuv_denoised_file = NULL;
87#endif
88#ifdef OUTPUT_YUV_SKINMAP
89FILE *yuv_skinmap_file = NULL;
90#endif
91#ifdef OUTPUT_YUV_REC
92FILE *yuv_rec_file;
93#define FILE_NAME_LEN 100
94#endif
95
96#if 0
97FILE *framepsnr;
98FILE *kf_list;
99FILE *keyfile;
100#endif
101
Yaowu Xuf883b422016-08-30 14:01:10 -0700102static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700103 switch (mode) {
104 case NORMAL:
105 *hr = 1;
106 *hs = 1;
107 break;
108 case FOURFIVE:
109 *hr = 4;
110 *hs = 5;
111 break;
112 case THREEFIVE:
113 *hr = 3;
114 *hs = 5;
115 break;
116 case ONETWO:
117 *hr = 1;
118 *hs = 2;
119 break;
120 default:
121 *hr = 1;
122 *hs = 1;
123 assert(0);
124 break;
125 }
126}
127
128// Mark all inactive blocks as active. Other segmentation features may be set
129// so memset cannot be used, instead only inactive blocks should be reset.
Yaowu Xuf883b422016-08-30 14:01:10 -0700130static void suppress_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700131 unsigned char *const seg_map = cpi->segmentation_map;
132 int i;
133 if (cpi->active_map.enabled || cpi->active_map.update)
134 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
135 if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
136 seg_map[i] = AM_SEGMENT_ID_ACTIVE;
137}
138
Yaowu Xuf883b422016-08-30 14:01:10 -0700139static void apply_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700140 struct segmentation *const seg = &cpi->common.seg;
141 unsigned char *const seg_map = cpi->segmentation_map;
142 const unsigned char *const active_map = cpi->active_map.map;
143 int i;
144
145 assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
146
147 if (frame_is_intra_only(&cpi->common)) {
148 cpi->active_map.enabled = 0;
149 cpi->active_map.update = 1;
150 }
151
152 if (cpi->active_map.update) {
153 if (cpi->active_map.enabled) {
154 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
155 if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700156 av1_enable_segmentation(seg);
157 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
158 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700159 // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
160 // filter level being zero regardless of the value of seg->abs_delta.
Yaowu Xuf883b422016-08-30 14:01:10 -0700161 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
162 -MAX_LOOP_FILTER);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700163 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700164 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
165 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700166 if (seg->enabled) {
167 seg->update_data = 1;
168 seg->update_map = 1;
169 }
170 }
171 cpi->active_map.update = 0;
172 }
173}
174
Yaowu Xuf883b422016-08-30 14:01:10 -0700175int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
176 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700177 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
178 unsigned char *const active_map_8x8 = cpi->active_map.map;
179 const int mi_rows = cpi->common.mi_rows;
180 const int mi_cols = cpi->common.mi_cols;
181 cpi->active_map.update = 1;
182 if (new_map_16x16) {
183 int r, c;
184 for (r = 0; r < mi_rows; ++r) {
185 for (c = 0; c < mi_cols; ++c) {
186 active_map_8x8[r * mi_cols + c] =
187 new_map_16x16[(r >> 1) * cols + (c >> 1)]
188 ? AM_SEGMENT_ID_ACTIVE
189 : AM_SEGMENT_ID_INACTIVE;
190 }
191 }
192 cpi->active_map.enabled = 1;
193 } else {
194 cpi->active_map.enabled = 0;
195 }
196 return 0;
197 } else {
198 return -1;
199 }
200}
201
Yaowu Xuf883b422016-08-30 14:01:10 -0700202int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
203 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700204 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
205 new_map_16x16) {
206 unsigned char *const seg_map_8x8 = cpi->segmentation_map;
207 const int mi_rows = cpi->common.mi_rows;
208 const int mi_cols = cpi->common.mi_cols;
209 memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
210 if (cpi->active_map.enabled) {
211 int r, c;
212 for (r = 0; r < mi_rows; ++r) {
213 for (c = 0; c < mi_cols; ++c) {
214 // Cyclic refresh segments are considered active despite not having
215 // AM_SEGMENT_ID_ACTIVE
216 new_map_16x16[(r >> 1) * cols + (c >> 1)] |=
217 seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
218 }
219 }
220 }
221 return 0;
222 } else {
223 return -1;
224 }
225}
226
Yaowu Xuf883b422016-08-30 14:01:10 -0700227void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700228 MACROBLOCK *const mb = &cpi->td.mb;
229 cpi->common.allow_high_precision_mv = allow_high_precision_mv;
230
231#if CONFIG_REF_MV
232 if (cpi->common.allow_high_precision_mv) {
233 int i;
234 for (i = 0; i < NMV_CONTEXTS; ++i) {
235 mb->mv_cost_stack[i] = mb->nmvcost_hp[i];
236 mb->mvsadcost = mb->nmvsadcost_hp;
237 }
238 } else {
239 int i;
240 for (i = 0; i < NMV_CONTEXTS; ++i) {
241 mb->mv_cost_stack[i] = mb->nmvcost[i];
242 mb->mvsadcost = mb->nmvsadcost;
243 }
244 }
245#else
246 if (cpi->common.allow_high_precision_mv) {
247 mb->mvcost = mb->nmvcost_hp;
248 mb->mvsadcost = mb->nmvcost_hp;
249 } else {
250 mb->mvcost = mb->nmvcost;
251 mb->mvsadcost = mb->nmvcost;
252 }
253#endif
254}
255
Yaowu Xuf883b422016-08-30 14:01:10 -0700256static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700257#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700258 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700259 return BLOCK_64X64;
260
Yaowu Xuf883b422016-08-30 14:01:10 -0700261 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700262 return BLOCK_128X128;
263
Yaowu Xuf883b422016-08-30 14:01:10 -0700264 assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700265
266 assert(IMPLIES(cpi->common.tile_cols > 1,
267 cpi->common.tile_width % MAX_MIB_SIZE == 0));
268 assert(IMPLIES(cpi->common.tile_rows > 1,
269 cpi->common.tile_height % MAX_MIB_SIZE == 0));
270
271 // TODO(any): Possibly could improve this with a heuristic.
272 return BLOCK_128X128;
273#else
274 (void)cpi;
275 return BLOCK_64X64;
276#endif // CONFIG_EXT_PARTITION
277}
278
Yaowu Xuf883b422016-08-30 14:01:10 -0700279static void setup_frame(AV1_COMP *cpi) {
280 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700281 // Set up entropy context depending on frame type. The decoder mandates
282 // the use of the default context, index 0, for keyframes and inter
283 // frames where the error_resilient_mode or intra_only flag is set. For
284 // other inter-frames the encoder currently uses only two contexts;
285 // context 1 for ALTREF frames and context 0 for the others.
286 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700287 av1_setup_past_independence(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700288 } else {
289#if CONFIG_EXT_REFS
290 const GF_GROUP *gf_group = &cpi->twopass.gf_group;
291 if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
292 cm->frame_context_idx = EXT_ARF_FRAME;
293 else if (cpi->refresh_alt_ref_frame)
294 cm->frame_context_idx = ARF_FRAME;
295#else
296 if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
297#endif
298 else if (cpi->rc.is_src_frame_alt_ref)
299 cm->frame_context_idx = OVERLAY_FRAME;
300 else if (cpi->refresh_golden_frame)
301 cm->frame_context_idx = GLD_FRAME;
302#if CONFIG_EXT_REFS
303 else if (cpi->refresh_bwd_ref_frame)
304 cm->frame_context_idx = BRF_FRAME;
305#endif
306 else
307 cm->frame_context_idx = REGULAR_FRAME;
308 }
309
310 if (cm->frame_type == KEY_FRAME) {
311 cpi->refresh_golden_frame = 1;
312 cpi->refresh_alt_ref_frame = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700313 av1_zero(cpi->interp_filter_selected);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700314 } else {
315 *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -0700316 av1_zero(cpi->interp_filter_selected[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700317 }
318
319 cpi->vaq_refresh = 0;
320
321 set_sb_size(cm, select_sb_size(cpi));
322}
323
Yaowu Xuf883b422016-08-30 14:01:10 -0700324static void av1_enc_setup_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700325 int i;
326 cm->mi = cm->mip + cm->mi_stride + 1;
327 memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
328 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
329 // Clear top border row
330 memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
331 // Clear left border column
332 for (i = 1; i < cm->mi_rows + 1; ++i)
333 memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
334
335 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
336 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
337
338 memset(cm->mi_grid_base, 0,
339 cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
340}
341
Yaowu Xuf883b422016-08-30 14:01:10 -0700342static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
343 cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700344 if (!cm->mip) return 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700345 cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700346 if (!cm->prev_mip) return 1;
347 cm->mi_alloc_size = mi_size;
348
Yaowu Xuf883b422016-08-30 14:01:10 -0700349 cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700350 if (!cm->mi_grid_base) return 1;
351 cm->prev_mi_grid_base =
Yaowu Xuf883b422016-08-30 14:01:10 -0700352 (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700353 if (!cm->prev_mi_grid_base) return 1;
354
355 return 0;
356}
357
Yaowu Xuf883b422016-08-30 14:01:10 -0700358static void av1_enc_free_mi(AV1_COMMON *cm) {
359 aom_free(cm->mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700360 cm->mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700361 aom_free(cm->prev_mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700362 cm->prev_mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700363 aom_free(cm->mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700364 cm->mi_grid_base = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700365 aom_free(cm->prev_mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 cm->prev_mi_grid_base = NULL;
367}
368
Yaowu Xuf883b422016-08-30 14:01:10 -0700369static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700370 // Current mip will be the prev_mip for the next frame.
371 MODE_INFO **temp_base = cm->prev_mi_grid_base;
372 MODE_INFO *temp = cm->prev_mip;
373 cm->prev_mip = cm->mip;
374 cm->mip = temp;
375
376 // Update the upper left visible macroblock ptrs.
377 cm->mi = cm->mip + cm->mi_stride + 1;
378 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
379
380 cm->prev_mi_grid_base = cm->mi_grid_base;
381 cm->mi_grid_base = temp_base;
382 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
383 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
384}
385
Yaowu Xuf883b422016-08-30 14:01:10 -0700386void av1_initialize_enc(void) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700387 static volatile int init_done = 0;
388
389 if (!init_done) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700390 av1_rtcd();
391 aom_dsp_rtcd();
392 aom_scale_rtcd();
393 av1_init_intra_predictors();
394 av1_init_me_luts();
395 av1_rc_init_minq_luts();
396 av1_entropy_mv_init();
397 av1_encode_token_init();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700398#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700399 av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700400#endif
401 init_done = 1;
402 }
403}
404
Yaowu Xuf883b422016-08-30 14:01:10 -0700405static void dealloc_compressor_data(AV1_COMP *cpi) {
406 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700407 int i;
408
Yaowu Xuf883b422016-08-30 14:01:10 -0700409 aom_free(cpi->mbmi_ext_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700410 cpi->mbmi_ext_base = NULL;
411
Yaowu Xuf883b422016-08-30 14:01:10 -0700412 aom_free(cpi->tile_data);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700413 cpi->tile_data = NULL;
414
415 // Delete sementation map
Yaowu Xuf883b422016-08-30 14:01:10 -0700416 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700417 cpi->segmentation_map = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700418 aom_free(cpi->coding_context.last_frame_seg_map_copy);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700419 cpi->coding_context.last_frame_seg_map_copy = NULL;
420
421#if CONFIG_REF_MV
422 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700423 aom_free(cpi->nmv_costs[i][0]);
424 aom_free(cpi->nmv_costs[i][1]);
425 aom_free(cpi->nmv_costs_hp[i][0]);
426 aom_free(cpi->nmv_costs_hp[i][1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700427 cpi->nmv_costs[i][0] = NULL;
428 cpi->nmv_costs[i][1] = NULL;
429 cpi->nmv_costs_hp[i][0] = NULL;
430 cpi->nmv_costs_hp[i][1] = NULL;
431 }
432#endif
433
Yaowu Xuf883b422016-08-30 14:01:10 -0700434 aom_free(cpi->nmvcosts[0]);
435 aom_free(cpi->nmvcosts[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700436 cpi->nmvcosts[0] = NULL;
437 cpi->nmvcosts[1] = NULL;
438
Yaowu Xuf883b422016-08-30 14:01:10 -0700439 aom_free(cpi->nmvcosts_hp[0]);
440 aom_free(cpi->nmvcosts_hp[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700441 cpi->nmvcosts_hp[0] = NULL;
442 cpi->nmvcosts_hp[1] = NULL;
443
Yaowu Xuf883b422016-08-30 14:01:10 -0700444 aom_free(cpi->nmvsadcosts[0]);
445 aom_free(cpi->nmvsadcosts[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700446 cpi->nmvsadcosts[0] = NULL;
447 cpi->nmvsadcosts[1] = NULL;
448
Yaowu Xuf883b422016-08-30 14:01:10 -0700449 aom_free(cpi->nmvsadcosts_hp[0]);
450 aom_free(cpi->nmvsadcosts_hp[1]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700451 cpi->nmvsadcosts_hp[0] = NULL;
452 cpi->nmvsadcosts_hp[1] = NULL;
453
Yaowu Xuf883b422016-08-30 14:01:10 -0700454 av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700455 cpi->cyclic_refresh = NULL;
456
Yaowu Xuf883b422016-08-30 14:01:10 -0700457 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700458 cpi->active_map.map = NULL;
459
460 // Free up-sampled reference buffers.
461 for (i = 0; i < (REF_FRAMES + 1); i++)
Yaowu Xuf883b422016-08-30 14:01:10 -0700462 aom_free_frame_buffer(&cpi->upsampled_ref_bufs[i].buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700463
Yaowu Xuf883b422016-08-30 14:01:10 -0700464 av1_free_ref_frame_buffers(cm->buffer_pool);
465 av1_free_context_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700466
Yaowu Xuf883b422016-08-30 14:01:10 -0700467 aom_free_frame_buffer(&cpi->last_frame_uf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700468#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700469 aom_free_frame_buffer(&cpi->last_frame_db);
470 av1_free_restoration_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700471#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700472 aom_free_frame_buffer(&cpi->scaled_source);
473 aom_free_frame_buffer(&cpi->scaled_last_source);
474 aom_free_frame_buffer(&cpi->alt_ref_buffer);
475 av1_lookahead_destroy(cpi->lookahead);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700476
Yaowu Xuf883b422016-08-30 14:01:10 -0700477 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700478 cpi->tile_tok[0][0] = 0;
479
Yaowu Xuf883b422016-08-30 14:01:10 -0700480 av1_free_pc_tree(&cpi->td);
481 av1_free_var_tree(&cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700482
483 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -0700484 aom_free(cpi->td.mb.palette_buffer);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700485
486 if (cpi->source_diff_var != NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700487 aom_free(cpi->source_diff_var);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700488 cpi->source_diff_var = NULL;
489 }
490#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -0700491 aom_buf_ans_free(&cpi->buf_ans);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700492#endif // CONFIG_ANS
493}
494
Yaowu Xuf883b422016-08-30 14:01:10 -0700495static void save_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700496 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700497 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700498#if CONFIG_REF_MV
499 int i;
500#endif
501
502// Stores a snapshot of key state variables which can subsequently be
Yaowu Xuf883b422016-08-30 14:01:10 -0700503// restored with a call to av1_restore_coding_context. These functions are
504// intended for use in a re-code loop in av1_compress_frame where the
Yaowu Xuc27fc142016-08-22 16:08:15 -0700505// quantizer value is adjusted between loop iterations.
506#if CONFIG_REF_MV
507 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700508 av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700509 memcpy(cc->nmv_costs[i][0], cpi->nmv_costs[i][0],
510 MV_VALS * sizeof(*cpi->nmv_costs[i][0]));
511 memcpy(cc->nmv_costs[i][1], cpi->nmv_costs[i][1],
512 MV_VALS * sizeof(*cpi->nmv_costs[i][1]));
513 memcpy(cc->nmv_costs_hp[i][0], cpi->nmv_costs_hp[i][0],
514 MV_VALS * sizeof(*cpi->nmv_costs_hp[i][0]));
515 memcpy(cc->nmv_costs_hp[i][1], cpi->nmv_costs_hp[i][1],
516 MV_VALS * sizeof(*cpi->nmv_costs_hp[i][1]));
517 }
518#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700519 av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700520#endif
521
522 memcpy(cc->nmvcosts[0], cpi->nmvcosts[0],
523 MV_VALS * sizeof(*cpi->nmvcosts[0]));
524 memcpy(cc->nmvcosts[1], cpi->nmvcosts[1],
525 MV_VALS * sizeof(*cpi->nmvcosts[1]));
526 memcpy(cc->nmvcosts_hp[0], cpi->nmvcosts_hp[0],
527 MV_VALS * sizeof(*cpi->nmvcosts_hp[0]));
528 memcpy(cc->nmvcosts_hp[1], cpi->nmvcosts_hp[1],
529 MV_VALS * sizeof(*cpi->nmvcosts_hp[1]));
530
531 memcpy(cpi->coding_context.last_frame_seg_map_copy, cm->last_frame_seg_map,
532 (cm->mi_rows * cm->mi_cols));
533
Yaowu Xuf883b422016-08-30 14:01:10 -0700534 av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
535 av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700536
537 cc->fc = *cm->fc;
538}
539
Yaowu Xuf883b422016-08-30 14:01:10 -0700540static void restore_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700541 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700542 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700543#if CONFIG_REF_MV
544 int i;
545#endif
546
547// Restore key state variables to the snapshot state stored in the
Yaowu Xuf883b422016-08-30 14:01:10 -0700548// previous call to av1_save_coding_context.
Yaowu Xuc27fc142016-08-22 16:08:15 -0700549#if CONFIG_REF_MV
550 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700551 av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700552 memcpy(cpi->nmv_costs[i][0], cc->nmv_costs[i][0],
553 MV_VALS * sizeof(*cc->nmv_costs[i][0]));
554 memcpy(cpi->nmv_costs[i][1], cc->nmv_costs[i][1],
555 MV_VALS * sizeof(*cc->nmv_costs[i][1]));
556 memcpy(cpi->nmv_costs_hp[i][0], cc->nmv_costs_hp[i][0],
557 MV_VALS * sizeof(*cc->nmv_costs_hp[i][0]));
558 memcpy(cpi->nmv_costs_hp[i][1], cc->nmv_costs_hp[i][1],
559 MV_VALS * sizeof(*cc->nmv_costs_hp[i][1]));
560 }
561#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700562 av1_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700563#endif
564
565 memcpy(cpi->nmvcosts[0], cc->nmvcosts[0], MV_VALS * sizeof(*cc->nmvcosts[0]));
566 memcpy(cpi->nmvcosts[1], cc->nmvcosts[1], MV_VALS * sizeof(*cc->nmvcosts[1]));
567 memcpy(cpi->nmvcosts_hp[0], cc->nmvcosts_hp[0],
568 MV_VALS * sizeof(*cc->nmvcosts_hp[0]));
569 memcpy(cpi->nmvcosts_hp[1], cc->nmvcosts_hp[1],
570 MV_VALS * sizeof(*cc->nmvcosts_hp[1]));
571
572 memcpy(cm->last_frame_seg_map, cpi->coding_context.last_frame_seg_map_copy,
573 (cm->mi_rows * cm->mi_cols));
574
Yaowu Xuf883b422016-08-30 14:01:10 -0700575 av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
576 av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700577
578 *cm->fc = cc->fc;
579}
580
Yaowu Xuf883b422016-08-30 14:01:10 -0700581static void configure_static_seg_features(AV1_COMP *cpi) {
582 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700583 const RATE_CONTROL *const rc = &cpi->rc;
584 struct segmentation *const seg = &cm->seg;
585
586 int high_q = (int)(rc->avg_q > 48.0);
587 int qi_delta;
588
589 // Disable and clear down for KF
590 if (cm->frame_type == KEY_FRAME) {
591 // Clear down the global segmentation map
592 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
593 seg->update_map = 0;
594 seg->update_data = 0;
595 cpi->static_mb_pct = 0;
596
597 // Disable segmentation
Yaowu Xuf883b422016-08-30 14:01:10 -0700598 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599
600 // Clear down the segment features.
Yaowu Xuf883b422016-08-30 14:01:10 -0700601 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700602 } else if (cpi->refresh_alt_ref_frame) {
603 // If this is an alt ref frame
604 // Clear down the global segmentation map
605 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
606 seg->update_map = 0;
607 seg->update_data = 0;
608 cpi->static_mb_pct = 0;
609
610 // Disable segmentation and individual segment features by default
Yaowu Xuf883b422016-08-30 14:01:10 -0700611 av1_disable_segmentation(seg);
612 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700613
614 // Scan frames from current to arf frame.
615 // This function re-enables segmentation if appropriate.
Yaowu Xuf883b422016-08-30 14:01:10 -0700616 av1_update_mbgraph_stats(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700617
618 // If segmentation was enabled set those features needed for the
619 // arf itself.
620 if (seg->enabled) {
621 seg->update_map = 1;
622 seg->update_data = 1;
623
624 qi_delta =
Yaowu Xuf883b422016-08-30 14:01:10 -0700625 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
626 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
627 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700628
Yaowu Xuf883b422016-08-30 14:01:10 -0700629 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
630 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700631
632 // Where relevant assume segment data is delta data
633 seg->abs_delta = SEGMENT_DELTADATA;
634 }
635 } else if (seg->enabled) {
636 // All other frames if segmentation has been enabled
637
638 // First normal frame in a valid gf or alt ref group
639 if (rc->frames_since_golden == 0) {
640 // Set up segment features for normal frames in an arf group
641 if (rc->source_alt_ref_active) {
642 seg->update_map = 0;
643 seg->update_data = 1;
644 seg->abs_delta = SEGMENT_DELTADATA;
645
Yaowu Xuf883b422016-08-30 14:01:10 -0700646 qi_delta =
647 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
648 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
649 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700650
Yaowu Xuf883b422016-08-30 14:01:10 -0700651 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
652 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700653
654 // Segment coding disabled for compred testing
655 if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700656 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
657 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
658 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700659 }
660 } else {
661 // Disable segmentation and clear down features if alt ref
662 // is not active for this group
663
Yaowu Xuf883b422016-08-30 14:01:10 -0700664 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700665
666 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
667
668 seg->update_map = 0;
669 seg->update_data = 0;
670
Yaowu Xuf883b422016-08-30 14:01:10 -0700671 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700672 }
673 } else if (rc->is_src_frame_alt_ref) {
674 // Special case where we are coding over the top of a previous
675 // alt ref frame.
676 // Segment coding disabled for compred testing
677
678 // Enable ref frame features for segment 0 as well
Yaowu Xuf883b422016-08-30 14:01:10 -0700679 av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
680 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700681
682 // All mbs should use ALTREF_FRAME
Yaowu Xuf883b422016-08-30 14:01:10 -0700683 av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
684 av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
685 av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
686 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700687
688 // Skip all MBs if high Q (0,0 mv and skip coeffs)
689 if (high_q) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700690 av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
691 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700692 }
693 // Enable data update
694 seg->update_data = 1;
695 } else {
696 // All other frames.
697
698 // No updates.. leave things as they are.
699 seg->update_map = 0;
700 seg->update_data = 0;
701 }
702 }
703}
704
Yaowu Xuf883b422016-08-30 14:01:10 -0700705static void update_reference_segmentation_map(AV1_COMP *cpi) {
706 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700707 MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
708 uint8_t *cache_ptr = cm->last_frame_seg_map;
709 int row, col;
710
711 for (row = 0; row < cm->mi_rows; row++) {
712 MODE_INFO **mi_8x8 = mi_8x8_ptr;
713 uint8_t *cache = cache_ptr;
714 for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
715 cache[0] = mi_8x8[0]->mbmi.segment_id;
716 mi_8x8_ptr += cm->mi_stride;
717 cache_ptr += cm->mi_cols;
718 }
719}
720
Yaowu Xuf883b422016-08-30 14:01:10 -0700721static void alloc_raw_frame_buffers(AV1_COMP *cpi) {
722 AV1_COMMON *cm = &cpi->common;
723 const AV1EncoderConfig *oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700724
725 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700726 cpi->lookahead = av1_lookahead_init(oxcf->width, oxcf->height,
727 cm->subsampling_x, cm->subsampling_y,
728#if CONFIG_AOM_HIGHBITDEPTH
729 cm->use_highbitdepth,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700730#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700731 oxcf->lag_in_frames);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700732 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700733 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700734 "Failed to allocate lag buffers");
735
736 // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xuf883b422016-08-30 14:01:10 -0700737 if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700738 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700739#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700740 cm->use_highbitdepth,
741#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700742 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
743 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700744 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700745 "Failed to allocate altref buffer");
746}
747
Yaowu Xuf883b422016-08-30 14:01:10 -0700748static void alloc_util_frame_buffers(AV1_COMP *cpi) {
749 AV1_COMMON *const cm = &cpi->common;
750 if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700751 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700752#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700753 cm->use_highbitdepth,
754#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700755 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
756 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700757 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700758 "Failed to allocate last frame buffer");
759
760#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700761 if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700762 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700763#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700764 cm->use_highbitdepth,
765#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700766 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
767 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700768 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700769 "Failed to allocate last frame deblocked buffer");
770#endif // CONFIG_LOOP_RESTORATION
771
Yaowu Xuf883b422016-08-30 14:01:10 -0700772 if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700774#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700775 cm->use_highbitdepth,
776#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700777 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
778 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700779 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700780 "Failed to allocate scaled source buffer");
781
Yaowu Xuf883b422016-08-30 14:01:10 -0700782 if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700783 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700784#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700785 cm->use_highbitdepth,
786#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700787 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
788 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700789 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700790 "Failed to allocate scaled last source buffer");
791}
792
Yaowu Xuf883b422016-08-30 14:01:10 -0700793static int alloc_context_buffers_ext(AV1_COMP *cpi) {
794 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700795 int mi_size = cm->mi_cols * cm->mi_rows;
796
Yaowu Xuf883b422016-08-30 14:01:10 -0700797 cpi->mbmi_ext_base = aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700798 if (!cpi->mbmi_ext_base) return 1;
799
800 return 0;
801}
802
Yaowu Xuf883b422016-08-30 14:01:10 -0700803void av1_alloc_compressor_data(AV1_COMP *cpi) {
804 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700805
Yaowu Xuf883b422016-08-30 14:01:10 -0700806 av1_alloc_context_buffers(cm, cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700807
808 alloc_context_buffers_ext(cpi);
809
Yaowu Xuf883b422016-08-30 14:01:10 -0700810 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700811
812 {
813 unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
814 CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700815 aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700816#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -0700817 aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, tokens);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700818#endif // CONFIG_ANS
819 }
820
Yaowu Xuf883b422016-08-30 14:01:10 -0700821 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700822}
823
Yaowu Xuf883b422016-08-30 14:01:10 -0700824void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700825 cpi->framerate = framerate < 0.1 ? 30 : framerate;
Yaowu Xuf883b422016-08-30 14:01:10 -0700826 av1_rc_update_framerate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700827}
828
Yaowu Xuf883b422016-08-30 14:01:10 -0700829static void set_tile_info(AV1_COMP *cpi) {
830 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700831
832#if CONFIG_EXT_TILE
833#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700834 if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700835 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
836 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
837 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
838 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
839 } else {
840 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
841 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
842 cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
843 cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
844 }
845#else
846 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
847 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
848 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
849 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
850#endif // CONFIG_EXT_PARTITION
851
Yaowu Xuf883b422016-08-30 14:01:10 -0700852 cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
853 cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700854
855 assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
856 assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
857
858 // Get the number of tiles
859 cm->tile_cols = 1;
860 while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
861
862 cm->tile_rows = 1;
863 while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
864#else
865 int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xuf883b422016-08-30 14:01:10 -0700866 av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700867
868 cm->log2_tile_cols =
869 clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
870 cm->log2_tile_rows = cpi->oxcf.tile_rows;
871
872 cm->tile_cols = 1 << cm->log2_tile_cols;
873 cm->tile_rows = 1 << cm->log2_tile_rows;
874
875 cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
876 cm->tile_width >>= cm->log2_tile_cols;
877 cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
878 cm->tile_height >>= cm->log2_tile_rows;
879
880 // round to integer multiples of max superblock size
881 cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
882 cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
883#endif // CONFIG_EXT_TILE
884}
885
Yaowu Xuf883b422016-08-30 14:01:10 -0700886static void update_frame_size(AV1_COMP *cpi) {
887 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
889
Yaowu Xuf883b422016-08-30 14:01:10 -0700890 av1_set_mb_mi(cm, cm->width, cm->height);
891 av1_init_context_buffers(cm);
892 av1_init_macroblockd(cm, xd, NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700893 memset(cpi->mbmi_ext_base, 0,
894 cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
895
896 set_tile_info(cpi);
897}
898
Yaowu Xuf883b422016-08-30 14:01:10 -0700899static void init_buffer_indices(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700900#if CONFIG_EXT_REFS
901 int fb_idx;
902 for (fb_idx = 0; fb_idx < LAST_REF_FRAMES; ++fb_idx)
903 cpi->lst_fb_idxes[fb_idx] = fb_idx;
904 cpi->gld_fb_idx = LAST_REF_FRAMES;
905 cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
906 cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
907 for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
908 cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
909#else
910 cpi->lst_fb_idx = 0;
911 cpi->gld_fb_idx = 1;
912 cpi->alt_fb_idx = 2;
913#endif // CONFIG_EXT_REFS
914}
915
Yaowu Xuf883b422016-08-30 14:01:10 -0700916static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
917 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700918
919 cpi->oxcf = *oxcf;
920 cpi->framerate = oxcf->init_framerate;
921
922 cm->profile = oxcf->profile;
923 cm->bit_depth = oxcf->bit_depth;
Yaowu Xuf883b422016-08-30 14:01:10 -0700924#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700925 cm->use_highbitdepth = oxcf->use_highbitdepth;
926#endif
927 cm->color_space = oxcf->color_space;
928 cm->color_range = oxcf->color_range;
929
930 cm->width = oxcf->width;
931 cm->height = oxcf->height;
Yaowu Xuf883b422016-08-30 14:01:10 -0700932 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700933
934 // Single thread case: use counts in common.
935 cpi->td.counts = &cm->counts;
936
937 // change includes all joint functionality
Yaowu Xuf883b422016-08-30 14:01:10 -0700938 av1_change_config(cpi, oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700939
940 cpi->static_mb_pct = 0;
941 cpi->ref_frame_flags = 0;
942
943 init_buffer_indices(cpi);
944}
945
946static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xuf883b422016-08-30 14:01:10 -0700947 const AV1EncoderConfig *oxcf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948 const int64_t bandwidth = oxcf->target_bandwidth;
949 const int64_t starting = oxcf->starting_buffer_level_ms;
950 const int64_t optimal = oxcf->optimal_buffer_level_ms;
951 const int64_t maximum = oxcf->maximum_buffer_size_ms;
952
953 rc->starting_buffer_level = starting * bandwidth / 1000;
954 rc->optimal_buffer_level =
955 (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
956 rc->maximum_buffer_size =
957 (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
958}
959
Yaowu Xuf883b422016-08-30 14:01:10 -0700960#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700961#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
962 cpi->fn_ptr[BT].sdf = SDF; \
963 cpi->fn_ptr[BT].sdaf = SDAF; \
964 cpi->fn_ptr[BT].vf = VF; \
965 cpi->fn_ptr[BT].svf = SVF; \
966 cpi->fn_ptr[BT].svaf = SVAF; \
967 cpi->fn_ptr[BT].sdx3f = SDX3F; \
968 cpi->fn_ptr[BT].sdx8f = SDX8F; \
969 cpi->fn_ptr[BT].sdx4df = SDX4DF;
970
971#define MAKE_BFP_SAD_WRAPPER(fnname) \
972 static unsigned int fnname##_bits8(const uint8_t *src_ptr, \
973 int source_stride, \
974 const uint8_t *ref_ptr, int ref_stride) { \
975 return fnname(src_ptr, source_stride, ref_ptr, ref_stride); \
976 } \
977 static unsigned int fnname##_bits10( \
978 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
979 int ref_stride) { \
980 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2; \
981 } \
982 static unsigned int fnname##_bits12( \
983 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
984 int ref_stride) { \
985 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4; \
986 }
987
988#define MAKE_BFP_SADAVG_WRAPPER(fnname) \
989 static unsigned int fnname##_bits8( \
990 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
991 int ref_stride, const uint8_t *second_pred) { \
992 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred); \
993 } \
994 static unsigned int fnname##_bits10( \
995 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
996 int ref_stride, const uint8_t *second_pred) { \
997 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
998 2; \
999 } \
1000 static unsigned int fnname##_bits12( \
1001 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1002 int ref_stride, const uint8_t *second_pred) { \
1003 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
1004 4; \
1005 }
1006
1007#define MAKE_BFP_SAD3_WRAPPER(fnname) \
1008 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1009 const uint8_t *ref_ptr, int ref_stride, \
1010 unsigned int *sad_array) { \
1011 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1012 } \
1013 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1014 const uint8_t *ref_ptr, int ref_stride, \
1015 unsigned int *sad_array) { \
1016 int i; \
1017 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1018 for (i = 0; i < 3; i++) sad_array[i] >>= 2; \
1019 } \
1020 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1021 const uint8_t *ref_ptr, int ref_stride, \
1022 unsigned int *sad_array) { \
1023 int i; \
1024 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1025 for (i = 0; i < 3; i++) sad_array[i] >>= 4; \
1026 }
1027
1028#define MAKE_BFP_SAD8_WRAPPER(fnname) \
1029 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1030 const uint8_t *ref_ptr, int ref_stride, \
1031 unsigned int *sad_array) { \
1032 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1033 } \
1034 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1035 const uint8_t *ref_ptr, int ref_stride, \
1036 unsigned int *sad_array) { \
1037 int i; \
1038 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1039 for (i = 0; i < 8; i++) sad_array[i] >>= 2; \
1040 } \
1041 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1042 const uint8_t *ref_ptr, int ref_stride, \
1043 unsigned int *sad_array) { \
1044 int i; \
1045 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1046 for (i = 0; i < 8; i++) sad_array[i] >>= 4; \
1047 }
1048#define MAKE_BFP_SAD4D_WRAPPER(fnname) \
1049 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1050 const uint8_t *const ref_ptr[], int ref_stride, \
1051 unsigned int *sad_array) { \
1052 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1053 } \
1054 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1055 const uint8_t *const ref_ptr[], int ref_stride, \
1056 unsigned int *sad_array) { \
1057 int i; \
1058 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1059 for (i = 0; i < 4; i++) sad_array[i] >>= 2; \
1060 } \
1061 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1062 const uint8_t *const ref_ptr[], int ref_stride, \
1063 unsigned int *sad_array) { \
1064 int i; \
1065 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1066 for (i = 0; i < 4; i++) sad_array[i] >>= 4; \
1067 }
1068
1069#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001070MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x128)
1071MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x128_avg)
1072MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad128x128x3)
1073MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad128x128x8)
1074MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x128x4d)
1075MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x64)
1076MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x64_avg)
1077MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x64x4d)
1078MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x128)
1079MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x128_avg)
1080MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001081#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001082MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x16)
1083MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x16_avg)
1084MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x16x4d)
1085MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x32)
1086MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x32_avg)
1087MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x32x4d)
1088MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x32)
1089MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x32_avg)
1090MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x32x4d)
1091MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x64)
1092MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x64_avg)
1093MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x64x4d)
1094MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x32)
1095MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x32_avg)
1096MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad32x32x3)
1097MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad32x32x8)
1098MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x32x4d)
1099MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x64)
1100MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x64_avg)
1101MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad64x64x3)
1102MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad64x64x8)
1103MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x64x4d)
1104MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x16)
1105MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x16_avg)
1106MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x16x3)
1107MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x16x8)
1108MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x16x4d)
1109MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x8)
1110MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x8_avg)
1111MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x8x3)
1112MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x8x8)
1113MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x8x4d)
1114MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x16)
1115MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x16_avg)
1116MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x16x3)
1117MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x16x8)
1118MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x16x4d)
1119MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x8)
1120MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x8_avg)
1121MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x8x3)
1122MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x8x8)
1123MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x8x4d)
1124MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x4)
1125MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x4_avg)
1126MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x4x8)
1127MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x4x4d)
1128MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x8)
1129MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x8_avg)
1130MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x8x8)
1131MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x8x4d)
1132MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x4)
1133MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x4_avg)
1134MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad4x4x3)
1135MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x4x8)
1136MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001137
1138#if CONFIG_EXT_INTER
1139#define HIGHBD_MBFP(BT, MSDF, MVF, MSVF) \
1140 cpi->fn_ptr[BT].msdf = MSDF; \
1141 cpi->fn_ptr[BT].mvf = MVF; \
1142 cpi->fn_ptr[BT].msvf = MSVF;
1143
1144#define MAKE_MBFP_SAD_WRAPPER(fnname) \
1145 static unsigned int fnname##_bits8( \
1146 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1147 int ref_stride, const uint8_t *m, int m_stride) { \
1148 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride); \
1149 } \
1150 static unsigned int fnname##_bits10( \
1151 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1152 int ref_stride, const uint8_t *m, int m_stride) { \
1153 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride) >> \
1154 2; \
1155 } \
1156 static unsigned int fnname##_bits12( \
1157 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1158 int ref_stride, const uint8_t *m, int m_stride) { \
1159 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride) >> \
1160 4; \
1161 }
1162
1163#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001164MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad128x128)
1165MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad128x64)
1166MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001167#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001168MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x64)
1169MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x32)
1170MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x64)
1171MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x32)
1172MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x16)
1173MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x32)
1174MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x16)
1175MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x8)
1176MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x16)
1177MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x8)
1178MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x4)
1179MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad4x8)
1180MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001181#endif // CONFIG_EXT_INTER
1182
1183#if CONFIG_OBMC
1184#define HIGHBD_OBFP(BT, OSDF, OVF, OSVF) \
1185 cpi->fn_ptr[BT].osdf = OSDF; \
1186 cpi->fn_ptr[BT].ovf = OVF; \
1187 cpi->fn_ptr[BT].osvf = OSVF;
1188
1189#define MAKE_OBFP_SAD_WRAPPER(fnname) \
1190 static unsigned int fnname##_bits8(const uint8_t *ref, int ref_stride, \
1191 const int32_t *wsrc, \
1192 const int32_t *msk) { \
1193 return fnname(ref, ref_stride, wsrc, msk); \
1194 } \
1195 static unsigned int fnname##_bits10(const uint8_t *ref, int ref_stride, \
1196 const int32_t *wsrc, \
1197 const int32_t *msk) { \
1198 return fnname(ref, ref_stride, wsrc, msk) >> 2; \
1199 } \
1200 static unsigned int fnname##_bits12(const uint8_t *ref, int ref_stride, \
1201 const int32_t *wsrc, \
1202 const int32_t *msk) { \
1203 return fnname(ref, ref_stride, wsrc, msk) >> 4; \
1204 }
1205
1206#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001207MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x128)
1208MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x64)
1209MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001210#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001211MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x64)
1212MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x32)
1213MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x64)
1214MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x32)
1215MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x16)
1216MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x32)
1217MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x16)
1218MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x8)
1219MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x16)
1220MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x8)
1221MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x4)
1222MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x8)
1223MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224#endif // CONFIG_OBMC
1225
Yaowu Xuf883b422016-08-30 14:01:10 -07001226static void highbd_set_var_fns(AV1_COMP *const cpi) {
1227 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001228 if (cm->use_highbitdepth) {
1229 switch (cm->bit_depth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001230 case AOM_BITS_8:
1231 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits8,
1232 aom_highbd_sad32x16_avg_bits8, aom_highbd_8_variance32x16,
1233 aom_highbd_8_sub_pixel_variance32x16,
1234 aom_highbd_8_sub_pixel_avg_variance32x16, NULL, NULL,
1235 aom_highbd_sad32x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001236
Yaowu Xuf883b422016-08-30 14:01:10 -07001237 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits8,
1238 aom_highbd_sad16x32_avg_bits8, aom_highbd_8_variance16x32,
1239 aom_highbd_8_sub_pixel_variance16x32,
1240 aom_highbd_8_sub_pixel_avg_variance16x32, NULL, NULL,
1241 aom_highbd_sad16x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001242
Yaowu Xuf883b422016-08-30 14:01:10 -07001243 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits8,
1244 aom_highbd_sad64x32_avg_bits8, aom_highbd_8_variance64x32,
1245 aom_highbd_8_sub_pixel_variance64x32,
1246 aom_highbd_8_sub_pixel_avg_variance64x32, NULL, NULL,
1247 aom_highbd_sad64x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001248
Yaowu Xuf883b422016-08-30 14:01:10 -07001249 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits8,
1250 aom_highbd_sad32x64_avg_bits8, aom_highbd_8_variance32x64,
1251 aom_highbd_8_sub_pixel_variance32x64,
1252 aom_highbd_8_sub_pixel_avg_variance32x64, NULL, NULL,
1253 aom_highbd_sad32x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001254
Yaowu Xuf883b422016-08-30 14:01:10 -07001255 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits8,
1256 aom_highbd_sad32x32_avg_bits8, aom_highbd_8_variance32x32,
1257 aom_highbd_8_sub_pixel_variance32x32,
1258 aom_highbd_8_sub_pixel_avg_variance32x32,
1259 aom_highbd_sad32x32x3_bits8, aom_highbd_sad32x32x8_bits8,
1260 aom_highbd_sad32x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001261
Yaowu Xuf883b422016-08-30 14:01:10 -07001262 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits8,
1263 aom_highbd_sad64x64_avg_bits8, aom_highbd_8_variance64x64,
1264 aom_highbd_8_sub_pixel_variance64x64,
1265 aom_highbd_8_sub_pixel_avg_variance64x64,
1266 aom_highbd_sad64x64x3_bits8, aom_highbd_sad64x64x8_bits8,
1267 aom_highbd_sad64x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001268
Yaowu Xuf883b422016-08-30 14:01:10 -07001269 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits8,
1270 aom_highbd_sad16x16_avg_bits8, aom_highbd_8_variance16x16,
1271 aom_highbd_8_sub_pixel_variance16x16,
1272 aom_highbd_8_sub_pixel_avg_variance16x16,
1273 aom_highbd_sad16x16x3_bits8, aom_highbd_sad16x16x8_bits8,
1274 aom_highbd_sad16x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001275
1276 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001277 BLOCK_16X8, aom_highbd_sad16x8_bits8, aom_highbd_sad16x8_avg_bits8,
1278 aom_highbd_8_variance16x8, aom_highbd_8_sub_pixel_variance16x8,
1279 aom_highbd_8_sub_pixel_avg_variance16x8, aom_highbd_sad16x8x3_bits8,
1280 aom_highbd_sad16x8x8_bits8, aom_highbd_sad16x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001281
1282 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001283 BLOCK_8X16, aom_highbd_sad8x16_bits8, aom_highbd_sad8x16_avg_bits8,
1284 aom_highbd_8_variance8x16, aom_highbd_8_sub_pixel_variance8x16,
1285 aom_highbd_8_sub_pixel_avg_variance8x16, aom_highbd_sad8x16x3_bits8,
1286 aom_highbd_sad8x16x8_bits8, aom_highbd_sad8x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001287
1288 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001289 BLOCK_8X8, aom_highbd_sad8x8_bits8, aom_highbd_sad8x8_avg_bits8,
1290 aom_highbd_8_variance8x8, aom_highbd_8_sub_pixel_variance8x8,
1291 aom_highbd_8_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits8,
1292 aom_highbd_sad8x8x8_bits8, aom_highbd_sad8x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001293
Yaowu Xuf883b422016-08-30 14:01:10 -07001294 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits8,
1295 aom_highbd_sad8x4_avg_bits8, aom_highbd_8_variance8x4,
1296 aom_highbd_8_sub_pixel_variance8x4,
1297 aom_highbd_8_sub_pixel_avg_variance8x4, NULL,
1298 aom_highbd_sad8x4x8_bits8, aom_highbd_sad8x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001299
Yaowu Xuf883b422016-08-30 14:01:10 -07001300 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits8,
1301 aom_highbd_sad4x8_avg_bits8, aom_highbd_8_variance4x8,
1302 aom_highbd_8_sub_pixel_variance4x8,
1303 aom_highbd_8_sub_pixel_avg_variance4x8, NULL,
1304 aom_highbd_sad4x8x8_bits8, aom_highbd_sad4x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001305
1306 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001307 BLOCK_4X4, aom_highbd_sad4x4_bits8, aom_highbd_sad4x4_avg_bits8,
1308 aom_highbd_8_variance4x4, aom_highbd_8_sub_pixel_variance4x4,
1309 aom_highbd_8_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits8,
1310 aom_highbd_sad4x4x8_bits8, aom_highbd_sad4x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001311
1312#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001313 HIGHBD_BFP(BLOCK_128X128, aom_highbd_sad128x128_bits8,
1314 aom_highbd_sad128x128_avg_bits8,
1315 aom_highbd_8_variance128x128,
1316 aom_highbd_8_sub_pixel_variance128x128,
1317 aom_highbd_8_sub_pixel_avg_variance128x128,
1318 aom_highbd_sad128x128x3_bits8, aom_highbd_sad128x128x8_bits8,
1319 aom_highbd_sad128x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001320
Yaowu Xuf883b422016-08-30 14:01:10 -07001321 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits8,
1322 aom_highbd_sad128x64_avg_bits8, aom_highbd_8_variance128x64,
1323 aom_highbd_8_sub_pixel_variance128x64,
1324 aom_highbd_8_sub_pixel_avg_variance128x64, NULL, NULL,
1325 aom_highbd_sad128x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001326
Yaowu Xuf883b422016-08-30 14:01:10 -07001327 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits8,
1328 aom_highbd_sad64x128_avg_bits8, aom_highbd_8_variance64x128,
1329 aom_highbd_8_sub_pixel_variance64x128,
1330 aom_highbd_8_sub_pixel_avg_variance64x128, NULL, NULL,
1331 aom_highbd_sad64x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001332#endif // CONFIG_EXT_PARTITION
1333
1334#if CONFIG_EXT_INTER
1335#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001336 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits8,
1337 aom_highbd_masked_variance128x128,
1338 aom_highbd_masked_sub_pixel_variance128x128)
1339 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits8,
1340 aom_highbd_masked_variance128x64,
1341 aom_highbd_masked_sub_pixel_variance128x64)
1342 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits8,
1343 aom_highbd_masked_variance64x128,
1344 aom_highbd_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001345#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001346 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits8,
1347 aom_highbd_masked_variance64x64,
1348 aom_highbd_masked_sub_pixel_variance64x64)
1349 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits8,
1350 aom_highbd_masked_variance64x32,
1351 aom_highbd_masked_sub_pixel_variance64x32)
1352 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits8,
1353 aom_highbd_masked_variance32x64,
1354 aom_highbd_masked_sub_pixel_variance32x64)
1355 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits8,
1356 aom_highbd_masked_variance32x32,
1357 aom_highbd_masked_sub_pixel_variance32x32)
1358 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits8,
1359 aom_highbd_masked_variance32x16,
1360 aom_highbd_masked_sub_pixel_variance32x16)
1361 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits8,
1362 aom_highbd_masked_variance16x32,
1363 aom_highbd_masked_sub_pixel_variance16x32)
1364 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits8,
1365 aom_highbd_masked_variance16x16,
1366 aom_highbd_masked_sub_pixel_variance16x16)
1367 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits8,
1368 aom_highbd_masked_variance8x16,
1369 aom_highbd_masked_sub_pixel_variance8x16)
1370 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits8,
1371 aom_highbd_masked_variance16x8,
1372 aom_highbd_masked_sub_pixel_variance16x8)
1373 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits8,
1374 aom_highbd_masked_variance8x8,
1375 aom_highbd_masked_sub_pixel_variance8x8)
1376 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits8,
1377 aom_highbd_masked_variance4x8,
1378 aom_highbd_masked_sub_pixel_variance4x8)
1379 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits8,
1380 aom_highbd_masked_variance8x4,
1381 aom_highbd_masked_sub_pixel_variance8x4)
1382 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits8,
1383 aom_highbd_masked_variance4x4,
1384 aom_highbd_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001385#endif // CONFIG_EXT_INTER
1386#if CONFIG_OBMC
1387#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001388 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits8,
1389 aom_highbd_obmc_variance128x128,
1390 aom_highbd_obmc_sub_pixel_variance128x128)
1391 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits8,
1392 aom_highbd_obmc_variance128x64,
1393 aom_highbd_obmc_sub_pixel_variance128x64)
1394 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits8,
1395 aom_highbd_obmc_variance64x128,
1396 aom_highbd_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001397#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001398 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits8,
1399 aom_highbd_obmc_variance64x64,
1400 aom_highbd_obmc_sub_pixel_variance64x64)
1401 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits8,
1402 aom_highbd_obmc_variance64x32,
1403 aom_highbd_obmc_sub_pixel_variance64x32)
1404 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits8,
1405 aom_highbd_obmc_variance32x64,
1406 aom_highbd_obmc_sub_pixel_variance32x64)
1407 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits8,
1408 aom_highbd_obmc_variance32x32,
1409 aom_highbd_obmc_sub_pixel_variance32x32)
1410 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits8,
1411 aom_highbd_obmc_variance32x16,
1412 aom_highbd_obmc_sub_pixel_variance32x16)
1413 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits8,
1414 aom_highbd_obmc_variance16x32,
1415 aom_highbd_obmc_sub_pixel_variance16x32)
1416 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits8,
1417 aom_highbd_obmc_variance16x16,
1418 aom_highbd_obmc_sub_pixel_variance16x16)
1419 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits8,
1420 aom_highbd_obmc_variance8x16,
1421 aom_highbd_obmc_sub_pixel_variance8x16)
1422 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits8,
1423 aom_highbd_obmc_variance16x8,
1424 aom_highbd_obmc_sub_pixel_variance16x8)
1425 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits8,
1426 aom_highbd_obmc_variance8x8,
1427 aom_highbd_obmc_sub_pixel_variance8x8)
1428 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits8,
1429 aom_highbd_obmc_variance4x8,
1430 aom_highbd_obmc_sub_pixel_variance4x8)
1431 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits8,
1432 aom_highbd_obmc_variance8x4,
1433 aom_highbd_obmc_sub_pixel_variance8x4)
1434 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits8,
1435 aom_highbd_obmc_variance4x4,
1436 aom_highbd_obmc_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001437#endif // CONFIG_OBMC
1438 break;
1439
Yaowu Xuf883b422016-08-30 14:01:10 -07001440 case AOM_BITS_10:
1441 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits10,
1442 aom_highbd_sad32x16_avg_bits10, aom_highbd_10_variance32x16,
1443 aom_highbd_10_sub_pixel_variance32x16,
1444 aom_highbd_10_sub_pixel_avg_variance32x16, NULL, NULL,
1445 aom_highbd_sad32x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001446
Yaowu Xuf883b422016-08-30 14:01:10 -07001447 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits10,
1448 aom_highbd_sad16x32_avg_bits10, aom_highbd_10_variance16x32,
1449 aom_highbd_10_sub_pixel_variance16x32,
1450 aom_highbd_10_sub_pixel_avg_variance16x32, NULL, NULL,
1451 aom_highbd_sad16x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001452
Yaowu Xuf883b422016-08-30 14:01:10 -07001453 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits10,
1454 aom_highbd_sad64x32_avg_bits10, aom_highbd_10_variance64x32,
1455 aom_highbd_10_sub_pixel_variance64x32,
1456 aom_highbd_10_sub_pixel_avg_variance64x32, NULL, NULL,
1457 aom_highbd_sad64x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001458
Yaowu Xuf883b422016-08-30 14:01:10 -07001459 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits10,
1460 aom_highbd_sad32x64_avg_bits10, aom_highbd_10_variance32x64,
1461 aom_highbd_10_sub_pixel_variance32x64,
1462 aom_highbd_10_sub_pixel_avg_variance32x64, NULL, NULL,
1463 aom_highbd_sad32x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001464
Yaowu Xuf883b422016-08-30 14:01:10 -07001465 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits10,
1466 aom_highbd_sad32x32_avg_bits10, aom_highbd_10_variance32x32,
1467 aom_highbd_10_sub_pixel_variance32x32,
1468 aom_highbd_10_sub_pixel_avg_variance32x32,
1469 aom_highbd_sad32x32x3_bits10, aom_highbd_sad32x32x8_bits10,
1470 aom_highbd_sad32x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001471
Yaowu Xuf883b422016-08-30 14:01:10 -07001472 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits10,
1473 aom_highbd_sad64x64_avg_bits10, aom_highbd_10_variance64x64,
1474 aom_highbd_10_sub_pixel_variance64x64,
1475 aom_highbd_10_sub_pixel_avg_variance64x64,
1476 aom_highbd_sad64x64x3_bits10, aom_highbd_sad64x64x8_bits10,
1477 aom_highbd_sad64x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001478
Yaowu Xuf883b422016-08-30 14:01:10 -07001479 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits10,
1480 aom_highbd_sad16x16_avg_bits10, aom_highbd_10_variance16x16,
1481 aom_highbd_10_sub_pixel_variance16x16,
1482 aom_highbd_10_sub_pixel_avg_variance16x16,
1483 aom_highbd_sad16x16x3_bits10, aom_highbd_sad16x16x8_bits10,
1484 aom_highbd_sad16x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001485
Yaowu Xuf883b422016-08-30 14:01:10 -07001486 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits10,
1487 aom_highbd_sad16x8_avg_bits10, aom_highbd_10_variance16x8,
1488 aom_highbd_10_sub_pixel_variance16x8,
1489 aom_highbd_10_sub_pixel_avg_variance16x8,
1490 aom_highbd_sad16x8x3_bits10, aom_highbd_sad16x8x8_bits10,
1491 aom_highbd_sad16x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001492
Yaowu Xuf883b422016-08-30 14:01:10 -07001493 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits10,
1494 aom_highbd_sad8x16_avg_bits10, aom_highbd_10_variance8x16,
1495 aom_highbd_10_sub_pixel_variance8x16,
1496 aom_highbd_10_sub_pixel_avg_variance8x16,
1497 aom_highbd_sad8x16x3_bits10, aom_highbd_sad8x16x8_bits10,
1498 aom_highbd_sad8x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001499
1500 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001501 BLOCK_8X8, aom_highbd_sad8x8_bits10, aom_highbd_sad8x8_avg_bits10,
1502 aom_highbd_10_variance8x8, aom_highbd_10_sub_pixel_variance8x8,
1503 aom_highbd_10_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits10,
1504 aom_highbd_sad8x8x8_bits10, aom_highbd_sad8x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001505
Yaowu Xuf883b422016-08-30 14:01:10 -07001506 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits10,
1507 aom_highbd_sad8x4_avg_bits10, aom_highbd_10_variance8x4,
1508 aom_highbd_10_sub_pixel_variance8x4,
1509 aom_highbd_10_sub_pixel_avg_variance8x4, NULL,
1510 aom_highbd_sad8x4x8_bits10, aom_highbd_sad8x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001511
Yaowu Xuf883b422016-08-30 14:01:10 -07001512 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits10,
1513 aom_highbd_sad4x8_avg_bits10, aom_highbd_10_variance4x8,
1514 aom_highbd_10_sub_pixel_variance4x8,
1515 aom_highbd_10_sub_pixel_avg_variance4x8, NULL,
1516 aom_highbd_sad4x8x8_bits10, aom_highbd_sad4x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001517
1518 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001519 BLOCK_4X4, aom_highbd_sad4x4_bits10, aom_highbd_sad4x4_avg_bits10,
1520 aom_highbd_10_variance4x4, aom_highbd_10_sub_pixel_variance4x4,
1521 aom_highbd_10_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits10,
1522 aom_highbd_sad4x4x8_bits10, aom_highbd_sad4x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001523
1524#if CONFIG_EXT_PARTITION
1525 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001526 BLOCK_128X128, aom_highbd_sad128x128_bits10,
1527 aom_highbd_sad128x128_avg_bits10, aom_highbd_10_variance128x128,
1528 aom_highbd_10_sub_pixel_variance128x128,
1529 aom_highbd_10_sub_pixel_avg_variance128x128,
1530 aom_highbd_sad128x128x3_bits10, aom_highbd_sad128x128x8_bits10,
1531 aom_highbd_sad128x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001532
Yaowu Xuf883b422016-08-30 14:01:10 -07001533 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits10,
1534 aom_highbd_sad128x64_avg_bits10,
1535 aom_highbd_10_variance128x64,
1536 aom_highbd_10_sub_pixel_variance128x64,
1537 aom_highbd_10_sub_pixel_avg_variance128x64, NULL, NULL,
1538 aom_highbd_sad128x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001539
Yaowu Xuf883b422016-08-30 14:01:10 -07001540 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits10,
1541 aom_highbd_sad64x128_avg_bits10,
1542 aom_highbd_10_variance64x128,
1543 aom_highbd_10_sub_pixel_variance64x128,
1544 aom_highbd_10_sub_pixel_avg_variance64x128, NULL, NULL,
1545 aom_highbd_sad64x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001546#endif // CONFIG_EXT_PARTITION
1547
1548#if CONFIG_EXT_INTER
1549#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001550 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits10,
1551 aom_highbd_10_masked_variance128x128,
1552 aom_highbd_10_masked_sub_pixel_variance128x128)
1553 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits10,
1554 aom_highbd_10_masked_variance128x64,
1555 aom_highbd_10_masked_sub_pixel_variance128x64)
1556 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits10,
1557 aom_highbd_10_masked_variance64x128,
1558 aom_highbd_10_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001559#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001560 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits10,
1561 aom_highbd_10_masked_variance64x64,
1562 aom_highbd_10_masked_sub_pixel_variance64x64)
1563 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits10,
1564 aom_highbd_10_masked_variance64x32,
1565 aom_highbd_10_masked_sub_pixel_variance64x32)
1566 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits10,
1567 aom_highbd_10_masked_variance32x64,
1568 aom_highbd_10_masked_sub_pixel_variance32x64)
1569 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits10,
1570 aom_highbd_10_masked_variance32x32,
1571 aom_highbd_10_masked_sub_pixel_variance32x32)
1572 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits10,
1573 aom_highbd_10_masked_variance32x16,
1574 aom_highbd_10_masked_sub_pixel_variance32x16)
1575 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits10,
1576 aom_highbd_10_masked_variance16x32,
1577 aom_highbd_10_masked_sub_pixel_variance16x32)
1578 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits10,
1579 aom_highbd_10_masked_variance16x16,
1580 aom_highbd_10_masked_sub_pixel_variance16x16)
1581 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits10,
1582 aom_highbd_10_masked_variance8x16,
1583 aom_highbd_10_masked_sub_pixel_variance8x16)
1584 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits10,
1585 aom_highbd_10_masked_variance16x8,
1586 aom_highbd_10_masked_sub_pixel_variance16x8)
1587 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits10,
1588 aom_highbd_10_masked_variance8x8,
1589 aom_highbd_10_masked_sub_pixel_variance8x8)
1590 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits10,
1591 aom_highbd_10_masked_variance4x8,
1592 aom_highbd_10_masked_sub_pixel_variance4x8)
1593 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits10,
1594 aom_highbd_10_masked_variance8x4,
1595 aom_highbd_10_masked_sub_pixel_variance8x4)
1596 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits10,
1597 aom_highbd_10_masked_variance4x4,
1598 aom_highbd_10_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001599#endif // CONFIG_EXT_INTER
1600#if CONFIG_OBMC
1601#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001602 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits10,
1603 aom_highbd_10_obmc_variance128x128,
1604 aom_highbd_10_obmc_sub_pixel_variance128x128)
1605 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits10,
1606 aom_highbd_10_obmc_variance128x64,
1607 aom_highbd_10_obmc_sub_pixel_variance128x64)
1608 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits10,
1609 aom_highbd_10_obmc_variance64x128,
1610 aom_highbd_10_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001611#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001612 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits10,
1613 aom_highbd_10_obmc_variance64x64,
1614 aom_highbd_10_obmc_sub_pixel_variance64x64)
1615 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits10,
1616 aom_highbd_10_obmc_variance64x32,
1617 aom_highbd_10_obmc_sub_pixel_variance64x32)
1618 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits10,
1619 aom_highbd_10_obmc_variance32x64,
1620 aom_highbd_10_obmc_sub_pixel_variance32x64)
1621 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits10,
1622 aom_highbd_10_obmc_variance32x32,
1623 aom_highbd_10_obmc_sub_pixel_variance32x32)
1624 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits10,
1625 aom_highbd_10_obmc_variance32x16,
1626 aom_highbd_10_obmc_sub_pixel_variance32x16)
1627 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits10,
1628 aom_highbd_10_obmc_variance16x32,
1629 aom_highbd_10_obmc_sub_pixel_variance16x32)
1630 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits10,
1631 aom_highbd_10_obmc_variance16x16,
1632 aom_highbd_10_obmc_sub_pixel_variance16x16)
1633 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits10,
1634 aom_highbd_10_obmc_variance8x16,
1635 aom_highbd_10_obmc_sub_pixel_variance8x16)
1636 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits10,
1637 aom_highbd_10_obmc_variance16x8,
1638 aom_highbd_10_obmc_sub_pixel_variance16x8)
1639 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits10,
1640 aom_highbd_10_obmc_variance8x8,
1641 aom_highbd_10_obmc_sub_pixel_variance8x8)
1642 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits10,
1643 aom_highbd_10_obmc_variance4x8,
1644 aom_highbd_10_obmc_sub_pixel_variance4x8)
1645 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits10,
1646 aom_highbd_10_obmc_variance8x4,
1647 aom_highbd_10_obmc_sub_pixel_variance8x4)
1648 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits10,
1649 aom_highbd_10_obmc_variance4x4,
1650 aom_highbd_10_obmc_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001651#endif // CONFIG_OBMC
1652 break;
1653
Yaowu Xuf883b422016-08-30 14:01:10 -07001654 case AOM_BITS_12:
1655 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits12,
1656 aom_highbd_sad32x16_avg_bits12, aom_highbd_12_variance32x16,
1657 aom_highbd_12_sub_pixel_variance32x16,
1658 aom_highbd_12_sub_pixel_avg_variance32x16, NULL, NULL,
1659 aom_highbd_sad32x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001660
Yaowu Xuf883b422016-08-30 14:01:10 -07001661 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits12,
1662 aom_highbd_sad16x32_avg_bits12, aom_highbd_12_variance16x32,
1663 aom_highbd_12_sub_pixel_variance16x32,
1664 aom_highbd_12_sub_pixel_avg_variance16x32, NULL, NULL,
1665 aom_highbd_sad16x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001666
Yaowu Xuf883b422016-08-30 14:01:10 -07001667 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits12,
1668 aom_highbd_sad64x32_avg_bits12, aom_highbd_12_variance64x32,
1669 aom_highbd_12_sub_pixel_variance64x32,
1670 aom_highbd_12_sub_pixel_avg_variance64x32, NULL, NULL,
1671 aom_highbd_sad64x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001672
Yaowu Xuf883b422016-08-30 14:01:10 -07001673 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits12,
1674 aom_highbd_sad32x64_avg_bits12, aom_highbd_12_variance32x64,
1675 aom_highbd_12_sub_pixel_variance32x64,
1676 aom_highbd_12_sub_pixel_avg_variance32x64, NULL, NULL,
1677 aom_highbd_sad32x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001678
Yaowu Xuf883b422016-08-30 14:01:10 -07001679 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits12,
1680 aom_highbd_sad32x32_avg_bits12, aom_highbd_12_variance32x32,
1681 aom_highbd_12_sub_pixel_variance32x32,
1682 aom_highbd_12_sub_pixel_avg_variance32x32,
1683 aom_highbd_sad32x32x3_bits12, aom_highbd_sad32x32x8_bits12,
1684 aom_highbd_sad32x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001685
Yaowu Xuf883b422016-08-30 14:01:10 -07001686 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits12,
1687 aom_highbd_sad64x64_avg_bits12, aom_highbd_12_variance64x64,
1688 aom_highbd_12_sub_pixel_variance64x64,
1689 aom_highbd_12_sub_pixel_avg_variance64x64,
1690 aom_highbd_sad64x64x3_bits12, aom_highbd_sad64x64x8_bits12,
1691 aom_highbd_sad64x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001692
Yaowu Xuf883b422016-08-30 14:01:10 -07001693 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits12,
1694 aom_highbd_sad16x16_avg_bits12, aom_highbd_12_variance16x16,
1695 aom_highbd_12_sub_pixel_variance16x16,
1696 aom_highbd_12_sub_pixel_avg_variance16x16,
1697 aom_highbd_sad16x16x3_bits12, aom_highbd_sad16x16x8_bits12,
1698 aom_highbd_sad16x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001699
Yaowu Xuf883b422016-08-30 14:01:10 -07001700 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits12,
1701 aom_highbd_sad16x8_avg_bits12, aom_highbd_12_variance16x8,
1702 aom_highbd_12_sub_pixel_variance16x8,
1703 aom_highbd_12_sub_pixel_avg_variance16x8,
1704 aom_highbd_sad16x8x3_bits12, aom_highbd_sad16x8x8_bits12,
1705 aom_highbd_sad16x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001706
Yaowu Xuf883b422016-08-30 14:01:10 -07001707 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits12,
1708 aom_highbd_sad8x16_avg_bits12, aom_highbd_12_variance8x16,
1709 aom_highbd_12_sub_pixel_variance8x16,
1710 aom_highbd_12_sub_pixel_avg_variance8x16,
1711 aom_highbd_sad8x16x3_bits12, aom_highbd_sad8x16x8_bits12,
1712 aom_highbd_sad8x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001713
1714 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001715 BLOCK_8X8, aom_highbd_sad8x8_bits12, aom_highbd_sad8x8_avg_bits12,
1716 aom_highbd_12_variance8x8, aom_highbd_12_sub_pixel_variance8x8,
1717 aom_highbd_12_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits12,
1718 aom_highbd_sad8x8x8_bits12, aom_highbd_sad8x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001719
Yaowu Xuf883b422016-08-30 14:01:10 -07001720 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits12,
1721 aom_highbd_sad8x4_avg_bits12, aom_highbd_12_variance8x4,
1722 aom_highbd_12_sub_pixel_variance8x4,
1723 aom_highbd_12_sub_pixel_avg_variance8x4, NULL,
1724 aom_highbd_sad8x4x8_bits12, aom_highbd_sad8x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001725
Yaowu Xuf883b422016-08-30 14:01:10 -07001726 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits12,
1727 aom_highbd_sad4x8_avg_bits12, aom_highbd_12_variance4x8,
1728 aom_highbd_12_sub_pixel_variance4x8,
1729 aom_highbd_12_sub_pixel_avg_variance4x8, NULL,
1730 aom_highbd_sad4x8x8_bits12, aom_highbd_sad4x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001731
1732 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001733 BLOCK_4X4, aom_highbd_sad4x4_bits12, aom_highbd_sad4x4_avg_bits12,
1734 aom_highbd_12_variance4x4, aom_highbd_12_sub_pixel_variance4x4,
1735 aom_highbd_12_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits12,
1736 aom_highbd_sad4x4x8_bits12, aom_highbd_sad4x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001737
1738#if CONFIG_EXT_PARTITION
1739 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001740 BLOCK_128X128, aom_highbd_sad128x128_bits12,
1741 aom_highbd_sad128x128_avg_bits12, aom_highbd_12_variance128x128,
1742 aom_highbd_12_sub_pixel_variance128x128,
1743 aom_highbd_12_sub_pixel_avg_variance128x128,
1744 aom_highbd_sad128x128x3_bits12, aom_highbd_sad128x128x8_bits12,
1745 aom_highbd_sad128x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001746
Yaowu Xuf883b422016-08-30 14:01:10 -07001747 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits12,
1748 aom_highbd_sad128x64_avg_bits12,
1749 aom_highbd_12_variance128x64,
1750 aom_highbd_12_sub_pixel_variance128x64,
1751 aom_highbd_12_sub_pixel_avg_variance128x64, NULL, NULL,
1752 aom_highbd_sad128x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001753
Yaowu Xuf883b422016-08-30 14:01:10 -07001754 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits12,
1755 aom_highbd_sad64x128_avg_bits12,
1756 aom_highbd_12_variance64x128,
1757 aom_highbd_12_sub_pixel_variance64x128,
1758 aom_highbd_12_sub_pixel_avg_variance64x128, NULL, NULL,
1759 aom_highbd_sad64x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001760#endif // CONFIG_EXT_PARTITION
1761
1762#if CONFIG_EXT_INTER
1763#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001764 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits12,
1765 aom_highbd_12_masked_variance128x128,
1766 aom_highbd_12_masked_sub_pixel_variance128x128)
1767 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits12,
1768 aom_highbd_12_masked_variance128x64,
1769 aom_highbd_12_masked_sub_pixel_variance128x64)
1770 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits12,
1771 aom_highbd_12_masked_variance64x128,
1772 aom_highbd_12_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001773#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001774 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits12,
1775 aom_highbd_12_masked_variance64x64,
1776 aom_highbd_12_masked_sub_pixel_variance64x64)
1777 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits12,
1778 aom_highbd_12_masked_variance64x32,
1779 aom_highbd_12_masked_sub_pixel_variance64x32)
1780 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits12,
1781 aom_highbd_12_masked_variance32x64,
1782 aom_highbd_12_masked_sub_pixel_variance32x64)
1783 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits12,
1784 aom_highbd_12_masked_variance32x32,
1785 aom_highbd_12_masked_sub_pixel_variance32x32)
1786 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits12,
1787 aom_highbd_12_masked_variance32x16,
1788 aom_highbd_12_masked_sub_pixel_variance32x16)
1789 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits12,
1790 aom_highbd_12_masked_variance16x32,
1791 aom_highbd_12_masked_sub_pixel_variance16x32)
1792 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits12,
1793 aom_highbd_12_masked_variance16x16,
1794 aom_highbd_12_masked_sub_pixel_variance16x16)
1795 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits12,
1796 aom_highbd_12_masked_variance8x16,
1797 aom_highbd_12_masked_sub_pixel_variance8x16)
1798 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits12,
1799 aom_highbd_12_masked_variance16x8,
1800 aom_highbd_12_masked_sub_pixel_variance16x8)
1801 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits12,
1802 aom_highbd_12_masked_variance8x8,
1803 aom_highbd_12_masked_sub_pixel_variance8x8)
1804 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits12,
1805 aom_highbd_12_masked_variance4x8,
1806 aom_highbd_12_masked_sub_pixel_variance4x8)
1807 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits12,
1808 aom_highbd_12_masked_variance8x4,
1809 aom_highbd_12_masked_sub_pixel_variance8x4)
1810 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits12,
1811 aom_highbd_12_masked_variance4x4,
1812 aom_highbd_12_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001813#endif // CONFIG_EXT_INTER
1814
1815#if CONFIG_OBMC
1816#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001817 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits12,
1818 aom_highbd_12_obmc_variance128x128,
1819 aom_highbd_12_obmc_sub_pixel_variance128x128)
1820 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits12,
1821 aom_highbd_12_obmc_variance128x64,
1822 aom_highbd_12_obmc_sub_pixel_variance128x64)
1823 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits12,
1824 aom_highbd_12_obmc_variance64x128,
1825 aom_highbd_12_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001826#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001827 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits12,
1828 aom_highbd_12_obmc_variance64x64,
1829 aom_highbd_12_obmc_sub_pixel_variance64x64)
1830 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits12,
1831 aom_highbd_12_obmc_variance64x32,
1832 aom_highbd_12_obmc_sub_pixel_variance64x32)
1833 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits12,
1834 aom_highbd_12_obmc_variance32x64,
1835 aom_highbd_12_obmc_sub_pixel_variance32x64)
1836 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits12,
1837 aom_highbd_12_obmc_variance32x32,
1838 aom_highbd_12_obmc_sub_pixel_variance32x32)
1839 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits12,
1840 aom_highbd_12_obmc_variance32x16,
1841 aom_highbd_12_obmc_sub_pixel_variance32x16)
1842 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits12,
1843 aom_highbd_12_obmc_variance16x32,
1844 aom_highbd_12_obmc_sub_pixel_variance16x32)
1845 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits12,
1846 aom_highbd_12_obmc_variance16x16,
1847 aom_highbd_12_obmc_sub_pixel_variance16x16)
1848 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits12,
1849 aom_highbd_12_obmc_variance8x16,
1850 aom_highbd_12_obmc_sub_pixel_variance8x16)
1851 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits12,
1852 aom_highbd_12_obmc_variance16x8,
1853 aom_highbd_12_obmc_sub_pixel_variance16x8)
1854 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits12,
1855 aom_highbd_12_obmc_variance8x8,
1856 aom_highbd_12_obmc_sub_pixel_variance8x8)
1857 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits12,
1858 aom_highbd_12_obmc_variance4x8,
1859 aom_highbd_12_obmc_sub_pixel_variance4x8)
1860 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits12,
1861 aom_highbd_12_obmc_variance8x4,
1862 aom_highbd_12_obmc_sub_pixel_variance8x4)
1863 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits12,
1864 aom_highbd_12_obmc_variance4x4,
1865 aom_highbd_12_obmc_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001866#endif // CONFIG_OBMC
1867 break;
1868
1869 default:
1870 assert(0 &&
Yaowu Xuf883b422016-08-30 14:01:10 -07001871 "cm->bit_depth should be AOM_BITS_8, "
1872 "AOM_BITS_10 or AOM_BITS_12");
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873 }
1874 }
1875}
Yaowu Xuf883b422016-08-30 14:01:10 -07001876#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001877
Yaowu Xuf883b422016-08-30 14:01:10 -07001878static void realloc_segmentation_maps(AV1_COMP *cpi) {
1879 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001880
1881 // Create the encoder segmentation map and set all entries to 0
Yaowu Xuf883b422016-08-30 14:01:10 -07001882 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 CHECK_MEM_ERROR(cm, cpi->segmentation_map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001884 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001885
1886 // Create a map used for cyclic background refresh.
Yaowu Xuf883b422016-08-30 14:01:10 -07001887 if (cpi->cyclic_refresh) av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001888 CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
Yaowu Xuf883b422016-08-30 14:01:10 -07001889 av1_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001890
1891 // Create a map used to mark inactive areas.
Yaowu Xuf883b422016-08-30 14:01:10 -07001892 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001893 CHECK_MEM_ERROR(cm, cpi->active_map.map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001894 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001895
1896 // And a place holder structure is the coding context
1897 // for use if we want to save and restore it
Yaowu Xuf883b422016-08-30 14:01:10 -07001898 aom_free(cpi->coding_context.last_frame_seg_map_copy);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001899 CHECK_MEM_ERROR(cm, cpi->coding_context.last_frame_seg_map_copy,
Yaowu Xuf883b422016-08-30 14:01:10 -07001900 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001901}
1902
Yaowu Xuf883b422016-08-30 14:01:10 -07001903void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
1904 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001905 RATE_CONTROL *const rc = &cpi->rc;
1906
1907 if (cm->profile != oxcf->profile) cm->profile = oxcf->profile;
1908 cm->bit_depth = oxcf->bit_depth;
1909 cm->color_space = oxcf->color_space;
1910 cm->color_range = oxcf->color_range;
1911
1912 if (cm->profile <= PROFILE_1)
Yaowu Xuf883b422016-08-30 14:01:10 -07001913 assert(cm->bit_depth == AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001915 assert(cm->bit_depth > AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001916
1917 cpi->oxcf = *oxcf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001918#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001919 cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
Yaowu Xuf883b422016-08-30 14:01:10 -07001920#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921#if CONFIG_GLOBAL_MOTION
1922 cpi->td.mb.e_mbd.global_motion = cm->global_motion;
1923#endif // CONFIG_GLOBAL_MOTION
1924
Yaowu Xuf883b422016-08-30 14:01:10 -07001925 if ((oxcf->pass == 0) && (oxcf->rc_mode == AOM_Q)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001926 rc->baseline_gf_interval = FIXED_GF_INTERVAL;
1927 } else {
1928 rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
1929 }
1930
1931 cpi->refresh_last_frame = 1;
1932 cpi->refresh_golden_frame = 0;
1933#if CONFIG_EXT_REFS
1934 cpi->refresh_bwd_ref_frame = 0;
1935#endif // CONFIG_EXT_REFS
1936
1937 cm->refresh_frame_context =
1938 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
1939 ? REFRESH_FRAME_CONTEXT_FORWARD
1940 : REFRESH_FRAME_CONTEXT_BACKWARD;
1941 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
1942
Yaowu Xuf883b422016-08-30 14:01:10 -07001943 cm->allow_screen_content_tools = (cpi->oxcf.content == AOM_CONTENT_SCREEN);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001944 if (cm->allow_screen_content_tools) {
1945 MACROBLOCK *x = &cpi->td.mb;
1946 if (x->palette_buffer == 0) {
1947 CHECK_MEM_ERROR(cm, x->palette_buffer,
Yaowu Xuf883b422016-08-30 14:01:10 -07001948 aom_memalign(16, sizeof(*x->palette_buffer)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001949 }
1950 // Reallocate the pc_tree, as it's contents depends on
1951 // the state of cm->allow_screen_content_tools
Yaowu Xuf883b422016-08-30 14:01:10 -07001952 av1_free_pc_tree(&cpi->td);
1953 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001954 }
1955
Yaowu Xuf883b422016-08-30 14:01:10 -07001956 av1_reset_segment_features(cm);
1957 av1_set_high_precision_mv(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001958
1959 {
1960 int i;
1961
1962 for (i = 0; i < MAX_SEGMENTS; i++)
1963 cpi->segment_encode_breakout[i] = cpi->oxcf.encode_breakout;
1964 }
1965 cpi->encode_breakout = cpi->oxcf.encode_breakout;
1966
1967 set_rc_buffer_sizes(rc, &cpi->oxcf);
1968
1969 // Under a configuration change, where maximum_buffer_size may change,
1970 // keep buffer level clipped to the maximum allowed buffer size.
Yaowu Xuf883b422016-08-30 14:01:10 -07001971 rc->bits_off_target = AOMMIN(rc->bits_off_target, rc->maximum_buffer_size);
1972 rc->buffer_level = AOMMIN(rc->buffer_level, rc->maximum_buffer_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001973
1974 // Set up frame rate and related parameters rate control values.
Yaowu Xuf883b422016-08-30 14:01:10 -07001975 av1_new_framerate(cpi, cpi->framerate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001976
1977 // Set absolute upper and lower quality limits
1978 rc->worst_quality = cpi->oxcf.worst_allowed_q;
1979 rc->best_quality = cpi->oxcf.best_allowed_q;
1980
1981 cm->interp_filter = cpi->sf.default_interp_filter;
1982
1983 if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) {
1984 cm->render_width = cpi->oxcf.render_width;
1985 cm->render_height = cpi->oxcf.render_height;
1986 } else {
1987 cm->render_width = cpi->oxcf.width;
1988 cm->render_height = cpi->oxcf.height;
1989 }
1990 cm->width = cpi->oxcf.width;
1991 cm->height = cpi->oxcf.height;
1992
1993 if (cpi->initial_width) {
1994 if (cm->width > cpi->initial_width || cm->height > cpi->initial_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001995 av1_free_context_buffers(cm);
1996 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001997 realloc_segmentation_maps(cpi);
1998 cpi->initial_width = cpi->initial_height = 0;
1999 }
2000 }
2001 update_frame_size(cpi);
2002
2003 cpi->alt_ref_source = NULL;
2004 rc->is_src_frame_alt_ref = 0;
2005
2006#if CONFIG_EXT_REFS
2007 rc->is_bwd_ref_frame = 0;
2008 rc->is_last_bipred_frame = 0;
2009 rc->is_bipred_frame = 0;
2010#endif // CONFIG_EXT_REFS
2011
2012#if 0
2013 // Experimental RD Code
2014 cpi->frame_distortion = 0;
2015 cpi->last_frame_distortion = 0;
2016#endif
2017
2018 set_tile_info(cpi);
2019
2020 cpi->ext_refresh_frame_flags_pending = 0;
2021 cpi->ext_refresh_frame_context_pending = 0;
2022
Yaowu Xuf883b422016-08-30 14:01:10 -07002023#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002024 highbd_set_var_fns(cpi);
2025#endif
2026}
2027
2028#ifndef M_LOG2_E
2029#define M_LOG2_E 0.693147180559945309417
2030#endif
2031#define log2f(x) (log(x) / (float)M_LOG2_E)
2032
2033#if !CONFIG_REF_MV
2034static void cal_nmvjointsadcost(int *mvjointsadcost) {
2035 mvjointsadcost[0] = 600;
2036 mvjointsadcost[1] = 300;
2037 mvjointsadcost[2] = 300;
2038 mvjointsadcost[3] = 300;
2039}
2040#endif
2041
2042static void cal_nmvsadcosts(int *mvsadcost[2]) {
2043 int i = 1;
2044
2045 mvsadcost[0][0] = 0;
2046 mvsadcost[1][0] = 0;
2047
2048 do {
2049 double z = 256 * (2 * (log2f(8 * i) + .6));
2050 mvsadcost[0][i] = (int)z;
2051 mvsadcost[1][i] = (int)z;
2052 mvsadcost[0][-i] = (int)z;
2053 mvsadcost[1][-i] = (int)z;
2054 } while (++i <= MV_MAX);
2055}
2056
2057static void cal_nmvsadcosts_hp(int *mvsadcost[2]) {
2058 int i = 1;
2059
2060 mvsadcost[0][0] = 0;
2061 mvsadcost[1][0] = 0;
2062
2063 do {
2064 double z = 256 * (2 * (log2f(8 * i) + .6));
2065 mvsadcost[0][i] = (int)z;
2066 mvsadcost[1][i] = (int)z;
2067 mvsadcost[0][-i] = (int)z;
2068 mvsadcost[1][-i] = (int)z;
2069 } while (++i <= MV_MAX);
2070}
2071
Yaowu Xuf883b422016-08-30 14:01:10 -07002072static INLINE void init_upsampled_ref_frame_bufs(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002073 int i;
2074
2075 for (i = 0; i < (REF_FRAMES + 1); ++i) {
2076 cpi->upsampled_ref_bufs[i].ref_count = 0;
2077 cpi->upsampled_ref_idx[i] = INVALID_IDX;
2078 }
2079}
2080
Yaowu Xuf883b422016-08-30 14:01:10 -07002081AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
2082 BufferPool *const pool) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002083 unsigned int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07002084 AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));
2085 AV1_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002086
2087 if (!cm) return NULL;
2088
Yaowu Xuf883b422016-08-30 14:01:10 -07002089 av1_zero(*cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090
2091 if (setjmp(cm->error.jmp)) {
2092 cm->error.setjmp = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07002093 av1_remove_compressor(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002094 return 0;
2095 }
2096
2097 cm->error.setjmp = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002098 cm->alloc_mi = av1_enc_alloc_mi;
2099 cm->free_mi = av1_enc_free_mi;
2100 cm->setup_mi = av1_enc_setup_mi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002101
Yaowu Xuf883b422016-08-30 14:01:10 -07002102 CHECK_MEM_ERROR(cm, cm->fc, (FRAME_CONTEXT *)aom_calloc(1, sizeof(*cm->fc)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002103 CHECK_MEM_ERROR(
2104 cm, cm->frame_contexts,
Yaowu Xuf883b422016-08-30 14:01:10 -07002105 (FRAME_CONTEXT *)aom_calloc(FRAME_CONTEXTS, sizeof(*cm->frame_contexts)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002106
2107 cpi->resize_state = 0;
2108 cpi->resize_avg_qp = 0;
2109 cpi->resize_buffer_underflow = 0;
2110 cpi->common.buffer_pool = pool;
2111
2112 init_config(cpi, oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07002113 av1_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002114
2115 cm->current_video_frame = 0;
2116 cpi->partition_search_skippable_frame = 0;
2117 cpi->tile_data = NULL;
2118 cpi->last_show_frame_buf_idx = INVALID_IDX;
2119
2120 realloc_segmentation_maps(cpi);
2121
2122#if CONFIG_REF_MV
2123 for (i = 0; i < NMV_CONTEXTS; ++i) {
2124 CHECK_MEM_ERROR(cm, cpi->nmv_costs[i][0],
Yaowu Xuf883b422016-08-30 14:01:10 -07002125 aom_calloc(MV_VALS, sizeof(*cpi->nmv_costs[i][0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002126 CHECK_MEM_ERROR(cm, cpi->nmv_costs[i][1],
Yaowu Xuf883b422016-08-30 14:01:10 -07002127 aom_calloc(MV_VALS, sizeof(*cpi->nmv_costs[i][1])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002128 CHECK_MEM_ERROR(cm, cpi->nmv_costs_hp[i][0],
Yaowu Xuf883b422016-08-30 14:01:10 -07002129 aom_calloc(MV_VALS, sizeof(*cpi->nmv_costs_hp[i][0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002130 CHECK_MEM_ERROR(cm, cpi->nmv_costs_hp[i][1],
Yaowu Xuf883b422016-08-30 14:01:10 -07002131 aom_calloc(MV_VALS, sizeof(*cpi->nmv_costs_hp[i][1])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002132 }
2133#endif
2134
2135 CHECK_MEM_ERROR(cm, cpi->nmvcosts[0],
Yaowu Xuf883b422016-08-30 14:01:10 -07002136 aom_calloc(MV_VALS, sizeof(*cpi->nmvcosts[0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002137 CHECK_MEM_ERROR(cm, cpi->nmvcosts[1],
Yaowu Xuf883b422016-08-30 14:01:10 -07002138 aom_calloc(MV_VALS, sizeof(*cpi->nmvcosts[1])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002139 CHECK_MEM_ERROR(cm, cpi->nmvcosts_hp[0],
Yaowu Xuf883b422016-08-30 14:01:10 -07002140 aom_calloc(MV_VALS, sizeof(*cpi->nmvcosts_hp[0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002141 CHECK_MEM_ERROR(cm, cpi->nmvcosts_hp[1],
Yaowu Xuf883b422016-08-30 14:01:10 -07002142 aom_calloc(MV_VALS, sizeof(*cpi->nmvcosts_hp[1])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002143 CHECK_MEM_ERROR(cm, cpi->nmvsadcosts[0],
Yaowu Xuf883b422016-08-30 14:01:10 -07002144 aom_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts[0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002145 CHECK_MEM_ERROR(cm, cpi->nmvsadcosts[1],
Yaowu Xuf883b422016-08-30 14:01:10 -07002146 aom_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts[1])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002147 CHECK_MEM_ERROR(cm, cpi->nmvsadcosts_hp[0],
Yaowu Xuf883b422016-08-30 14:01:10 -07002148 aom_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002149 CHECK_MEM_ERROR(cm, cpi->nmvsadcosts_hp[1],
Yaowu Xuf883b422016-08-30 14:01:10 -07002150 aom_calloc(MV_VALS, sizeof(*cpi->nmvsadcosts_hp[1])));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002151
2152 for (i = 0; i < (sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]));
2153 i++) {
2154 CHECK_MEM_ERROR(
2155 cm, cpi->mbgraph_stats[i].mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07002156 aom_calloc(cm->MBs * sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002157 }
2158
2159#if CONFIG_FP_MB_STATS
2160 cpi->use_fp_mb_stats = 0;
2161 if (cpi->use_fp_mb_stats) {
2162 // a place holder used to store the first pass mb stats in the first pass
2163 CHECK_MEM_ERROR(cm, cpi->twopass.frame_mb_stats_buf,
Yaowu Xuf883b422016-08-30 14:01:10 -07002164 aom_calloc(cm->MBs * sizeof(uint8_t), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002165 } else {
2166 cpi->twopass.frame_mb_stats_buf = NULL;
2167 }
2168#endif
2169
2170 cpi->refresh_alt_ref_frame = 0;
2171 cpi->multi_arf_last_grp_enabled = 0;
2172
2173 cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
2174#if CONFIG_INTERNAL_STATS
2175 cpi->b_calculate_blockiness = 1;
2176 cpi->b_calculate_consistency = 1;
2177 cpi->total_inconsistency = 0;
2178 cpi->psnr.worst = 100.0;
2179 cpi->worst_ssim = 100.0;
2180
2181 cpi->count = 0;
2182 cpi->bytes = 0;
2183
2184 if (cpi->b_calculate_psnr) {
2185 cpi->total_sq_error = 0;
2186 cpi->total_samples = 0;
2187 cpi->tot_recode_hits = 0;
2188 cpi->summed_quality = 0;
2189 cpi->summed_weights = 0;
2190 }
2191
2192 cpi->fastssim.worst = 100.0;
2193 cpi->psnrhvs.worst = 100.0;
2194
2195 if (cpi->b_calculate_blockiness) {
2196 cpi->total_blockiness = 0;
2197 cpi->worst_blockiness = 0.0;
2198 }
2199
2200 if (cpi->b_calculate_consistency) {
2201 CHECK_MEM_ERROR(cm, cpi->ssim_vars,
Yaowu Xuf883b422016-08-30 14:01:10 -07002202 aom_malloc(sizeof(*cpi->ssim_vars) * 4 *
Yaowu Xuc27fc142016-08-22 16:08:15 -07002203 cpi->common.mi_rows * cpi->common.mi_cols));
2204 cpi->worst_consistency = 100.0;
2205 }
2206#endif
2207
2208 cpi->first_time_stamp_ever = INT64_MAX;
2209
2210#if CONFIG_REF_MV
2211 for (i = 0; i < NMV_CONTEXTS; ++i) {
2212 cpi->td.mb.nmvcost[i][0] = &cpi->nmv_costs[i][0][MV_MAX];
2213 cpi->td.mb.nmvcost[i][1] = &cpi->nmv_costs[i][1][MV_MAX];
2214 cpi->td.mb.nmvcost_hp[i][0] = &cpi->nmv_costs_hp[i][0][MV_MAX];
2215 cpi->td.mb.nmvcost_hp[i][1] = &cpi->nmv_costs_hp[i][1][MV_MAX];
2216 }
2217#else
2218 cal_nmvjointsadcost(cpi->td.mb.nmvjointsadcost);
2219 cpi->td.mb.nmvcost[0] = &cpi->nmvcosts[0][MV_MAX];
2220 cpi->td.mb.nmvcost[1] = &cpi->nmvcosts[1][MV_MAX];
2221 cpi->td.mb.nmvcost_hp[0] = &cpi->nmvcosts_hp[0][MV_MAX];
2222 cpi->td.mb.nmvcost_hp[1] = &cpi->nmvcosts_hp[1][MV_MAX];
2223#endif
2224 cpi->td.mb.nmvsadcost[0] = &cpi->nmvsadcosts[0][MV_MAX];
2225 cpi->td.mb.nmvsadcost[1] = &cpi->nmvsadcosts[1][MV_MAX];
2226 cal_nmvsadcosts(cpi->td.mb.nmvsadcost);
2227
2228 cpi->td.mb.nmvsadcost_hp[0] = &cpi->nmvsadcosts_hp[0][MV_MAX];
2229 cpi->td.mb.nmvsadcost_hp[1] = &cpi->nmvsadcosts_hp[1][MV_MAX];
2230 cal_nmvsadcosts_hp(cpi->td.mb.nmvsadcost_hp);
2231
2232#ifdef OUTPUT_YUV_SKINMAP
2233 yuv_skinmap_file = fopen("skinmap.yuv", "ab");
2234#endif
2235#ifdef OUTPUT_YUV_REC
2236 yuv_rec_file = fopen("rec.yuv", "wb");
2237#endif
2238
2239#if 0
2240 framepsnr = fopen("framepsnr.stt", "a");
2241 kf_list = fopen("kf_list.stt", "w");
2242#endif
2243
2244 cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
2245
2246 if (oxcf->pass == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002247 av1_init_first_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002248 } else if (oxcf->pass == 2) {
2249 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
2250 const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz);
2251
2252#if CONFIG_FP_MB_STATS
2253 if (cpi->use_fp_mb_stats) {
2254 const size_t psz = cpi->common.MBs * sizeof(uint8_t);
2255 const int ps = (int)(oxcf->firstpass_mb_stats_in.sz / psz);
2256
2257 cpi->twopass.firstpass_mb_stats.mb_stats_start =
2258 oxcf->firstpass_mb_stats_in.buf;
2259 cpi->twopass.firstpass_mb_stats.mb_stats_end =
2260 cpi->twopass.firstpass_mb_stats.mb_stats_start +
2261 (ps - 1) * cpi->common.MBs * sizeof(uint8_t);
2262 }
2263#endif
2264
2265 cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
2266 cpi->twopass.stats_in = cpi->twopass.stats_in_start;
2267 cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];
2268
Yaowu Xuf883b422016-08-30 14:01:10 -07002269 av1_init_second_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002270 }
2271
2272 init_upsampled_ref_frame_bufs(cpi);
2273
Yaowu Xuf883b422016-08-30 14:01:10 -07002274 av1_set_speed_features_framesize_independent(cpi);
2275 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002276
2277 // Allocate memory to store variances for a frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002278 CHECK_MEM_ERROR(cm, cpi->source_diff_var, aom_calloc(cm->MBs, sizeof(diff)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002279 cpi->source_var_thresh = 0;
2280 cpi->frames_till_next_var_check = 0;
2281
2282#define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
2283 cpi->fn_ptr[BT].sdf = SDF; \
2284 cpi->fn_ptr[BT].sdaf = SDAF; \
2285 cpi->fn_ptr[BT].vf = VF; \
2286 cpi->fn_ptr[BT].svf = SVF; \
2287 cpi->fn_ptr[BT].svaf = SVAF; \
2288 cpi->fn_ptr[BT].sdx3f = SDX3F; \
2289 cpi->fn_ptr[BT].sdx8f = SDX8F; \
2290 cpi->fn_ptr[BT].sdx4df = SDX4DF;
2291
2292#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002293 BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
2294 aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
2295 aom_sad128x128x3, aom_sad128x128x8, aom_sad128x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002296
Yaowu Xuf883b422016-08-30 14:01:10 -07002297 BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
2298 aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64, NULL,
2299 NULL, aom_sad128x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002300
Yaowu Xuf883b422016-08-30 14:01:10 -07002301 BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
2302 aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128, NULL,
2303 NULL, aom_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002304#endif // CONFIG_EXT_PARTITION
2305
Yaowu Xuf883b422016-08-30 14:01:10 -07002306 BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
2307 aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16, NULL, NULL,
2308 aom_sad32x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002309
Yaowu Xuf883b422016-08-30 14:01:10 -07002310 BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
2311 aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32, NULL, NULL,
2312 aom_sad16x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002313
Yaowu Xuf883b422016-08-30 14:01:10 -07002314 BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
2315 aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32, NULL, NULL,
2316 aom_sad64x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002317
Yaowu Xuf883b422016-08-30 14:01:10 -07002318 BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
2319 aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64, NULL, NULL,
2320 aom_sad32x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002321
Yaowu Xuf883b422016-08-30 14:01:10 -07002322 BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
2323 aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
2324 aom_sad32x32x3, aom_sad32x32x8, aom_sad32x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002325
Yaowu Xuf883b422016-08-30 14:01:10 -07002326 BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
2327 aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
2328 aom_sad64x64x3, aom_sad64x64x8, aom_sad64x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002329
Yaowu Xuf883b422016-08-30 14:01:10 -07002330 BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
2331 aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
2332 aom_sad16x16x3, aom_sad16x16x8, aom_sad16x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002333
Yaowu Xuf883b422016-08-30 14:01:10 -07002334 BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
2335 aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8, aom_sad16x8x3,
2336 aom_sad16x8x8, aom_sad16x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002337
Yaowu Xuf883b422016-08-30 14:01:10 -07002338 BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
2339 aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16, aom_sad8x16x3,
2340 aom_sad8x16x8, aom_sad8x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002341
Yaowu Xuf883b422016-08-30 14:01:10 -07002342 BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
2343 aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x3,
2344 aom_sad8x8x8, aom_sad8x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002345
Yaowu Xuf883b422016-08-30 14:01:10 -07002346 BFP(BLOCK_8X4, aom_sad8x4, aom_sad8x4_avg, aom_variance8x4,
2347 aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, NULL,
2348 aom_sad8x4x8, aom_sad8x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002349
Yaowu Xuf883b422016-08-30 14:01:10 -07002350 BFP(BLOCK_4X8, aom_sad4x8, aom_sad4x8_avg, aom_variance4x8,
2351 aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, NULL,
2352 aom_sad4x8x8, aom_sad4x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002353
Yaowu Xuf883b422016-08-30 14:01:10 -07002354 BFP(BLOCK_4X4, aom_sad4x4, aom_sad4x4_avg, aom_variance4x4,
2355 aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x3,
2356 aom_sad4x4x8, aom_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002357
2358#if CONFIG_OBMC
2359#define OBFP(BT, OSDF, OVF, OSVF) \
2360 cpi->fn_ptr[BT].osdf = OSDF; \
2361 cpi->fn_ptr[BT].ovf = OVF; \
2362 cpi->fn_ptr[BT].osvf = OSVF;
2363
2364#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002365 OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
2366 aom_obmc_sub_pixel_variance128x128)
2367 OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
2368 aom_obmc_sub_pixel_variance128x64)
2369 OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
2370 aom_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002371#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002372 OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
2373 aom_obmc_sub_pixel_variance64x64)
2374 OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
2375 aom_obmc_sub_pixel_variance64x32)
2376 OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
2377 aom_obmc_sub_pixel_variance32x64)
2378 OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
2379 aom_obmc_sub_pixel_variance32x32)
2380 OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
2381 aom_obmc_sub_pixel_variance32x16)
2382 OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
2383 aom_obmc_sub_pixel_variance16x32)
2384 OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
2385 aom_obmc_sub_pixel_variance16x16)
2386 OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
2387 aom_obmc_sub_pixel_variance16x8)
2388 OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
2389 aom_obmc_sub_pixel_variance8x16)
2390 OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
2391 aom_obmc_sub_pixel_variance8x8)
2392 OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
2393 aom_obmc_sub_pixel_variance4x8)
2394 OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
2395 aom_obmc_sub_pixel_variance8x4)
2396 OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
2397 aom_obmc_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002398#endif // CONFIG_OBMC
2399
2400#if CONFIG_EXT_INTER
2401#define MBFP(BT, MSDF, MVF, MSVF) \
2402 cpi->fn_ptr[BT].msdf = MSDF; \
2403 cpi->fn_ptr[BT].mvf = MVF; \
2404 cpi->fn_ptr[BT].msvf = MSVF;
2405
2406#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002407 MBFP(BLOCK_128X128, aom_masked_sad128x128, aom_masked_variance128x128,
2408 aom_masked_sub_pixel_variance128x128)
2409 MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_variance128x64,
2410 aom_masked_sub_pixel_variance128x64)
2411 MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_variance64x128,
2412 aom_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002413#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002414 MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_variance64x64,
2415 aom_masked_sub_pixel_variance64x64)
2416 MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_variance64x32,
2417 aom_masked_sub_pixel_variance64x32)
2418 MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_variance32x64,
2419 aom_masked_sub_pixel_variance32x64)
2420 MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_variance32x32,
2421 aom_masked_sub_pixel_variance32x32)
2422 MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_variance32x16,
2423 aom_masked_sub_pixel_variance32x16)
2424 MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_variance16x32,
2425 aom_masked_sub_pixel_variance16x32)
2426 MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_variance16x16,
2427 aom_masked_sub_pixel_variance16x16)
2428 MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_variance16x8,
2429 aom_masked_sub_pixel_variance16x8)
2430 MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_variance8x16,
2431 aom_masked_sub_pixel_variance8x16)
2432 MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_variance8x8,
2433 aom_masked_sub_pixel_variance8x8)
2434 MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_variance4x8,
2435 aom_masked_sub_pixel_variance4x8)
2436 MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_variance8x4,
2437 aom_masked_sub_pixel_variance8x4)
2438 MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_variance4x4,
2439 aom_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002440#endif // CONFIG_EXT_INTER
2441
Yaowu Xuf883b422016-08-30 14:01:10 -07002442#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002443 highbd_set_var_fns(cpi);
2444#endif
2445
Yaowu Xuf883b422016-08-30 14:01:10 -07002446 /* av1_init_quantizer() is first called here. Add check in
2447 * av1_frame_init_quantizer() so that av1_init_quantizer is only
Yaowu Xuc27fc142016-08-22 16:08:15 -07002448 * called later when needed. This will avoid unnecessary calls of
Yaowu Xuf883b422016-08-30 14:01:10 -07002449 * av1_init_quantizer() for every frame.
Yaowu Xuc27fc142016-08-22 16:08:15 -07002450 */
Yaowu Xuf883b422016-08-30 14:01:10 -07002451 av1_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002452#if CONFIG_AOM_QM
2453 aom_qm_init(cm);
2454#endif
2455
Yaowu Xuf883b422016-08-30 14:01:10 -07002456 av1_loop_filter_init(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002457#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07002458 av1_loop_restoration_precal();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002459#endif // CONFIG_LOOP_RESTORATION
2460
2461 cm->error.setjmp = 0;
2462
2463 return cpi;
2464}
2465
2466#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
2467
2468#define SNPRINT2(H, T, V) \
2469 snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
2470
Yaowu Xuf883b422016-08-30 14:01:10 -07002471void av1_remove_compressor(AV1_COMP *cpi) {
2472 AV1_COMMON *cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002473 unsigned int i;
2474 int t;
2475
2476 if (!cpi) return;
2477
2478 cm = &cpi->common;
2479 if (cm->current_video_frame > 0) {
2480#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07002481 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002482
2483 if (cpi->oxcf.pass != 1) {
2484 char headings[512] = { 0 };
2485 char results[512] = { 0 };
2486 FILE *f = fopen("opsnr.stt", "a");
2487 double time_encoded =
2488 (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
2489 10000000.000;
2490 double total_encode_time =
2491 (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
2492 const double dr =
2493 (double)cpi->bytes * (double)8 / (double)1000 / time_encoded;
2494 const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
2495 const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
2496 const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
2497
2498 if (cpi->b_calculate_psnr) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002499 const double total_psnr = aom_sse_to_psnr(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002500 (double)cpi->total_samples, peak, (double)cpi->total_sq_error);
2501 const double total_ssim =
2502 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
2503 snprintf(headings, sizeof(headings),
2504 "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
Yaowu Xuf883b422016-08-30 14:01:10 -07002505 "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
Yaowu Xuc27fc142016-08-22 16:08:15 -07002506 "WstPsnr\tWstSsim\tWstFast\tWstHVS");
2507 snprintf(results, sizeof(results),
2508 "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2509 "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2510 "%7.3f\t%7.3f\t%7.3f\t%7.3f",
2511 dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr,
2512 cpi->psnr.stat[ALL] / cpi->count, total_psnr, total_ssim,
2513 total_ssim, cpi->fastssim.stat[ALL] / cpi->count,
2514 cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst,
2515 cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst);
2516
2517 if (cpi->b_calculate_blockiness) {
2518 SNPRINT(headings, "\t Block\tWstBlck");
2519 SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count);
2520 SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness);
2521 }
2522
2523 if (cpi->b_calculate_consistency) {
2524 double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07002525 aom_sse_to_psnr((double)cpi->total_samples, peak,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002526 (double)cpi->total_inconsistency);
2527
2528 SNPRINT(headings, "\tConsist\tWstCons");
2529 SNPRINT2(results, "\t%7.3f", consistency);
2530 SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
2531 }
Sarah Parkerf97b7862016-08-25 17:42:57 -07002532 fprintf(f, "%s\t Time\tRcErr\tAbsErr\n", headings);
2533 fprintf(f, "%s\t%8.0f\t%7.2f\t%7.2f\n", results, total_encode_time,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002534 rate_err, fabs(rate_err));
2535 }
2536
2537 fclose(f);
2538 }
2539
2540#endif
2541
2542#if 0
2543 {
2544 printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000);
2545 printf("\n_frames recive_data encod_mb_row compress_frame Total\n");
2546 printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame,
2547 cpi->time_receive_data / 1000, cpi->time_encode_sb_row / 1000,
2548 cpi->time_compress_data / 1000,
2549 (cpi->time_receive_data + cpi->time_compress_data) / 1000);
2550 }
2551#endif
2552 }
2553
2554 for (t = 0; t < cpi->num_workers; ++t) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002555 AVxWorker *const worker = &cpi->workers[t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002556 EncWorkerData *const thread_data = &cpi->tile_thr_data[t];
2557
2558 // Deallocate allocated threads.
Yaowu Xuf883b422016-08-30 14:01:10 -07002559 aom_get_worker_interface()->end(worker);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002560
2561 // Deallocate allocated thread data.
2562 if (t < cpi->num_workers - 1) {
2563 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -07002564 aom_free(thread_data->td->mb.palette_buffer);
2565 aom_free(thread_data->td->counts);
2566 av1_free_pc_tree(thread_data->td);
2567 av1_free_var_tree(thread_data->td);
2568 aom_free(thread_data->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002569 }
2570 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002571 aom_free(cpi->tile_thr_data);
2572 aom_free(cpi->workers);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002573
Yaowu Xuf883b422016-08-30 14:01:10 -07002574 if (cpi->num_workers > 1) av1_loop_filter_dealloc(&cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002575
2576 dealloc_compressor_data(cpi);
2577
2578 for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
2579 ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002580 aom_free(cpi->mbgraph_stats[i].mb_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002581 }
2582
2583#if CONFIG_FP_MB_STATS
2584 if (cpi->use_fp_mb_stats) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002585 aom_free(cpi->twopass.frame_mb_stats_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002586 cpi->twopass.frame_mb_stats_buf = NULL;
2587 }
2588#endif
2589
Yaowu Xuf883b422016-08-30 14:01:10 -07002590 av1_remove_common(cm);
2591 av1_free_ref_frame_buffers(cm->buffer_pool);
2592 aom_free(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002593
2594#ifdef OUTPUT_YUV_SKINMAP
2595 fclose(yuv_skinmap_file);
2596#endif
2597#ifdef OUTPUT_YUV_REC
2598 fclose(yuv_rec_file);
2599#endif
2600
2601#if 0
2602
2603 if (keyfile)
2604 fclose(keyfile);
2605
2606 if (framepsnr)
2607 fclose(framepsnr);
2608
2609 if (kf_list)
2610 fclose(kf_list);
2611
2612#endif
2613}
2614
Yaowu Xuf883b422016-08-30 14:01:10 -07002615static void generate_psnr_packet(AV1_COMP *cpi) {
2616 struct aom_codec_cx_pkt pkt;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002617 int i;
2618 PSNR_STATS psnr;
Yaowu Xuf883b422016-08-30 14:01:10 -07002619#if CONFIG_AOM_HIGHBITDEPTH
2620 aom_calc_highbd_psnr(cpi->Source, cpi->common.frame_to_show, &psnr,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002621 cpi->td.mb.e_mbd.bd, cpi->oxcf.input_bit_depth);
2622#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002623 aom_calc_psnr(cpi->Source, cpi->common.frame_to_show, &psnr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002624#endif
2625
2626 for (i = 0; i < 4; ++i) {
2627 pkt.data.psnr.samples[i] = psnr.samples[i];
2628 pkt.data.psnr.sse[i] = psnr.sse[i];
2629 pkt.data.psnr.psnr[i] = psnr.psnr[i];
2630 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002631 pkt.kind = AOM_CODEC_PSNR_PKT;
2632 aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002633}
2634
Yaowu Xuf883b422016-08-30 14:01:10 -07002635int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002636 if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
2637
2638 cpi->ref_frame_flags = ref_frame_flags;
2639 return 0;
2640}
2641
Yaowu Xuf883b422016-08-30 14:01:10 -07002642void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags) {
2643 cpi->ext_refresh_golden_frame = (ref_frame_flags & AOM_GOLD_FLAG) != 0;
2644 cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & AOM_ALT_FLAG) != 0;
2645 cpi->ext_refresh_last_frame = (ref_frame_flags & AOM_LAST_FLAG) != 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002646 cpi->ext_refresh_frame_flags_pending = 1;
2647}
2648
Yaowu Xuf883b422016-08-30 14:01:10 -07002649static YV12_BUFFER_CONFIG *get_av1_ref_frame_buffer(
2650 AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002651 MV_REFERENCE_FRAME ref_frame = NONE;
Yaowu Xuf883b422016-08-30 14:01:10 -07002652 if (ref_frame_flag == AOM_LAST_FLAG) ref_frame = LAST_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002653#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002654 else if (ref_frame_flag == AOM_LAST2_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002655 ref_frame = LAST2_FRAME;
Yaowu Xuf883b422016-08-30 14:01:10 -07002656 else if (ref_frame_flag == AOM_LAST3_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002657 ref_frame = LAST3_FRAME;
2658#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002659 else if (ref_frame_flag == AOM_GOLD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002660 ref_frame = GOLDEN_FRAME;
2661#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002662 else if (ref_frame_flag == AOM_BWD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002663 ref_frame = BWDREF_FRAME;
2664#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002665 else if (ref_frame_flag == AOM_ALT_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002666 ref_frame = ALTREF_FRAME;
2667
2668 return ref_frame == NONE ? NULL : get_ref_frame_buffer(cpi, ref_frame);
2669}
2670
Yaowu Xuf883b422016-08-30 14:01:10 -07002671int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002672 YV12_BUFFER_CONFIG *sd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002673 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002674 if (cfg) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002675 aom_yv12_copy_frame(cfg, sd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002676 return 0;
2677 } else {
2678 return -1;
2679 }
2680}
2681
Yaowu Xuf883b422016-08-30 14:01:10 -07002682int av1_set_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
2683 YV12_BUFFER_CONFIG *sd) {
2684 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
2685 if (cfg) {
2686 aom_yv12_copy_frame(sd, cfg);
2687 return 0;
2688 } else {
2689 return -1;
2690 }
2691}
2692
2693int av1_update_entropy(AV1_COMP *cpi, int update) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002694 cpi->ext_refresh_frame_context = update;
2695 cpi->ext_refresh_frame_context_pending = 1;
2696 return 0;
2697}
2698
2699#if defined(OUTPUT_YUV_DENOISED) || defined(OUTPUT_YUV_SKINMAP)
2700// The denoiser buffer is allocated as a YUV 440 buffer. This function writes it
2701// as YUV 420. We simply use the top-left pixels of the UV buffers, since we do
2702// not denoise the UV channels at this time. If ever we implement UV channel
2703// denoising we will have to modify this.
Yaowu Xuf883b422016-08-30 14:01:10 -07002704void aom_write_yuv_frame_420(YV12_BUFFER_CONFIG *s, FILE *f) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002705 uint8_t *src = s->y_buffer;
2706 int h = s->y_height;
2707
2708 do {
2709 fwrite(src, s->y_width, 1, f);
2710 src += s->y_stride;
2711 } while (--h);
2712
2713 src = s->u_buffer;
2714 h = s->uv_height;
2715
2716 do {
2717 fwrite(src, s->uv_width, 1, f);
2718 src += s->uv_stride;
2719 } while (--h);
2720
2721 src = s->v_buffer;
2722 h = s->uv_height;
2723
2724 do {
2725 fwrite(src, s->uv_width, 1, f);
2726 src += s->uv_stride;
2727 } while (--h);
2728}
2729#endif
2730
2731#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002732static void check_show_existing_frame(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002733 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
Yaowu Xuf883b422016-08-30 14:01:10 -07002734 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002735 const FRAME_UPDATE_TYPE next_frame_update_type =
2736 gf_group->update_type[gf_group->index];
2737 const int which_arf = gf_group->arf_update_idx[gf_group->index];
2738 if (cpi->rc.is_last_bipred_frame) {
2739 // NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
2740 // needed next to show the BWDREF_FRAME, which is pointed by
2741 // the last_fb_idxes[0] after reference frame buffer update
2742 cpi->rc.is_last_bipred_frame = 0;
2743 cm->show_existing_frame = 1;
2744 cpi->existing_fb_idx_to_show = cpi->lst_fb_idxes[0];
2745 } else if (cpi->is_arf_filter_off[which_arf] &&
2746 (next_frame_update_type == OVERLAY_UPDATE ||
2747 next_frame_update_type == INTNL_OVERLAY_UPDATE)) {
2748 // Other parameters related to OVERLAY_UPDATE will be taken care of
Yaowu Xuf883b422016-08-30 14:01:10 -07002749 // in av1_rc_get_second_pass_params(cpi)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002750 cm->show_existing_frame = 1;
2751 cpi->rc.is_src_frame_alt_ref = 1;
2752 cpi->existing_fb_idx_to_show = cpi->alt_fb_idx;
2753 cpi->is_arf_filter_off[which_arf] = 0;
2754 } else {
2755 cm->show_existing_frame = 0;
2756 }
2757 cpi->rc.is_src_frame_ext_arf = 0;
2758}
2759#endif // CONFIG_EXT_REFS
2760
2761#ifdef OUTPUT_YUV_REC
Yaowu Xuf883b422016-08-30 14:01:10 -07002762void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002763 uint8_t *src = s->y_buffer;
2764 int h = cm->height;
2765
Yaowu Xuf883b422016-08-30 14:01:10 -07002766#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002767 if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
2768 uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
2769
2770 do {
2771 fwrite(src16, s->y_width, 2, yuv_rec_file);
2772 src16 += s->y_stride;
2773 } while (--h);
2774
2775 src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
2776 h = s->uv_height;
2777
2778 do {
2779 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2780 src16 += s->uv_stride;
2781 } while (--h);
2782
2783 src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
2784 h = s->uv_height;
2785
2786 do {
2787 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2788 src16 += s->uv_stride;
2789 } while (--h);
2790
2791 fflush(yuv_rec_file);
2792 return;
2793 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002794#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002795
2796 do {
2797 fwrite(src, s->y_width, 1, yuv_rec_file);
2798 src += s->y_stride;
2799 } while (--h);
2800
2801 src = s->u_buffer;
2802 h = s->uv_height;
2803
2804 do {
2805 fwrite(src, s->uv_width, 1, yuv_rec_file);
2806 src += s->uv_stride;
2807 } while (--h);
2808
2809 src = s->v_buffer;
2810 h = s->uv_height;
2811
2812 do {
2813 fwrite(src, s->uv_width, 1, yuv_rec_file);
2814 src += s->uv_stride;
2815 } while (--h);
2816
2817 fflush(yuv_rec_file);
2818}
2819#endif // OUTPUT_YUV_REC
2820
Yaowu Xuf883b422016-08-30 14:01:10 -07002821#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002822static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
2823 YV12_BUFFER_CONFIG *dst,
2824 int bd) {
2825#else
2826static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
2827 YV12_BUFFER_CONFIG *dst) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002828#endif // CONFIG_AOM_HIGHBITDEPTH
2829 // TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07002830 int i;
2831 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2832 src->v_buffer };
2833 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2834 const int src_widths[3] = { src->y_crop_width, src->uv_crop_width,
2835 src->uv_crop_width };
2836 const int src_heights[3] = { src->y_crop_height, src->uv_crop_height,
2837 src->uv_crop_height };
2838 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2839 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2840 const int dst_widths[3] = { dst->y_crop_width, dst->uv_crop_width,
2841 dst->uv_crop_width };
2842 const int dst_heights[3] = { dst->y_crop_height, dst->uv_crop_height,
2843 dst->uv_crop_height };
2844
2845 for (i = 0; i < MAX_MB_PLANE; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002846#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002847 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002848 av1_highbd_resize_plane(srcs[i], src_heights[i], src_widths[i],
2849 src_strides[i], dsts[i], dst_heights[i],
2850 dst_widths[i], dst_strides[i], bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002851 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002852 av1_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
2853 dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002854 }
2855#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002856 av1_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
2857 dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
2858#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002859 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002860 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002861}
2862
Yaowu Xuf883b422016-08-30 14:01:10 -07002863#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002864static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2865 YV12_BUFFER_CONFIG *dst, int planes,
2866 int bd) {
2867#else
2868static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2869 YV12_BUFFER_CONFIG *dst, int planes) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002870#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871 const int src_w = src->y_crop_width;
2872 const int src_h = src->y_crop_height;
2873 const int dst_w = dst->y_crop_width;
2874 const int dst_h = dst->y_crop_height;
2875 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2876 src->v_buffer };
2877 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2878 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2879 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2880 const InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -07002881 av1_get_interp_filter_params(EIGHTTAP_REGULAR);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002882 const int16_t *kernel = interp_filter_params.filter_ptr;
2883 const int taps = interp_filter_params.taps;
2884 int x, y, i;
2885
2886 for (y = 0; y < dst_h; y += 16) {
2887 for (x = 0; x < dst_w; x += 16) {
2888 for (i = 0; i < planes; ++i) {
2889 const int factor = (i == 0 || i == 3 ? 1 : 2);
2890 const int x_q4 = x * (16 / factor) * src_w / dst_w;
2891 const int y_q4 = y * (16 / factor) * src_h / dst_h;
2892 const int src_stride = src_strides[i];
2893 const int dst_stride = dst_strides[i];
2894 const uint8_t *src_ptr = srcs[i] +
2895 (y / factor) * src_h / dst_h * src_stride +
2896 (x / factor) * src_w / dst_w;
2897 uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor);
2898
Yaowu Xuf883b422016-08-30 14:01:10 -07002899#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002900 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002901 aom_highbd_convolve8(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002902 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2903 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2904 16 / factor, 16 / factor, bd);
2905 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002906 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002907 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2908 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2909 16 / factor, 16 / factor);
2910 }
2911#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002912 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002913 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2914 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2915 16 / factor, 16 / factor);
Yaowu Xuf883b422016-08-30 14:01:10 -07002916#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002917 }
2918 }
2919 }
2920
2921 if (planes == 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07002922 aom_extend_frame_borders_y(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002923 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002924 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002925}
2926
Yaowu Xuf883b422016-08-30 14:01:10 -07002927static int scale_down(AV1_COMP *cpi, int q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002928 RATE_CONTROL *const rc = &cpi->rc;
2929 GF_GROUP *const gf_group = &cpi->twopass.gf_group;
2930 int scale = 0;
2931 assert(frame_is_kf_gf_arf(cpi));
2932
2933 if (rc->frame_size_selector == UNSCALED &&
2934 q >= rc->rf_level_maxq[gf_group->rf_level[gf_group->index]]) {
2935 const int max_size_thresh =
2936 (int)(rate_thresh_mult[SCALE_STEP1] *
Yaowu Xuf883b422016-08-30 14:01:10 -07002937 AOMMAX(rc->this_frame_target, rc->avg_frame_bandwidth));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002938 scale = rc->projected_frame_size > max_size_thresh ? 1 : 0;
2939 }
2940 return scale;
2941}
2942
2943// Function to test for conditions that indicate we should loop
2944// back and recode a frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002945static int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit, int q,
2946 int maxq, int minq) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002947 const RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07002948 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002949 const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
2950 int force_recode = 0;
2951
2952 if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
2953 (cpi->sf.recode_loop == ALLOW_RECODE) ||
2954 (frame_is_kfgfarf && (cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
2955 if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) &&
2956 scale_down(cpi, q)) {
2957 // Code this group at a lower resolution.
2958 cpi->resize_pending = 1;
2959 return 1;
2960 }
2961
2962 // TODO(agrange) high_limit could be greater than the scale-down threshold.
2963 if ((rc->projected_frame_size > high_limit && q < maxq) ||
2964 (rc->projected_frame_size < low_limit && q > minq)) {
2965 force_recode = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002966 } else if (cpi->oxcf.rc_mode == AOM_CQ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002967 // Deal with frame undershoot and whether or not we are
2968 // below the automatically set cq level.
2969 if (q > oxcf->cq_level &&
2970 rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
2971 force_recode = 1;
2972 }
2973 }
2974 }
2975 return force_recode;
2976}
2977
2978static INLINE int get_free_upsampled_ref_buf(EncRefCntBuffer *ubufs) {
2979 int i;
2980
2981 for (i = 0; i < (REF_FRAMES + 1); i++) {
2982 if (!ubufs[i].ref_count) {
2983 return i;
2984 }
2985 }
2986 return INVALID_IDX;
2987}
2988
2989// Up-sample 1 reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002990static INLINE int upsample_ref_frame(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002991 const YV12_BUFFER_CONFIG *const ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002992 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002993 EncRefCntBuffer *ubufs = cpi->upsampled_ref_bufs;
2994 int new_uidx = get_free_upsampled_ref_buf(ubufs);
2995
2996 if (new_uidx == INVALID_IDX) {
2997 return INVALID_IDX;
2998 } else {
2999 YV12_BUFFER_CONFIG *upsampled_ref = &ubufs[new_uidx].buf;
3000
3001 // Can allocate buffer for Y plane only.
3002 if (upsampled_ref->buffer_alloc_sz < (ref->buffer_alloc_sz << 6))
Yaowu Xuf883b422016-08-30 14:01:10 -07003003 if (aom_realloc_frame_buffer(upsampled_ref, (cm->width << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003004 (cm->height << 3), cm->subsampling_x,
3005 cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003006#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003007 cm->use_highbitdepth,
3008#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003009 (AOM_BORDER_IN_PIXELS << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003010 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003011 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003012 "Failed to allocate up-sampled frame buffer");
3013
3014// Currently, only Y plane is up-sampled, U, V are not used.
Yaowu Xuf883b422016-08-30 14:01:10 -07003015#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003016 scale_and_extend_frame(ref, upsampled_ref, 1, (int)cm->bit_depth);
3017#else
3018 scale_and_extend_frame(ref, upsampled_ref, 1);
3019#endif
3020 return new_uidx;
3021 }
3022}
3023
3024#define DUMP_REF_FRAME_IMAGES 0
3025
3026#if DUMP_REF_FRAME_IMAGES == 1
Yaowu Xuf883b422016-08-30 14:01:10 -07003027static int dump_one_image(AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003028 const YV12_BUFFER_CONFIG *const ref_buf,
3029 char *file_name) {
3030 int h;
3031 FILE *f_ref = NULL;
3032
3033 if (ref_buf == NULL) {
3034 printf("Frame data buffer is NULL.\n");
Yaowu Xuf883b422016-08-30 14:01:10 -07003035 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003036 }
3037
3038 if ((f_ref = fopen(file_name, "wb")) == NULL) {
3039 printf("Unable to open file %s to write.\n", file_name);
Yaowu Xuf883b422016-08-30 14:01:10 -07003040 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003041 }
3042
3043 // --- Y ---
3044 for (h = 0; h < cm->height; ++h) {
3045 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
3046 }
3047 // --- U ---
3048 for (h = 0; h < (cm->height >> 1); ++h) {
3049 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
3050 f_ref);
3051 }
3052 // --- V ---
3053 for (h = 0; h < (cm->height >> 1); ++h) {
3054 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
3055 f_ref);
3056 }
3057
3058 fclose(f_ref);
3059
Yaowu Xuf883b422016-08-30 14:01:10 -07003060 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003061}
3062
Yaowu Xuf883b422016-08-30 14:01:10 -07003063static void dump_ref_frame_images(AV1_COMP *cpi) {
3064 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003065 MV_REFERENCE_FRAME ref_frame;
3066
3067 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3068 char file_name[256] = "";
3069 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
3070 cm->current_video_frame, ref_frame);
3071 dump_one_image(cm, get_ref_frame_buffer(cpi, ref_frame), file_name);
3072 }
3073}
3074#endif // DUMP_REF_FRAME_IMAGES == 1
3075
3076#if CONFIG_EXT_REFS
3077// This function is used to shift the virtual indices of last reference frames
3078// as follows:
3079// LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3080// when the LAST_FRAME is updated.
Yaowu Xuf883b422016-08-30 14:01:10 -07003081static INLINE void shift_last_ref_frames(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003082 int ref_frame;
3083 for (ref_frame = LAST_REF_FRAMES - 1; ref_frame > 0; --ref_frame) {
3084 cpi->lst_fb_idxes[ref_frame] = cpi->lst_fb_idxes[ref_frame - 1];
3085
3086 // [0] is allocated to the current coded frame. The statistics for the
3087 // reference frames start at [1].
3088 if (!cpi->rc.is_src_frame_alt_ref) {
3089 memcpy(cpi->interp_filter_selected[ref_frame + 1],
3090 cpi->interp_filter_selected[ref_frame],
3091 sizeof(cpi->interp_filter_selected[ref_frame]));
3092 }
3093 }
3094}
3095#endif
3096
Yaowu Xuf883b422016-08-30 14:01:10 -07003097void av1_update_reference_frames(AV1_COMP *cpi) {
3098 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003099 BufferPool *const pool = cm->buffer_pool;
3100 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3101 int new_uidx = 0;
3102
3103 // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3104 // for the purpose to verify no mismatch between encoder and decoder.
3105 if (cm->show_frame) cpi->last_show_frame_buf_idx = cm->new_fb_idx;
3106
3107 if (use_upsampled_ref) {
3108#if CONFIG_EXT_REFS
3109 if (cm->show_existing_frame) {
3110 new_uidx = cpi->upsampled_ref_idx[cpi->existing_fb_idx_to_show];
3111 // TODO(zoeliu): Once following is confirmed, remove it.
3112 assert(cpi->upsampled_ref_bufs[new_uidx].ref_count > 0);
3113 } else {
3114#endif // CONFIG_EXT_REFS
3115 // Up-sample the current encoded frame.
3116 RefCntBuffer *bufs = pool->frame_bufs;
3117 const YV12_BUFFER_CONFIG *const ref = &bufs[cm->new_fb_idx].buf;
3118
3119 new_uidx = upsample_ref_frame(cpi, ref);
3120#if CONFIG_EXT_REFS
3121 assert(new_uidx != INVALID_IDX);
3122 }
3123#endif // CONFIG_EXT_REFS
3124 }
3125 // At this point the new frame has been encoded.
3126 // If any buffer copy / swapping is signaled it should be done here.
3127 if (cm->frame_type == KEY_FRAME) {
3128 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3129 cm->new_fb_idx);
3130#if CONFIG_EXT_REFS
3131 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3132 cm->new_fb_idx);
3133#endif // CONFIG_EXT_REFS
3134 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3135 cm->new_fb_idx);
3136
3137 if (use_upsampled_ref) {
3138 uref_cnt_fb(cpi->upsampled_ref_bufs,
3139 &cpi->upsampled_ref_idx[cpi->gld_fb_idx], new_uidx);
3140#if CONFIG_EXT_REFS
3141 uref_cnt_fb(cpi->upsampled_ref_bufs,
3142 &cpi->upsampled_ref_idx[cpi->bwd_fb_idx], new_uidx);
3143#endif // CONFIG_EXT_REFS
3144 uref_cnt_fb(cpi->upsampled_ref_bufs,
3145 &cpi->upsampled_ref_idx[cpi->alt_fb_idx], new_uidx);
3146 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003147 } else if (av1_preserve_existing_gf(cpi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003148 // We have decided to preserve the previously existing golden frame as our
3149 // new ARF frame. However, in the short term in function
Yaowu Xuf883b422016-08-30 14:01:10 -07003150 // av1_bitstream.c::get_refresh_mask() we left it in the GF slot and, if
Yaowu Xuc27fc142016-08-22 16:08:15 -07003151 // we're updating the GF with the current decoded frame, we save it to the
3152 // ARF slot instead.
3153 // We now have to update the ARF with the current frame and swap gld_fb_idx
3154 // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF
3155 // slot and, if we're updating the GF, the current frame becomes the new GF.
3156 int tmp;
3157
3158 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3159 cm->new_fb_idx);
3160 if (use_upsampled_ref)
3161 uref_cnt_fb(cpi->upsampled_ref_bufs,
3162 &cpi->upsampled_ref_idx[cpi->alt_fb_idx], new_uidx);
3163
3164 tmp = cpi->alt_fb_idx;
3165 cpi->alt_fb_idx = cpi->gld_fb_idx;
3166 cpi->gld_fb_idx = tmp;
3167
3168#if CONFIG_EXT_REFS
3169 // We need to modify the mapping accordingly
3170 cpi->arf_map[0] = cpi->alt_fb_idx;
3171#endif
3172// TODO(zoeliu): Do we need to copy cpi->interp_filter_selected[0] over to
3173// cpi->interp_filter_selected[GOLDEN_FRAME]?
3174#if CONFIG_EXT_REFS
3175 } else if (cpi->rc.is_last_bipred_frame) {
3176 // Refresh the LAST_FRAME with the BWDREF_FRAME and retire the LAST3_FRAME
3177 // by updating the virtual indices. Note that the frame BWDREF_FRAME points
3178 // to now should be retired, and it should not be used before refreshed.
3179 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3180
3181 shift_last_ref_frames(cpi);
3182
3183 cpi->lst_fb_idxes[0] = cpi->bwd_fb_idx;
3184 if (!cpi->rc.is_src_frame_alt_ref) {
3185 memcpy(cpi->interp_filter_selected[0],
3186 cpi->interp_filter_selected[BWDREF_FRAME],
3187 sizeof(cpi->interp_filter_selected[BWDREF_FRAME]));
3188 }
3189 cpi->bwd_fb_idx = tmp;
3190#endif // CONFIG_EXT_REFS
3191#if CONFIG_EXT_REFS
3192 } else if (cpi->rc.is_src_frame_ext_arf && cm->show_existing_frame) {
3193 // Deal with the special case for showing existing internal ALTREF_FRAME
3194 // Refresh the LAST_FRAME with the ALTREF_FRAME and retire the LAST3_FRAME
3195 // by updating the virtual indices.
3196 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3197 int which_arf = gf_group->arf_ref_idx[gf_group->index];
3198 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3199
3200 shift_last_ref_frames(cpi);
3201
3202 cpi->lst_fb_idxes[0] = cpi->alt_fb_idx;
3203 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3204 cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3205 sizeof(cpi->interp_filter_selected[ALTREF_FRAME + which_arf]));
3206
3207 cpi->alt_fb_idx = tmp;
3208 // We need to modify the mapping accordingly
3209 cpi->arf_map[which_arf] = cpi->alt_fb_idx;
3210#endif // CONFIG_EXT_REFS
3211 } else { /* For non key/golden frames */
3212 if (cpi->refresh_alt_ref_frame) {
3213 int arf_idx = cpi->alt_fb_idx;
3214 int which_arf = 0;
3215#if CONFIG_EXT_REFS
3216 if (cpi->oxcf.pass == 2) {
3217 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3218 which_arf = gf_group->arf_update_idx[gf_group->index];
3219 arf_idx = cpi->arf_map[which_arf];
3220 }
3221#else
3222 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
3223 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3224 arf_idx = gf_group->arf_update_idx[gf_group->index];
3225 }
3226#endif // CONFIG_EXT_REFS
3227 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
3228 if (use_upsampled_ref)
3229 uref_cnt_fb(cpi->upsampled_ref_bufs, &cpi->upsampled_ref_idx[arf_idx],
3230 new_uidx);
3231
3232 memcpy(cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3233 cpi->interp_filter_selected[0],
3234 sizeof(cpi->interp_filter_selected[0]));
3235 }
3236
3237 if (cpi->refresh_golden_frame) {
3238 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3239 cm->new_fb_idx);
3240 if (use_upsampled_ref)
3241 uref_cnt_fb(cpi->upsampled_ref_bufs,
3242 &cpi->upsampled_ref_idx[cpi->gld_fb_idx], new_uidx);
3243
3244 if (!cpi->rc.is_src_frame_alt_ref) {
3245 memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3246 cpi->interp_filter_selected[0],
3247 sizeof(cpi->interp_filter_selected[0]));
3248 } else {
3249 int which_arf = 0;
3250#if CONFIG_EXT_REFS
3251 if (cpi->oxcf.pass == 2) {
3252 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3253 which_arf = gf_group->arf_update_idx[gf_group->index];
3254 }
3255#endif // CONFIG_EXT_REFS
3256 memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3257 cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3258 sizeof(cpi->interp_filter_selected[ALTREF_FRAME + which_arf]));
3259 }
3260 }
3261
3262#if CONFIG_EXT_REFS
3263 if (cpi->refresh_bwd_ref_frame) {
3264 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3265 // We have swapped the virtual indices to allow bwd_ref_frame to use
3266 // ALT0 as reference frame. We need to swap them back.
3267 // NOTE: The ALT_REFs' are indexed reversely, and ALT0 refers to the
3268 // farthest ALT_REF from the first frame in the gf group.
3269 int tmp = cpi->arf_map[0];
3270 cpi->arf_map[0] = cpi->alt_fb_idx;
3271 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3272 cpi->bwd_fb_idx = tmp;
3273 }
3274 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3275 cm->new_fb_idx);
3276 if (use_upsampled_ref)
3277 uref_cnt_fb(cpi->upsampled_ref_bufs,
3278 &cpi->upsampled_ref_idx[cpi->bwd_fb_idx], new_uidx);
3279
3280 memcpy(cpi->interp_filter_selected[BWDREF_FRAME],
3281 cpi->interp_filter_selected[0],
3282 sizeof(cpi->interp_filter_selected[0]));
3283 }
3284#endif // CONFIG_EXT_REFS
3285 }
3286
3287 if (cpi->refresh_last_frame) {
3288#if CONFIG_EXT_REFS
3289 // NOTE(zoeliu): We have two layers of mapping (1) from the per-frame
3290 // reference to the reference frame buffer virtual index; and then (2) from
3291 // the virtual index to the reference frame buffer physical index:
3292 //
3293 // LAST_FRAME, ..., LAST3_FRAME, ..., ALTREF_FRAME
3294 // | | |
3295 // v v v
3296 // lst_fb_idxes[0], ..., lst_fb_idxes[2], ..., alt_fb_idx
3297 // | | |
3298 // v v v
3299 // ref_frame_map[], ..., ref_frame_map[], ..., ref_frame_map[]
3300 //
3301 // When refresh_last_frame is set, it is intended to retire LAST3_FRAME,
3302 // have the other 2 LAST reference frames shifted as follows:
3303 // LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3304 // , and then have LAST_FRAME refreshed by the newly coded frame.
3305 //
3306 // To fulfill it, the decoder will be notified to execute following 2 steps:
3307 //
3308 // (a) To change ref_frame_map[] and have the virtual index of LAST3_FRAME
3309 // to point to the newly coded frame, i.e.
3310 // ref_frame_map[lst_fb_idexes[2]] => new_fb_idx;
3311 //
3312 // (b) To change the 1st layer mapping to have LAST_FRAME mapped to the
3313 // original virtual index of LAST3_FRAME and have the other mappings
3314 // shifted as follows:
3315 // LAST_FRAME, LAST2_FRAME, LAST3_FRAME
3316 // | | |
3317 // v v v
3318 // lst_fb_idxes[2], lst_fb_idxes[0], lst_fb_idxes[1]
3319 int ref_frame;
3320 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3321 // We have swapped the virtual indices to use ALT0 as BWD_REF
3322 // and we need to swap them back.
3323 int tmp = cpi->arf_map[0];
3324 cpi->arf_map[0] = cpi->alt_fb_idx;
3325 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3326 cpi->bwd_fb_idx = tmp;
3327 }
3328 if (cm->frame_type == KEY_FRAME) {
3329 for (ref_frame = 0; ref_frame < LAST_REF_FRAMES; ++ref_frame) {
3330 ref_cnt_fb(pool->frame_bufs,
3331 &cm->ref_frame_map[cpi->lst_fb_idxes[ref_frame]],
3332 cm->new_fb_idx);
3333
3334 if (use_upsampled_ref)
3335 uref_cnt_fb(cpi->upsampled_ref_bufs,
3336 &cpi->upsampled_ref_idx[cpi->lst_fb_idxes[ref_frame]],
3337 new_uidx);
3338 }
3339 } else {
3340 int tmp;
3341
3342 ref_cnt_fb(pool->frame_bufs,
3343 &cm->ref_frame_map[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3344 cm->new_fb_idx);
3345
3346 if (use_upsampled_ref)
3347 uref_cnt_fb(
3348 cpi->upsampled_ref_bufs,
3349 &cpi->upsampled_ref_idx[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3350 new_uidx);
3351
3352 tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3353
3354 shift_last_ref_frames(cpi);
3355
3356 cpi->lst_fb_idxes[0] = tmp;
3357
3358 if (!cpi->rc.is_src_frame_alt_ref) {
3359 if (cm->show_existing_frame) {
3360 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3361 cpi->interp_filter_selected[BWDREF_FRAME],
3362 sizeof(cpi->interp_filter_selected[BWDREF_FRAME]));
3363 } else {
3364 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3365 cpi->interp_filter_selected[0],
3366 sizeof(cpi->interp_filter_selected[0]));
3367 }
3368 }
3369 }
3370#else
3371 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
3372 cm->new_fb_idx);
3373 if (use_upsampled_ref)
3374 uref_cnt_fb(cpi->upsampled_ref_bufs,
3375 &cpi->upsampled_ref_idx[cpi->lst_fb_idx], new_uidx);
3376 if (!cpi->rc.is_src_frame_alt_ref) {
3377 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3378 cpi->interp_filter_selected[0],
3379 sizeof(cpi->interp_filter_selected[0]));
3380 }
3381#endif // CONFIG_EXT_REFS
3382 }
3383
3384#if DUMP_REF_FRAME_IMAGES == 1
3385 // Dump out all reference frame images.
3386 dump_ref_frame_images(cpi);
3387#endif // DUMP_REF_FRAME_IMAGES
3388}
3389
Yaowu Xuf883b422016-08-30 14:01:10 -07003390static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003391 MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
3392 struct loopfilter *lf = &cm->lf;
3393 if (is_lossless_requested(&cpi->oxcf)) {
3394 lf->filter_level = 0;
3395 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003396 struct aom_usec_timer timer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003397
Yaowu Xuf883b422016-08-30 14:01:10 -07003398 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003399
Yaowu Xuf883b422016-08-30 14:01:10 -07003400 aom_usec_timer_start(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003401
3402#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07003403 av1_pick_filter_restoration(cpi->Source, cpi, cpi->sf.lpf_pick);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003404#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003405 av1_pick_filter_level(cpi->Source, cpi, cpi->sf.lpf_pick);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003406#endif // CONFIG_LOOP_RESTORATION
3407
Yaowu Xuf883b422016-08-30 14:01:10 -07003408 aom_usec_timer_mark(&timer);
3409 cpi->time_pick_lpf += aom_usec_timer_elapsed(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003410 }
3411
3412 if (lf->filter_level > 0) {
3413#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07003414 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003415#else
3416 if (cpi->num_workers > 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07003417 av1_loop_filter_frame_mt(cm->frame_to_show, cm, xd->plane,
3418 lf->filter_level, 0, 0, cpi->workers,
3419 cpi->num_workers, &cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003420 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003421 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003422#endif
3423 }
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003424#if CONFIG_CLPF
3425 cm->clpf_strength = 0;
3426 cm->clpf_size = 2;
3427 CHECK_MEM_ERROR(
3428 cm, cm->clpf_blocks,
3429 aom_malloc(((cm->frame_to_show->y_crop_width + 31) & ~31) *
3430 ((cm->frame_to_show->y_crop_height + 31) & ~31) >>
3431 10));
3432 if (!is_lossless_requested(&cpi->oxcf)) {
3433 // Test CLPF
3434 int i, hq = 1;
3435 // TODO(yaowu): investigate per-segment CLPF decision and
3436 // an optimal threshold, use 80 for now.
3437 for (i = 0; i < MAX_SEGMENTS; i++)
3438 hq &= av1_get_qindex(&cm->seg, i, cm->base_qindex) < 80;
3439
3440 // Don't try filter if the entire image is nearly losslessly encoded
3441 if (!hq) {
3442 // Find the best strength and block size for the entire frame
3443 int fb_size_log2, strength;
3444 av1_clpf_test_frame(&cpi->last_frame_uf, cpi->Source, cm, &strength,
3445 &fb_size_log2);
3446
3447 if (!fb_size_log2) fb_size_log2 = get_msb(MAX_FB_SIZE);
3448
3449 if (!strength) { // Better to disable for the whole frame?
3450 cm->clpf_strength = 0;
3451 } else {
3452 // Apply the filter using the chosen strength
3453 cm->clpf_strength = strength - (strength == 4);
3454 cm->clpf_size =
3455 fb_size_log2 ? fb_size_log2 - get_msb(MAX_FB_SIZE) + 3 : 0;
3456 aom_yv12_copy_frame(cm->frame_to_show, &cpi->last_frame_uf);
3457 cm->clpf_numblocks =
3458 av1_clpf_frame(cm->frame_to_show, &cpi->last_frame_uf, cpi->Source,
3459 cm, !!cm->clpf_size, strength, 4 + cm->clpf_size,
3460 cm->clpf_blocks, av1_clpf_decision);
3461 }
3462 }
3463 }
3464#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003465#if CONFIG_DERING
3466 if (is_lossless_requested(&cpi->oxcf)) {
3467 cm->dering_level = 0;
3468 } else {
3469 cm->dering_level =
Yaowu Xuf883b422016-08-30 14:01:10 -07003470 av1_dering_search(cm->frame_to_show, cpi->Source, cm, xd);
3471 av1_dering_frame(cm->frame_to_show, cm, xd, cm->dering_level);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003472 }
3473#endif // CONFIG_DERING
Yaowu Xuc27fc142016-08-22 16:08:15 -07003474#if CONFIG_LOOP_RESTORATION
3475 if (cm->rst_info.restoration_type != RESTORE_NONE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003476 av1_loop_restoration_init(&cm->rst_internal, &cm->rst_info,
3477 cm->frame_type == KEY_FRAME, cm->width,
3478 cm->height);
3479 av1_loop_restoration_rows(cm->frame_to_show, cm, 0, cm->mi_rows, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003480 }
3481#endif // CONFIG_LOOP_RESTORATION
3482
Yaowu Xuf883b422016-08-30 14:01:10 -07003483 aom_extend_frame_inner_borders(cm->frame_to_show);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003484}
3485
Yaowu Xuf883b422016-08-30 14:01:10 -07003486static INLINE void alloc_frame_mvs(AV1_COMMON *const cm, int buffer_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003487 RefCntBuffer *const new_fb_ptr = &cm->buffer_pool->frame_bufs[buffer_idx];
3488 if (new_fb_ptr->mvs == NULL || new_fb_ptr->mi_rows < cm->mi_rows ||
3489 new_fb_ptr->mi_cols < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003490 aom_free(new_fb_ptr->mvs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003491 CHECK_MEM_ERROR(cm, new_fb_ptr->mvs,
Yaowu Xuf883b422016-08-30 14:01:10 -07003492 (MV_REF *)aom_calloc(cm->mi_rows * cm->mi_cols,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003493 sizeof(*new_fb_ptr->mvs)));
3494 new_fb_ptr->mi_rows = cm->mi_rows;
3495 new_fb_ptr->mi_cols = cm->mi_cols;
3496 }
3497}
3498
Yaowu Xuf883b422016-08-30 14:01:10 -07003499void av1_scale_references(AV1_COMP *cpi) {
3500 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003501 MV_REFERENCE_FRAME ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003502 const AOM_REFFRAME ref_mask[INTER_REFS_PER_FRAME] = {
3503 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003504#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003505 AOM_LAST2_FLAG,
3506 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003507#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003508 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003509#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003510 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003511#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003512 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003513 };
3514
3515 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003516 // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
Yaowu Xuc27fc142016-08-22 16:08:15 -07003517 if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
3518 BufferPool *const pool = cm->buffer_pool;
3519 const YV12_BUFFER_CONFIG *const ref =
3520 get_ref_frame_buffer(cpi, ref_frame);
3521
3522 if (ref == NULL) {
3523 cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3524 continue;
3525 }
3526
Yaowu Xuf883b422016-08-30 14:01:10 -07003527#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003528 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3529 RefCntBuffer *new_fb_ptr = NULL;
3530 int force_scaling = 0;
3531 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3532 if (new_fb == INVALID_IDX) {
3533 new_fb = get_free_fb(cm);
3534 force_scaling = 1;
3535 }
3536 if (new_fb == INVALID_IDX) return;
3537 new_fb_ptr = &pool->frame_bufs[new_fb];
3538 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3539 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003540 if (aom_realloc_frame_buffer(
3541 &new_fb_ptr->buf, cm->width, cm->height, cm->subsampling_x,
3542 cm->subsampling_y, cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
3543 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003544 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 "Failed to allocate frame buffer");
3546 scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE,
3547 (int)cm->bit_depth);
3548 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3549 alloc_frame_mvs(cm, new_fb);
3550 }
3551#else
3552 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3553 RefCntBuffer *new_fb_ptr = NULL;
3554 int force_scaling = 0;
3555 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3556 if (new_fb == INVALID_IDX) {
3557 new_fb = get_free_fb(cm);
3558 force_scaling = 1;
3559 }
3560 if (new_fb == INVALID_IDX) return;
3561 new_fb_ptr = &pool->frame_bufs[new_fb];
3562 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3563 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003564 if (aom_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003565 cm->subsampling_x, cm->subsampling_y,
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003566 AOM_BORDER_IN_PIXELS, cm->byte_alignment,
3567 NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003568 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003569 "Failed to allocate frame buffer");
3570 scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE);
3571 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3572 alloc_frame_mvs(cm, new_fb);
3573 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003574#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003575
3576 if (cpi->sf.use_upsampled_references &&
3577 (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3578 new_fb_ptr->buf.y_crop_height != cm->height)) {
3579 const int map_idx = get_ref_frame_map_idx(cpi, ref_frame);
3580 EncRefCntBuffer *ubuf =
3581 &cpi->upsampled_ref_bufs[cpi->upsampled_ref_idx[map_idx]];
3582
Yaowu Xuf883b422016-08-30 14:01:10 -07003583 if (aom_realloc_frame_buffer(&ubuf->buf, (cm->width << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003584 (cm->height << 3), cm->subsampling_x,
3585 cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003586#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003587 cm->use_highbitdepth,
3588#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003589 (AOM_BORDER_IN_PIXELS << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003590 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003591 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003592 "Failed to allocate up-sampled frame buffer");
Yaowu Xuf883b422016-08-30 14:01:10 -07003593#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003594 scale_and_extend_frame(&new_fb_ptr->buf, &ubuf->buf, 1,
3595 (int)cm->bit_depth);
3596#else
3597 scale_and_extend_frame(&new_fb_ptr->buf, &ubuf->buf, 1);
3598#endif
3599 }
3600 } else {
3601 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3602 RefCntBuffer *const buf = &pool->frame_bufs[buf_idx];
3603 buf->buf.y_crop_width = ref->y_crop_width;
3604 buf->buf.y_crop_height = ref->y_crop_height;
3605 cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
3606 ++buf->ref_count;
3607 }
3608 } else {
3609 if (cpi->oxcf.pass != 0) cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3610 }
3611 }
3612}
3613
Yaowu Xuf883b422016-08-30 14:01:10 -07003614static void release_scaled_references(AV1_COMP *cpi) {
3615 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003616 int i;
3617 if (cpi->oxcf.pass == 0) {
3618 // Only release scaled references under certain conditions:
3619 // if reference will be updated, or if scaled reference has same resolution.
3620 int refresh[INTER_REFS_PER_FRAME];
3621 refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
3622#if CONFIG_EXT_REFS
3623 refresh[1] = refresh[2] = 0;
3624 refresh[3] = (cpi->refresh_golden_frame) ? 1 : 0;
3625 refresh[4] = (cpi->refresh_bwd_ref_frame) ? 1 : 0;
3626 refresh[5] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3627#else
3628 refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
3629 refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3630#endif // CONFIG_EXT_REFS
3631 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3632 const int idx = cpi->scaled_ref_idx[i - 1];
3633 RefCntBuffer *const buf =
3634 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3635 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i);
3636 if (buf != NULL &&
3637 (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width &&
3638 buf->buf.y_crop_height == ref->y_crop_height))) {
3639 --buf->ref_count;
3640 cpi->scaled_ref_idx[i - 1] = INVALID_IDX;
3641 }
3642 }
3643 } else {
3644 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) {
3645 const int idx = cpi->scaled_ref_idx[i];
3646 RefCntBuffer *const buf =
3647 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3648 if (buf != NULL) {
3649 --buf->ref_count;
3650 cpi->scaled_ref_idx[i] = INVALID_IDX;
3651 }
3652 }
3653 }
3654}
3655
3656static void full_to_model_count(unsigned int *model_count,
3657 unsigned int *full_count) {
3658 int n;
3659 model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN];
3660 model_count[ONE_TOKEN] = full_count[ONE_TOKEN];
3661 model_count[TWO_TOKEN] = full_count[TWO_TOKEN];
3662 for (n = THREE_TOKEN; n < EOB_TOKEN; ++n)
3663 model_count[TWO_TOKEN] += full_count[n];
3664 model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN];
3665}
3666
Yaowu Xuf883b422016-08-30 14:01:10 -07003667void av1_full_to_model_counts(av1_coeff_count_model *model_count,
3668 av1_coeff_count *full_count) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003669 int i, j, k, l;
3670
3671 for (i = 0; i < PLANE_TYPES; ++i)
3672 for (j = 0; j < REF_TYPES; ++j)
3673 for (k = 0; k < COEF_BANDS; ++k)
3674 for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
3675 full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]);
3676}
3677
3678#if 0 && CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07003679static void output_frame_level_debug_stats(AV1_COMP *cpi) {
3680 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003681 FILE *const f = fopen("tmp.stt", cm->current_video_frame ? "a" : "w");
3682 int64_t recon_err;
3683
Yaowu Xuf883b422016-08-30 14:01:10 -07003684 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003685
Yaowu Xuf883b422016-08-30 14:01:10 -07003686 recon_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003687
3688 if (cpi->twopass.total_left_stats.coded_error != 0.0)
3689 fprintf(f, "%10u %dx%d %10d %10d %d %d %10d %10d %10d %10d"
3690 "%10"PRId64" %10"PRId64" %5d %5d %10"PRId64" "
3691 "%10"PRId64" %10"PRId64" %10d "
3692 "%7.2lf %7.2lf %7.2lf %7.2lf %7.2lf"
3693 "%6d %6d %5d %5d %5d "
3694 "%10"PRId64" %10.3lf"
3695 "%10lf %8u %10"PRId64" %10d %10d %10d\n",
3696 cpi->common.current_video_frame,
3697 cm->width, cm->height,
3698 cpi->td.rd_counts.m_search_count,
3699 cpi->td.rd_counts.ex_search_count,
3700 cpi->rc.source_alt_ref_pending,
3701 cpi->rc.source_alt_ref_active,
3702 cpi->rc.this_frame_target,
3703 cpi->rc.projected_frame_size,
3704 cpi->rc.projected_frame_size / cpi->common.MBs,
3705 (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
3706 cpi->rc.vbr_bits_off_target,
3707 cpi->rc.vbr_bits_off_target_fast,
3708 cpi->twopass.extend_minq,
3709 cpi->twopass.extend_minq_fast,
3710 cpi->rc.total_target_vs_actual,
3711 (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target),
3712 cpi->rc.total_actual_bits, cm->base_qindex,
Yaowu Xuf883b422016-08-30 14:01:10 -07003713 av1_convert_qindex_to_q(cm->base_qindex, cm->bit_depth),
3714 (double)av1_dc_quant(cm->base_qindex, 0, cm->bit_depth) / 4.0,
3715 av1_convert_qindex_to_q(cpi->twopass.active_worst_quality,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003716 cm->bit_depth),
3717 cpi->rc.avg_q,
Yaowu Xuf883b422016-08-30 14:01:10 -07003718 av1_convert_qindex_to_q(cpi->oxcf.cq_level, cm->bit_depth),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003719 cpi->refresh_last_frame, cpi->refresh_golden_frame,
3720 cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost,
3721 cpi->twopass.bits_left,
3722 cpi->twopass.total_left_stats.coded_error,
3723 cpi->twopass.bits_left /
3724 (1 + cpi->twopass.total_left_stats.coded_error),
3725 cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost,
3726 cpi->twopass.kf_zeromotion_pct,
3727 cpi->twopass.fr_content_type);
3728
3729 fclose(f);
3730
3731 if (0) {
3732 FILE *const fmodes = fopen("Modes.stt", "a");
3733 int i;
3734
3735 fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame,
3736 cm->frame_type, cpi->refresh_golden_frame,
3737 cpi->refresh_alt_ref_frame);
3738
3739 for (i = 0; i < MAX_MODES; ++i)
3740 fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]);
3741
3742 fprintf(fmodes, "\n");
3743
3744 fclose(fmodes);
3745 }
3746}
3747#endif
3748
Yaowu Xuf883b422016-08-30 14:01:10 -07003749static void set_mv_search_params(AV1_COMP *cpi) {
3750 const AV1_COMMON *const cm = &cpi->common;
3751 const unsigned int max_mv_def = AOMMIN(cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003752
3753 // Default based on max resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003754 cpi->mv_step_param = av1_init_search_range(max_mv_def);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003755
3756 if (cpi->sf.mv.auto_mv_step_size) {
3757 if (frame_is_intra_only(cm)) {
3758 // Initialize max_mv_magnitude for use in the first INTER frame
3759 // after a key/intra-only frame.
3760 cpi->max_mv_magnitude = max_mv_def;
3761 } else {
3762 if (cm->show_frame) {
3763 // Allow mv_steps to correspond to twice the max mv magnitude found
3764 // in the previous frame, capped by the default max_mv_magnitude based
3765 // on resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003766 cpi->mv_step_param = av1_init_search_range(
3767 AOMMIN(max_mv_def, 2 * cpi->max_mv_magnitude));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003768 }
3769 cpi->max_mv_magnitude = 0;
3770 }
3771 }
3772}
3773
Yaowu Xuf883b422016-08-30 14:01:10 -07003774static void set_size_independent_vars(AV1_COMP *cpi) {
3775 av1_set_speed_features_framesize_independent(cpi);
3776 av1_set_rd_speed_thresholds(cpi);
3777 av1_set_rd_speed_thresholds_sub8x8(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003778 cpi->common.interp_filter = cpi->sf.default_interp_filter;
3779}
3780
Yaowu Xuf883b422016-08-30 14:01:10 -07003781static void set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003782 int *top_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003783 AV1_COMMON *const cm = &cpi->common;
3784 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003785
3786 // Setup variables that depend on the dimensions of the frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07003787 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788
3789 // Decide q and q bounds.
Yaowu Xuf883b422016-08-30 14:01:10 -07003790 *q = av1_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003791
3792 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003793 av1_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003794 }
3795
3796 // Configure experimental use of segmentation for enhanced coding of
3797 // static regions if indicated.
3798 // Only allowed in the second pass of a two pass encode, as it requires
3799 // lagged coding, and if the relevant speed feature flag is set.
3800 if (oxcf->pass == 2 && cpi->sf.static_segmentation)
3801 configure_static_seg_features(cpi);
3802}
3803
Yaowu Xuf883b422016-08-30 14:01:10 -07003804static void init_motion_estimation(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003805 int y_stride = cpi->scaled_source.y_stride;
3806
3807 if (cpi->sf.mv.search_method == NSTEP) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003808 av1_init3smotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003809 } else if (cpi->sf.mv.search_method == DIAMOND) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003810 av1_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003811 }
3812}
3813
Yaowu Xuf883b422016-08-30 14:01:10 -07003814static void set_frame_size(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003815 int ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003816 AV1_COMMON *const cm = &cpi->common;
3817 AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003818 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
3819
Yaowu Xuf883b422016-08-30 14:01:10 -07003820 if (oxcf->pass == 2 && oxcf->rc_mode == AOM_VBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003821 ((oxcf->resize_mode == RESIZE_FIXED && cm->current_video_frame == 0) ||
3822 (oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003823 av1_calculate_coded_size(cpi, &oxcf->scaled_frame_width,
3824 &oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003825
3826 // There has been a change in frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003827 av1_set_size_literal(cpi, oxcf->scaled_frame_width,
3828 oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003829 }
3830
Yaowu Xuf883b422016-08-30 14:01:10 -07003831 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003832 oxcf->resize_mode == RESIZE_DYNAMIC) {
3833 if (cpi->resize_pending == 1) {
3834 oxcf->scaled_frame_width =
3835 (cm->width * cpi->resize_scale_num) / cpi->resize_scale_den;
3836 oxcf->scaled_frame_height =
3837 (cm->height * cpi->resize_scale_num) / cpi->resize_scale_den;
3838 } else if (cpi->resize_pending == -1) {
3839 // Go back up to original size.
3840 oxcf->scaled_frame_width = oxcf->width;
3841 oxcf->scaled_frame_height = oxcf->height;
3842 }
3843 if (cpi->resize_pending != 0) {
3844 // There has been a change in frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003845 av1_set_size_literal(cpi, oxcf->scaled_frame_width,
3846 oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003847
3848 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
3849 set_mv_search_params(cpi);
3850 }
3851 }
3852
3853 if (oxcf->pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003854 av1_set_target_rate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003855 }
3856
3857 alloc_frame_mvs(cm, cm->new_fb_idx);
3858
3859 // Reset the frame pointers to the current frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003860 if (aom_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003861 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003862#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003863 cm->use_highbitdepth,
3864#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003865 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
3866 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003867 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003868 "Failed to allocate frame buffer");
3869
3870 alloc_util_frame_buffers(cpi);
3871 init_motion_estimation(cpi);
3872
3873 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3874 RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - LAST_FRAME];
3875 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3876
3877 ref_buf->idx = buf_idx;
3878
3879 if (buf_idx != INVALID_IDX) {
3880 YV12_BUFFER_CONFIG *const buf = &cm->buffer_pool->frame_bufs[buf_idx].buf;
3881 ref_buf->buf = buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07003882#if CONFIG_AOM_HIGHBITDEPTH
3883 av1_setup_scale_factors_for_frame(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003884 &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width,
3885 cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0);
3886#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003887 av1_setup_scale_factors_for_frame(&ref_buf->sf, buf->y_crop_width,
3888 buf->y_crop_height, cm->width,
3889 cm->height);
3890#endif // CONFIG_AOM_HIGHBITDEPTH
3891 if (av1_is_scaled(&ref_buf->sf)) aom_extend_frame_borders(buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003892 } else {
3893 ref_buf->buf = NULL;
3894 }
3895 }
3896
3897 set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
3898}
3899
Yaowu Xuf883b422016-08-30 14:01:10 -07003900static void reset_use_upsampled_references(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003901 MV_REFERENCE_FRAME ref_frame;
3902
3903 // reset up-sampled reference buffer structure.
3904 init_upsampled_ref_frame_bufs(cpi);
3905
3906 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3907 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, ref_frame);
3908 int new_uidx = upsample_ref_frame(cpi, ref);
3909
3910 // Update the up-sampled reference index.
3911 cpi->upsampled_ref_idx[get_ref_frame_map_idx(cpi, ref_frame)] = new_uidx;
3912 cpi->upsampled_ref_bufs[new_uidx].ref_count++;
3913 }
3914}
3915
Yaowu Xuf883b422016-08-30 14:01:10 -07003916static void encode_without_recode_loop(AV1_COMP *cpi) {
3917 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003918 int q = 0, bottom_index = 0, top_index = 0; // Dummy variables.
3919 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3920
Yaowu Xuf883b422016-08-30 14:01:10 -07003921 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003922
3923 set_frame_size(cpi);
3924
3925 // For 1 pass CBR under dynamic resize mode: use faster scaling for source.
3926 // Only for 2x2 scaling for now.
Yaowu Xuf883b422016-08-30 14:01:10 -07003927 if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003928 cpi->oxcf.resize_mode == RESIZE_DYNAMIC &&
3929 cpi->un_scaled_source->y_width == (cm->width << 1) &&
3930 cpi->un_scaled_source->y_height == (cm->height << 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003931 cpi->Source = av1_scale_if_required_fast(cm, cpi->un_scaled_source,
3932 &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003933 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07003934 cpi->Last_Source = av1_scale_if_required_fast(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003935 cm, cpi->unscaled_last_source, &cpi->scaled_last_source);
3936 } else {
3937 cpi->Source =
Yaowu Xuf883b422016-08-30 14:01:10 -07003938 av1_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003939 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07003940 cpi->Last_Source = av1_scale_if_required(cm, cpi->unscaled_last_source,
3941 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942 }
3943
3944 if (frame_is_intra_only(cm) == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003945 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003946 }
3947
3948 set_size_independent_vars(cpi);
3949 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3950
3951 // cpi->sf.use_upsampled_references can be different from frame to frame.
3952 // Every time when cpi->sf.use_upsampled_references is changed from 0 to 1.
3953 // The reference frames for this frame have to be up-sampled before encoding.
3954 if (!use_upsampled_ref && cpi->sf.use_upsampled_references)
3955 reset_use_upsampled_references(cpi);
3956
Yaowu Xuf883b422016-08-30 14:01:10 -07003957 av1_set_quantizer(cm, q);
3958 av1_set_variance_partition_thresholds(cpi, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003959
3960 setup_frame(cpi);
3961
3962#if CONFIG_ENTROPY
3963 cm->do_subframe_update = cm->tile_cols == 1 && cm->tile_rows == 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07003964 av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
3965 av1_copy(cpi->subframe_stats.enc_starting_coef_probs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003966 cm->coef_probs_update_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07003967 av1_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003968#endif // CONFIG_ENTROPY
3969
3970 suppress_active_map(cpi);
3971 // Variance adaptive and in frame q adjustment experiments are mutually
3972 // exclusive.
3973 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003974 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003975 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003976 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003977 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003978 av1_cyclic_refresh_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003979 }
3980 apply_active_map(cpi);
3981
3982 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07003983 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003984
3985 // Update some stats from cyclic refresh, and check if we should not update
3986 // golden reference, for 1 pass CBR.
3987 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->frame_type != KEY_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -07003988 (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR))
3989 av1_cyclic_refresh_check_golden_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003990
3991 // Update the skip mb flag probabilities based on the distribution
3992 // seen in the last encoder iteration.
3993 // update_base_skip_probs(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003994 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003995}
3996
Yaowu Xuf883b422016-08-30 14:01:10 -07003997static void encode_with_recode_loop(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003998 uint8_t *dest) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003999 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004000 RATE_CONTROL *const rc = &cpi->rc;
4001 int bottom_index, top_index;
4002 int loop_count = 0;
4003 int loop_at_this_size = 0;
4004 int loop = 0;
4005 int overshoot_seen = 0;
4006 int undershoot_seen = 0;
4007 int frame_over_shoot_limit;
4008 int frame_under_shoot_limit;
4009 int q = 0, q_low = 0, q_high = 0;
4010 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
4011
4012 set_size_independent_vars(cpi);
4013
4014 // cpi->sf.use_upsampled_references can be different from frame to frame.
4015 // Every time when cpi->sf.use_upsampled_references is changed from 0 to 1.
4016 // The reference frames for this frame have to be up-sampled before encoding.
4017 if (!use_upsampled_ref && cpi->sf.use_upsampled_references)
4018 reset_use_upsampled_references(cpi);
4019
4020 do {
Yaowu Xuf883b422016-08-30 14:01:10 -07004021 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004022
4023 set_frame_size(cpi);
4024
4025 if (loop_count == 0 || cpi->resize_pending != 0) {
4026 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
4027
4028 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
4029 set_mv_search_params(cpi);
4030
4031 // Reset the loop state for new frame size.
4032 overshoot_seen = 0;
4033 undershoot_seen = 0;
4034
4035 // Reconfiguration for change in frame size has concluded.
4036 cpi->resize_pending = 0;
4037
4038 q_low = bottom_index;
4039 q_high = top_index;
4040
4041 loop_at_this_size = 0;
4042 }
4043
4044 // Decide frame size bounds first time through.
4045 if (loop_count == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004046 av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
4047 &frame_under_shoot_limit,
4048 &frame_over_shoot_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004049 }
4050
4051 cpi->Source =
Yaowu Xuf883b422016-08-30 14:01:10 -07004052 av1_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004053
4054 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004055 cpi->Last_Source = av1_scale_if_required(cm, cpi->unscaled_last_source,
4056 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004057
4058 if (frame_is_intra_only(cm) == 0) {
4059 if (loop_count > 0) {
4060 release_scaled_references(cpi);
4061 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004062 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004063 }
4064
Yaowu Xuf883b422016-08-30 14:01:10 -07004065 av1_set_quantizer(cm, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004066
4067 if (loop_count == 0) setup_frame(cpi);
4068
4069#if CONFIG_ENTROPY
4070 // Base q-index may have changed, so we need to assign proper default coef
4071 // probs before every iteration.
4072 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
4073 int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07004074 av1_default_coef_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004075 if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
4076 cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
4077 for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
4078 } else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
4079 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
4080 }
4081 }
4082#endif // CONFIG_ENTROPY
4083
4084#if CONFIG_ENTROPY
4085 cm->do_subframe_update = cm->tile_cols == 1 && cm->tile_rows == 1;
4086 if (loop_count == 0 || frame_is_intra_only(cm) ||
4087 cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004088 av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
4089 av1_copy(cpi->subframe_stats.enc_starting_coef_probs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004090 } else {
4091 if (cm->do_subframe_update) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004092 av1_copy(cm->fc->coef_probs,
4093 cpi->subframe_stats.enc_starting_coef_probs);
4094 av1_copy(cm->starting_coef_probs,
4095 cpi->subframe_stats.enc_starting_coef_probs);
4096 av1_zero(cpi->subframe_stats.coef_counts_buf);
4097 av1_zero(cpi->subframe_stats.eob_counts_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004098 }
4099 }
4100 cm->coef_probs_update_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07004101 av1_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004102#endif // CONFIG_ENTROPY
4103
4104 // Variance adaptive and in frame q adjustment experiments are mutually
4105 // exclusive.
4106 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004107 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004108 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004109 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004110 }
4111
4112 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07004113 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004114
4115 // Update the skip mb flag probabilities based on the distribution
4116 // seen in the last encoder iteration.
4117 // update_base_skip_probs(cpi);
4118
Yaowu Xuf883b422016-08-30 14:01:10 -07004119 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004120
4121 // Dummy pack of the bitstream using up to date stats to get an
4122 // accurate estimate of output frame size to determine if we need
4123 // to recode.
4124 if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
4125 save_coding_context(cpi);
4126
Yaowu Xuf883b422016-08-30 14:01:10 -07004127 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004128
4129 rc->projected_frame_size = (int)(*size) << 3;
4130 restore_coding_context(cpi);
4131
4132 if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
4133 }
4134
Yaowu Xuf883b422016-08-30 14:01:10 -07004135 if (cpi->oxcf.rc_mode == AOM_Q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004136 loop = 0;
4137 } else {
4138 if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced &&
4139 (rc->projected_frame_size < rc->max_frame_bandwidth)) {
4140 int last_q = q;
4141 int64_t kf_err;
4142
4143 int64_t high_err_target = cpi->ambient_err;
4144 int64_t low_err_target = cpi->ambient_err >> 1;
4145
Yaowu Xuf883b422016-08-30 14:01:10 -07004146#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 if (cm->use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004148 kf_err = aom_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004149 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004150 kf_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004151 }
4152#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004153 kf_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4154#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004155
4156 // Prevent possible divide by zero error below for perfect KF
4157 kf_err += !kf_err;
4158
4159 // The key frame is not good enough or we can afford
4160 // to make it better without undue risk of popping.
4161 if ((kf_err > high_err_target &&
4162 rc->projected_frame_size <= frame_over_shoot_limit) ||
4163 (kf_err > low_err_target &&
4164 rc->projected_frame_size <= frame_under_shoot_limit)) {
4165 // Lower q_high
4166 q_high = q > q_low ? q - 1 : q_low;
4167
4168 // Adjust Q
4169 q = (int)((q * high_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004170 q = AOMMIN(q, (q_high + q_low) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004171 } else if (kf_err < low_err_target &&
4172 rc->projected_frame_size >= frame_under_shoot_limit) {
4173 // The key frame is much better than the previous frame
4174 // Raise q_low
4175 q_low = q < q_high ? q + 1 : q_high;
4176
4177 // Adjust Q
4178 q = (int)((q * low_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004179 q = AOMMIN(q, (q_high + q_low + 1) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004180 }
4181
4182 // Clamp Q to upper and lower limits:
4183 q = clamp(q, q_low, q_high);
4184
4185 loop = q != last_q;
4186 } else if (recode_loop_test(cpi, frame_over_shoot_limit,
4187 frame_under_shoot_limit, q,
Yaowu Xuf883b422016-08-30 14:01:10 -07004188 AOMMAX(q_high, top_index), bottom_index)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189 // Is the projected frame size out of range and are we allowed
4190 // to attempt to recode.
4191 int last_q = q;
4192 int retries = 0;
4193
4194 if (cpi->resize_pending == 1) {
4195 // Change in frame size so go back around the recode loop.
4196 cpi->rc.frame_size_selector =
4197 SCALE_STEP1 - cpi->rc.frame_size_selector;
4198 cpi->rc.next_frame_size_selector = cpi->rc.frame_size_selector;
4199
4200#if CONFIG_INTERNAL_STATS
4201 ++cpi->tot_recode_hits;
4202#endif
4203 ++loop_count;
4204 loop = 1;
4205 continue;
4206 }
4207
4208 // Frame size out of permitted range:
4209 // Update correction factor & compute new Q to try...
4210
4211 // Frame is too large
4212 if (rc->projected_frame_size > rc->this_frame_target) {
4213 // Special case if the projected size is > the max allowed.
4214 if (rc->projected_frame_size >= rc->max_frame_bandwidth)
4215 q_high = rc->worst_quality;
4216
4217 // Raise Qlow as to at least the current value
4218 q_low = q < q_high ? q + 1 : q_high;
4219
4220 if (undershoot_seen || loop_at_this_size > 1) {
4221 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004222 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004223
4224 q = (q_high + q_low + 1) / 2;
4225 } else {
4226 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004227 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004228
Yaowu Xuf883b422016-08-30 14:01:10 -07004229 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4230 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004231
4232 while (q < q_low && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004233 av1_rc_update_rate_correction_factors(cpi);
4234 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4235 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004236 retries++;
4237 }
4238 }
4239
4240 overshoot_seen = 1;
4241 } else {
4242 // Frame is too small
4243 q_high = q > q_low ? q - 1 : q_low;
4244
4245 if (overshoot_seen || loop_at_this_size > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004246 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004247 q = (q_high + q_low) / 2;
4248 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004249 av1_rc_update_rate_correction_factors(cpi);
4250 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4251 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004252 // Special case reset for qlow for constrained quality.
4253 // This should only trigger where there is very substantial
4254 // undershoot on a frame and the auto cq level is above
4255 // the user passsed in value.
Yaowu Xuf883b422016-08-30 14:01:10 -07004256 if (cpi->oxcf.rc_mode == AOM_CQ && q < q_low) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004257 q_low = q;
4258 }
4259
4260 while (q > q_high && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004261 av1_rc_update_rate_correction_factors(cpi);
4262 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4263 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004264 retries++;
4265 }
4266 }
4267
4268 undershoot_seen = 1;
4269 }
4270
4271 // Clamp Q to upper and lower limits:
4272 q = clamp(q, q_low, q_high);
4273
4274 loop = (q != last_q);
4275 } else {
4276 loop = 0;
4277 }
4278 }
4279
4280 // Special case for overlay frame.
4281 if (rc->is_src_frame_alt_ref &&
4282 rc->projected_frame_size < rc->max_frame_bandwidth)
4283 loop = 0;
4284
4285 if (loop) {
4286 ++loop_count;
4287 ++loop_at_this_size;
4288
4289#if CONFIG_INTERNAL_STATS
4290 ++cpi->tot_recode_hits;
4291#endif
4292 }
4293 } while (loop);
4294}
4295
Yaowu Xuf883b422016-08-30 14:01:10 -07004296static int get_ref_frame_flags(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004297 const int *const map = cpi->common.ref_frame_map;
4298
4299#if CONFIG_EXT_REFS
4300 const int last2_is_last =
4301 map[cpi->lst_fb_idxes[1]] == map[cpi->lst_fb_idxes[0]];
4302 const int last3_is_last =
4303 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[0]];
4304 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[0]];
4305 const int bwd_is_last = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[0]];
4306 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[0]];
4307
4308 const int last3_is_last2 =
4309 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[1]];
4310 const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[1]];
4311 const int bwd_is_last2 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[1]];
4312
4313 const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[2]];
4314 const int bwd_is_last3 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[2]];
4315
4316 const int bwd_is_gld = map[cpi->bwd_fb_idx] == map[cpi->gld_fb_idx];
4317
4318 const int last2_is_alt = map[cpi->lst_fb_idxes[1]] == map[cpi->alt_fb_idx];
4319 const int last3_is_alt = map[cpi->lst_fb_idxes[2]] == map[cpi->alt_fb_idx];
4320 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4321 const int bwd_is_alt = map[cpi->bwd_fb_idx] == map[cpi->alt_fb_idx];
4322#else
4323 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
4324 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4325 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
4326#endif // CONFIG_EXT_REFS
4327
Yaowu Xuf883b422016-08-30 14:01:10 -07004328 int flags = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004329
4330#if CONFIG_EXT_REFS
4331 // Disable the use of BWDREF_FRAME for non-bipredictive frames.
4332 if (!(cpi->rc.is_bipred_frame || cpi->rc.is_last_bipred_frame ||
4333 (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs)))
Yaowu Xuf883b422016-08-30 14:01:10 -07004334 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004335#endif // CONFIG_EXT_REFS
4336
Yaowu Xuf883b422016-08-30 14:01:10 -07004337 if (gld_is_last || gld_is_alt) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004338
Yaowu Xuf883b422016-08-30 14:01:10 -07004339 if (cpi->rc.frames_till_gf_update_due == INT_MAX) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004340
Yaowu Xuf883b422016-08-30 14:01:10 -07004341 if (alt_is_last) flags &= ~AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004342
4343#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004344 if (last2_is_last || last2_is_alt) flags &= ~AOM_LAST2_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004345
Yaowu Xuf883b422016-08-30 14:01:10 -07004346 if (last3_is_last || last3_is_last2 || last3_is_alt) flags &= ~AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004347
Yaowu Xuf883b422016-08-30 14:01:10 -07004348 if (gld_is_last2 || gld_is_last3) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004349
4350 if ((bwd_is_last || bwd_is_last2 || bwd_is_last3 || bwd_is_gld ||
4351 bwd_is_alt) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07004352 (flags & AOM_BWD_FLAG))
4353 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004354#endif // CONFIG_EXT_REFS
4355
4356 return flags;
4357}
4358
Yaowu Xuf883b422016-08-30 14:01:10 -07004359static void set_ext_overrides(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004360 // Overrides the defaults with the externally supplied values with
Yaowu Xuf883b422016-08-30 14:01:10 -07004361 // av1_update_reference() and av1_update_entropy() calls
Yaowu Xuc27fc142016-08-22 16:08:15 -07004362 // Note: The overrides are valid only for the next frame passed
4363 // to encode_frame_to_data_rate() function
4364 if (cpi->ext_refresh_frame_context_pending) {
4365 cpi->common.refresh_frame_context = cpi->ext_refresh_frame_context;
4366 cpi->ext_refresh_frame_context_pending = 0;
4367 }
4368 if (cpi->ext_refresh_frame_flags_pending) {
4369 cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
4370 cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
4371 cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
4372 cpi->ext_refresh_frame_flags_pending = 0;
4373 }
4374}
4375
Yaowu Xuf883b422016-08-30 14:01:10 -07004376YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
4377 YV12_BUFFER_CONFIG *unscaled,
4378 YV12_BUFFER_CONFIG *scaled) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004379 if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4380 cm->mi_rows * MI_SIZE != unscaled->y_height) {
4381 // For 2x2 scaling down.
Yaowu Xuf883b422016-08-30 14:01:10 -07004382 aom_scale_frame(unscaled, scaled, unscaled->y_buffer, 9, 2, 1, 2, 1, 0);
4383 aom_extend_frame_borders(scaled);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004384 return scaled;
4385 } else {
4386 return unscaled;
4387 }
4388}
4389
Yaowu Xuf883b422016-08-30 14:01:10 -07004390YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
4391 YV12_BUFFER_CONFIG *unscaled,
4392 YV12_BUFFER_CONFIG *scaled) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004393 if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4394 cm->mi_rows * MI_SIZE != unscaled->y_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004395#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004396 scale_and_extend_frame_nonnormative(unscaled, scaled, (int)cm->bit_depth);
4397#else
4398 scale_and_extend_frame_nonnormative(unscaled, scaled);
Yaowu Xuf883b422016-08-30 14:01:10 -07004399#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004400 return scaled;
4401 } else {
4402 return unscaled;
4403 }
4404}
4405
Yaowu Xuf883b422016-08-30 14:01:10 -07004406static void set_arf_sign_bias(AV1_COMP *cpi) {
4407 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004408 int arf_sign_bias;
4409#if CONFIG_EXT_REFS
4410 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4411 // The arf_sign_bias will be one for internal ARFs'
4412 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4413 (!cpi->refresh_alt_ref_frame ||
4414 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4415#else
4416 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
4417 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4418 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4419 (!cpi->refresh_alt_ref_frame ||
4420 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4421 } else {
4422 arf_sign_bias =
4423 (cpi->rc.source_alt_ref_active && !cpi->refresh_alt_ref_frame);
4424 }
4425#endif
4426 cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
4427#if CONFIG_EXT_REFS
4428 cm->ref_frame_sign_bias[BWDREF_FRAME] = cm->ref_frame_sign_bias[ALTREF_FRAME];
4429#endif // CONFIG_EXT_REFS
4430}
4431
Yaowu Xuf883b422016-08-30 14:01:10 -07004432static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
James Zern7b9407a2016-05-18 23:48:05 -07004433 InterpFilter ifilter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004434 int ref_total[TOTAL_REFS_PER_FRAME] = { 0 };
4435 MV_REFERENCE_FRAME ref;
4436 int mask = 0;
4437 int arf_idx = ALTREF_FRAME;
4438
4439#if CONFIG_EXT_REFS
4440 // Get which arf used as ALTREF_FRAME
4441 if (cpi->oxcf.pass == 2)
4442 arf_idx += cpi->twopass.gf_group.arf_ref_idx[cpi->twopass.gf_group.index];
4443#endif
4444
4445 if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
4446 return mask;
4447
4448#if CONFIG_EXT_REFS
4449 for (ref = LAST_FRAME; ref < ALTREF_FRAME; ++ref)
4450 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4451 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
4452
4453 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4454 ref_total[ref] += cpi->interp_filter_selected[arf_idx][ifilter];
4455#else
4456 for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
4457 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4458 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
4459#endif
4460
4461 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter) {
4462 if ((ref_total[LAST_FRAME] &&
4463 cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
4464#if CONFIG_EXT_REFS
4465 (ref_total[LAST2_FRAME] == 0 ||
4466 cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 50 <
4467 ref_total[LAST2_FRAME]) &&
4468 (ref_total[LAST3_FRAME] == 0 ||
4469 cpi->interp_filter_selected[LAST3_FRAME][ifilter] * 50 <
4470 ref_total[LAST3_FRAME]) &&
4471#endif // CONFIG_EXT_REFS
4472 (ref_total[GOLDEN_FRAME] == 0 ||
4473 cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50 <
4474 ref_total[GOLDEN_FRAME]) &&
4475#if CONFIG_EXT_REFS
4476 (ref_total[BWDREF_FRAME] == 0 ||
4477 cpi->interp_filter_selected[BWDREF_FRAME][ifilter] * 50 <
4478 ref_total[BWDREF_FRAME]) &&
4479#endif // CONFIG_EXT_REFS
4480 (ref_total[ALTREF_FRAME] == 0 ||
4481 cpi->interp_filter_selected[arf_idx][ifilter] * 50 <
4482 ref_total[ALTREF_FRAME]))
4483 mask |= 1 << ifilter;
4484 }
4485 return mask;
4486}
4487
4488#define DUMP_RECON_FRAMES 0
4489
4490#if DUMP_RECON_FRAMES == 1
4491// NOTE(zoeliu): For debug - Output the filtered reconstructed video.
Yaowu Xuf883b422016-08-30 14:01:10 -07004492static void dump_filtered_recon_frames(AV1_COMP *cpi) {
4493 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004494 const YV12_BUFFER_CONFIG *recon_buf = cm->frame_to_show;
4495 int h;
4496 char file_name[256] = "/tmp/enc_filtered_recon.yuv";
4497 FILE *f_recon = NULL;
4498
4499 if (recon_buf == NULL || !cm->show_frame) {
4500 printf("Frame %d is not ready or no show to dump.\n",
4501 cm->current_video_frame);
4502 return;
4503 }
4504
4505 if (cm->current_video_frame == 0) {
4506 if ((f_recon = fopen(file_name, "wb")) == NULL) {
4507 printf("Unable to open file %s to write.\n", file_name);
4508 return;
4509 }
4510 } else {
4511 if ((f_recon = fopen(file_name, "ab")) == NULL) {
4512 printf("Unable to open file %s to append.\n", file_name);
4513 return;
4514 }
4515 }
4516 printf(
4517 "\nFrame=%5d, encode_update_type[%5d]=%1d, show_existing_frame=%d, "
4518 "y_stride=%4d, uv_stride=%4d, width=%4d, height=%4d\n",
4519 cm->current_video_frame, cpi->twopass.gf_group.index,
4520 cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
4521 cm->show_existing_frame, recon_buf->y_stride, recon_buf->uv_stride,
4522 cm->width, cm->height);
4523
4524 // --- Y ---
4525 for (h = 0; h < cm->height; ++h) {
4526 fwrite(&recon_buf->y_buffer[h * recon_buf->y_stride], 1, cm->width,
4527 f_recon);
4528 }
4529 // --- U ---
4530 for (h = 0; h < (cm->height >> 1); ++h) {
4531 fwrite(&recon_buf->u_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4532 f_recon);
4533 }
4534 // --- V ---
4535 for (h = 0; h < (cm->height >> 1); ++h) {
4536 fwrite(&recon_buf->v_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4537 f_recon);
4538 }
4539
4540 fclose(f_recon);
4541}
4542#endif // DUMP_RECON_FRAMES
4543
Yaowu Xuf883b422016-08-30 14:01:10 -07004544static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004545 uint8_t *dest,
4546 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004547 AV1_COMMON *const cm = &cpi->common;
4548 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004549 struct segmentation *const seg = &cm->seg;
4550 TX_SIZE t;
4551 set_ext_overrides(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004552 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004553
4554 // Set the arf sign bias for this frame.
4555 set_arf_sign_bias(cpi);
4556
4557#if CONFIG_EXT_REFS
4558 // NOTE:
4559 // (1) Move the setup of the ref_frame_flags upfront as it would be
4560 // determined by the current frame properties;
4561 // (2) The setup of the ref_frame_flags applies to both show_existing_frame's
4562 // and the other cases.
4563 if (cm->current_video_frame > 0)
4564 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4565
4566 if (cm->show_existing_frame) {
4567 // NOTE(zoeliu): In BIDIR_PRED, the existing frame to show is the current
4568 // BWDREF_FRAME in the reference frame buffer.
4569 cm->frame_type = INTER_FRAME;
4570 cm->show_frame = 1;
4571 cpi->frame_flags = *frame_flags;
4572
4573 // In the case of show_existing frame, we will not send fresh flag
4574 // to decoder. Any change in the reference frame buffer can be done by
4575 // switching the virtual indices.
4576
4577 cpi->refresh_last_frame = 0;
4578 cpi->refresh_golden_frame = 0;
4579 cpi->refresh_bwd_ref_frame = 0;
4580 cpi->refresh_alt_ref_frame = 0;
4581
4582 cpi->rc.is_bwd_ref_frame = 0;
4583 cpi->rc.is_last_bipred_frame = 0;
4584 cpi->rc.is_bipred_frame = 0;
4585
4586 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004587 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004588
4589 // Set up frame to show to get ready for stats collection.
4590 cm->frame_to_show = get_frame_new_buffer(cm);
4591
4592#if DUMP_RECON_FRAMES == 1
4593 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4594 dump_filtered_recon_frames(cpi);
4595#endif // DUMP_RECON_FRAMES
4596
4597 // Update the LAST_FRAME in the reference frame buffer.
Yaowu Xuf883b422016-08-30 14:01:10 -07004598 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004599
4600 // Update frame flags
4601 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4602 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4603 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4604
4605 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4606
4607 // Update the frame type
4608 cm->last_frame_type = cm->frame_type;
4609
4610#if CONFIG_EXT_REFS
4611 // Since we allocate a spot for the OVERLAY frame in the gf group, we need
4612 // to do post-encoding update accordingly.
4613 if (cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004614 av1_set_target_rate(cpi);
4615 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004616 }
4617#endif
4618
4619 cm->last_width = cm->width;
4620 cm->last_height = cm->height;
4621
4622 ++cm->current_video_frame;
4623
4624 return;
4625 }
4626#endif // CONFIG_EXT_REFS
4627
4628 // Set default state for segment based loop filter update flags.
4629 cm->lf.mode_ref_delta_update = 0;
4630
4631 if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search)
4632 cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi);
4633
4634 // Set various flags etc to special state if it is a key frame.
4635 if (frame_is_intra_only(cm)) {
4636 // Reset the loop filter deltas and segmentation map.
Yaowu Xuf883b422016-08-30 14:01:10 -07004637 av1_reset_segment_features(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638
4639 // If segmentation is enabled force a map update for key frames.
4640 if (seg->enabled) {
4641 seg->update_map = 1;
4642 seg->update_data = 1;
4643 }
4644
4645 // The alternate reference frame cannot be active for a key frame.
4646 cpi->rc.source_alt_ref_active = 0;
4647
4648 cm->error_resilient_mode = oxcf->error_resilient_mode;
4649
4650 // By default, encoder assumes decoder can use prev_mi.
4651 if (cm->error_resilient_mode) {
4652 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
4653 cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_FORWARD;
4654 } else if (cm->intra_only) {
4655 // Only reset the current context.
4656 cm->reset_frame_context = RESET_FRAME_CONTEXT_CURRENT;
4657 }
4658 }
4659
4660 // For 1 pass CBR, check if we are dropping this frame.
4661 // Never drop on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004662 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004663 cm->frame_type != KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004664 if (av1_rc_drop_frame(cpi)) {
4665 av1_rc_postencode_update_drop_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004666 ++cm->current_video_frame;
4667 return;
4668 }
4669 }
4670
Yaowu Xuf883b422016-08-30 14:01:10 -07004671 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672
4673#if CONFIG_INTERNAL_STATS
4674 memset(cpi->mode_chosen_counts, 0,
4675 MAX_MODES * sizeof(*cpi->mode_chosen_counts));
4676#endif
4677
4678 if (cpi->sf.recode_loop == DISALLOW_RECODE) {
4679 encode_without_recode_loop(cpi);
4680 } else {
4681 encode_with_recode_loop(cpi, size, dest);
4682 }
4683
4684#ifdef OUTPUT_YUV_SKINMAP
4685 if (cpi->common.current_video_frame > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004686 av1_compute_skin_map(cpi, yuv_skinmap_file);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004687 }
4688#endif // OUTPUT_YUV_SKINMAP
4689
4690 // Special case code to reduce pulsing when key frames are forced at a
4691 // fixed interval. Note the reconstruction error if it is the frame before
4692 // the force key frame
4693 if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004694#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004695 if (cm->use_highbitdepth) {
4696 cpi->ambient_err =
Yaowu Xuf883b422016-08-30 14:01:10 -07004697 aom_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004699 cpi->ambient_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004700 }
4701#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004702 cpi->ambient_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4703#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004704 }
4705
4706 // If the encoder forced a KEY_FRAME decision
4707 if (cm->frame_type == KEY_FRAME) {
4708 cpi->refresh_last_frame = 1;
4709 }
4710
4711 cm->frame_to_show = get_frame_new_buffer(cm);
4712 cm->frame_to_show->color_space = cm->color_space;
4713 cm->frame_to_show->color_range = cm->color_range;
4714 cm->frame_to_show->render_width = cm->render_width;
4715 cm->frame_to_show->render_height = cm->render_height;
4716
4717#if CONFIG_EXT_REFS
4718// TODO(zoeliu): For non-ref frames, loop filtering may need to be turned
4719// off.
4720#endif // CONFIG_EXT_REFS
4721
4722 // Pick the loop filter level for the frame.
4723 loopfilter_frame(cpi, cm);
4724
4725 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004726 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004727
4728#if DUMP_RECON_FRAMES == 1
4729 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4730 if (cm->show_frame) dump_filtered_recon_frames(cpi);
4731#endif // DUMP_RECON_FRAMES
4732
Steinar Midtskogend06588a2016-05-06 13:48:20 +02004733#if CONFIG_CLPF
4734 aom_free(cm->clpf_blocks);
Steinar Midtskogenf4d41e62016-08-25 12:22:24 +02004735 cm->clpf_blocks = 0;
Steinar Midtskogend06588a2016-05-06 13:48:20 +02004736#endif
4737
Yaowu Xuc27fc142016-08-22 16:08:15 -07004738 if (cm->seg.update_map) update_reference_segmentation_map(cpi);
4739
4740 if (frame_is_intra_only(cm) == 0) {
4741 release_scaled_references(cpi);
4742 }
4743
Yaowu Xuf883b422016-08-30 14:01:10 -07004744 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004745
4746 for (t = TX_4X4; t <= TX_32X32; t++)
Yaowu Xuf883b422016-08-30 14:01:10 -07004747 av1_full_to_model_counts(cpi->td.counts->coef[t],
4748 cpi->td.rd_counts.coef_counts[t]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004749
4750 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4751#if CONFIG_ENTROPY
4752 cm->partial_prob_update = 0;
4753#endif // CONFIG_ENTROPY
Yaowu Xuf883b422016-08-30 14:01:10 -07004754 av1_adapt_coef_probs(cm);
4755 av1_adapt_intra_frame_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004756 }
4757
4758 if (!frame_is_intra_only(cm)) {
4759 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004760 av1_adapt_inter_frame_probs(cm);
4761 av1_adapt_mv_probs(cm, cm->allow_high_precision_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762 }
4763 }
4764
4765 if (cpi->refresh_golden_frame == 1)
4766 cpi->frame_flags |= FRAMEFLAGS_GOLDEN;
4767 else
4768 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4769
4770 if (cpi->refresh_alt_ref_frame == 1)
4771 cpi->frame_flags |= FRAMEFLAGS_ALTREF;
4772 else
4773 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4774
4775#if CONFIG_EXT_REFS
4776 if (cpi->refresh_bwd_ref_frame == 1)
4777 cpi->frame_flags |= FRAMEFLAGS_BWDREF;
4778 else
4779 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4780#endif // CONFIG_EXT_REFS
4781
4782#if !CONFIG_EXT_REFS
4783 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4784#endif // !CONFIG_EXT_REFS
4785
4786#if CONFIG_EXT_REFS
4787 cm->last3_frame_type = cm->last2_frame_type;
4788 cm->last2_frame_type = cm->last_frame_type;
4789#endif // CONFIG_EXT_REFS
4790 cm->last_frame_type = cm->frame_type;
4791
Yaowu Xuf883b422016-08-30 14:01:10 -07004792 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004793
4794#if 0
4795 output_frame_level_debug_stats(cpi);
4796#endif
4797
4798 if (cm->frame_type == KEY_FRAME) {
4799 // Tell the caller that the frame was coded as a key frame
4800 *frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY;
4801 } else {
4802 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4803 }
4804
4805 // Clear the one shot update flags for segmentation map and mode/ref loop
4806 // filter deltas.
4807 cm->seg.update_map = 0;
4808 cm->seg.update_data = 0;
4809 cm->lf.mode_ref_delta_update = 0;
4810
4811 // keep track of the last coded dimensions
4812 cm->last_width = cm->width;
4813 cm->last_height = cm->height;
4814
4815 // reset to normal state now that we are done.
4816 if (!cm->show_existing_frame) cm->last_show_frame = cm->show_frame;
4817
4818 if (cm->show_frame) {
4819#if CONFIG_EXT_REFS
4820// TODO(zoeliu): We may only swamp mi and prev_mi for those frames that are
4821// being used as reference.
4822#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004823 av1_swap_mi_and_prev_mi(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004824 // Don't increment frame counters if this was an altref buffer
4825 // update not a real frame
4826 ++cm->current_video_frame;
4827 }
4828
4829#if CONFIG_EXT_REFS
4830 // NOTE: Shall not refer to any frame not used as reference.
4831 if (cm->is_reference_frame)
4832#endif // CONFIG_EXT_REFS
4833 cm->prev_frame = cm->cur_frame;
4834}
4835
Yaowu Xuf883b422016-08-30 14:01:10 -07004836static void Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004837 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004838 if (cpi->oxcf.rc_mode == AOM_CBR) {
4839 av1_rc_get_one_pass_cbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004840 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004841 av1_rc_get_one_pass_vbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 }
4843 encode_frame_to_data_rate(cpi, size, dest, frame_flags);
4844}
4845
Yaowu Xuf883b422016-08-30 14:01:10 -07004846static void Pass2Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004847 unsigned int *frame_flags) {
4848 cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
4849
4850 encode_frame_to_data_rate(cpi, size, dest, frame_flags);
4851
4852#if CONFIG_EXT_REFS
4853 // Do not do post-encoding update for those frames that do not have a spot in
4854 // a gf group, but note that an OVERLAY frame always has a spot in a gf group,
4855 // even when show_existing_frame is used.
4856 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004857 av1_twopass_postencode_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004858 }
4859 check_show_existing_frame(cpi);
4860#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004861 av1_twopass_postencode_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004862#endif // CONFIG_EXT_REFS
4863}
4864
Yaowu Xuf883b422016-08-30 14:01:10 -07004865static void init_ref_frame_bufs(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 int i;
4867 BufferPool *const pool = cm->buffer_pool;
4868 cm->new_fb_idx = INVALID_IDX;
4869 for (i = 0; i < REF_FRAMES; ++i) {
4870 cm->ref_frame_map[i] = INVALID_IDX;
4871 pool->frame_bufs[i].ref_count = 0;
4872 }
4873}
4874
Yaowu Xuf883b422016-08-30 14:01:10 -07004875static void check_initial_width(AV1_COMP *cpi,
4876#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004877 int use_highbitdepth,
4878#endif
4879 int subsampling_x, int subsampling_y) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004880 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004881
4882 if (!cpi->initial_width ||
Yaowu Xuf883b422016-08-30 14:01:10 -07004883#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004884 cm->use_highbitdepth != use_highbitdepth ||
4885#endif
4886 cm->subsampling_x != subsampling_x ||
4887 cm->subsampling_y != subsampling_y) {
4888 cm->subsampling_x = subsampling_x;
4889 cm->subsampling_y = subsampling_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07004890#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004891 cm->use_highbitdepth = use_highbitdepth;
4892#endif
4893
4894 alloc_raw_frame_buffers(cpi);
4895 init_ref_frame_bufs(cm);
4896 alloc_util_frame_buffers(cpi);
4897
4898 init_motion_estimation(cpi); // TODO(agrange) This can be removed.
4899
4900 cpi->initial_width = cm->width;
4901 cpi->initial_height = cm->height;
4902 cpi->initial_mbs = cm->MBs;
4903 }
4904}
4905
Yaowu Xuf883b422016-08-30 14:01:10 -07004906int av1_receive_raw_frame(AV1_COMP *cpi, unsigned int frame_flags,
4907 YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
4908 int64_t end_time) {
4909 AV1_COMMON *const cm = &cpi->common;
4910 struct aom_usec_timer timer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004911 int res = 0;
4912 const int subsampling_x = sd->subsampling_x;
4913 const int subsampling_y = sd->subsampling_y;
Yaowu Xuf883b422016-08-30 14:01:10 -07004914#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004915 const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
4916#endif
4917
Yaowu Xuf883b422016-08-30 14:01:10 -07004918#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004919 check_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y);
4920#else
4921 check_initial_width(cpi, subsampling_x, subsampling_y);
Yaowu Xuf883b422016-08-30 14:01:10 -07004922#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004923
Yaowu Xuf883b422016-08-30 14:01:10 -07004924 aom_usec_timer_start(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004925
Yaowu Xuf883b422016-08-30 14:01:10 -07004926 if (av1_lookahead_push(cpi->lookahead, sd, time_stamp, end_time,
4927#if CONFIG_AOM_HIGHBITDEPTH
4928 use_highbitdepth,
4929#endif // CONFIG_AOM_HIGHBITDEPTH
4930 frame_flags))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004931 res = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -07004932 aom_usec_timer_mark(&timer);
4933 cpi->time_receive_data += aom_usec_timer_elapsed(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004934
4935 if ((cm->profile == PROFILE_0 || cm->profile == PROFILE_2) &&
4936 (subsampling_x != 1 || subsampling_y != 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004937 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004938 "Non-4:2:0 color format requires profile 1 or 3");
4939 res = -1;
4940 }
4941 if ((cm->profile == PROFILE_1 || cm->profile == PROFILE_3) &&
4942 (subsampling_x == 1 && subsampling_y == 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004943 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004944 "4:2:0 color format requires profile 0 or 2");
4945 res = -1;
4946 }
4947
4948 return res;
4949}
4950
Yaowu Xuf883b422016-08-30 14:01:10 -07004951static int frame_is_reference(const AV1_COMP *cpi) {
4952 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004953
4954 return cm->frame_type == KEY_FRAME || cpi->refresh_last_frame ||
4955 cpi->refresh_golden_frame ||
4956#if CONFIG_EXT_REFS
4957 cpi->refresh_bwd_ref_frame ||
4958#endif // CONFIG_EXT_REFS
4959 cpi->refresh_alt_ref_frame || !cm->error_resilient_mode ||
4960 cm->lf.mode_ref_delta_update || cm->seg.update_map ||
4961 cm->seg.update_data;
4962}
4963
Yaowu Xuf883b422016-08-30 14:01:10 -07004964static void adjust_frame_rate(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004965 const struct lookahead_entry *source) {
4966 int64_t this_duration;
4967 int step = 0;
4968
4969 if (source->ts_start == cpi->first_time_stamp_ever) {
4970 this_duration = source->ts_end - source->ts_start;
4971 step = 1;
4972 } else {
4973 int64_t last_duration =
4974 cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen;
4975
4976 this_duration = source->ts_end - cpi->last_end_time_stamp_seen;
4977
4978 // do a step update if the duration changes by 10%
4979 if (last_duration)
4980 step = (int)((this_duration - last_duration) * 10 / last_duration);
4981 }
4982
4983 if (this_duration) {
4984 if (step) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004985 av1_new_framerate(cpi, 10000000.0 / this_duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004986 } else {
4987 // Average this frame's rate into the last second's average
4988 // frame rate. If we haven't seen 1 second yet, then average
4989 // over the whole interval seen.
Yaowu Xuf883b422016-08-30 14:01:10 -07004990 const double interval = AOMMIN(
Yaowu Xuc27fc142016-08-22 16:08:15 -07004991 (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0);
4992 double avg_duration = 10000000.0 / cpi->framerate;
4993 avg_duration *= (interval - avg_duration + this_duration);
4994 avg_duration /= interval;
4995
Yaowu Xuf883b422016-08-30 14:01:10 -07004996 av1_new_framerate(cpi, 10000000.0 / avg_duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004997 }
4998 }
4999 cpi->last_time_stamp_seen = source->ts_start;
5000 cpi->last_end_time_stamp_seen = source->ts_end;
5001}
5002
5003// Returns 0 if this is not an alt ref else the offset of the source frame
5004// used as the arf midpoint.
Yaowu Xuf883b422016-08-30 14:01:10 -07005005static int get_arf_src_index(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005006 RATE_CONTROL *const rc = &cpi->rc;
5007 int arf_src_index = 0;
5008 if (is_altref_enabled(cpi)) {
5009 if (cpi->oxcf.pass == 2) {
5010 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5011 if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
5012 arf_src_index = gf_group->arf_src_offset[gf_group->index];
5013 }
5014 } else if (rc->source_alt_ref_pending) {
5015 arf_src_index = rc->frames_till_gf_update_due;
5016 }
5017 }
5018 return arf_src_index;
5019}
5020
5021#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005022static int get_brf_src_index(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005023 int brf_src_index = 0;
5024 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5025
5026 // TODO(zoeliu): We need to add the check on the -bwd_ref command line setup
5027 // flag.
5028 if (gf_group->bidir_pred_enabled[gf_group->index]) {
5029 if (cpi->oxcf.pass == 2) {
5030 if (gf_group->update_type[gf_group->index] == BRF_UPDATE)
5031 brf_src_index = gf_group->brf_src_offset[gf_group->index];
5032 } else {
5033 // TODO(zoeliu): To re-visit the setup for this scenario
5034 brf_src_index = cpi->rc.bipred_group_interval - 1;
5035 }
5036 }
5037
5038 return brf_src_index;
5039}
5040#endif // CONFIG_EXT_REFS
5041
Yaowu Xuf883b422016-08-30 14:01:10 -07005042static void check_src_altref(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005043 const struct lookahead_entry *source) {
5044 RATE_CONTROL *const rc = &cpi->rc;
5045
5046 // If pass == 2, the parameters set here will be reset in
Yaowu Xuf883b422016-08-30 14:01:10 -07005047 // av1_rc_get_second_pass_params()
Yaowu Xuc27fc142016-08-22 16:08:15 -07005048
5049 if (cpi->oxcf.pass == 2) {
5050 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5051 rc->is_src_frame_alt_ref =
5052#if CONFIG_EXT_REFS
5053 (gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE) ||
5054#endif
5055 (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
5056 } else {
5057 rc->is_src_frame_alt_ref =
5058 cpi->alt_ref_source && (source == cpi->alt_ref_source);
5059 }
5060
5061 if (rc->is_src_frame_alt_ref) {
5062 // Current frame is an ARF overlay frame.
5063 cpi->alt_ref_source = NULL;
5064
5065 // Don't refresh the last buffer for an ARF overlay frame. It will
5066 // become the GF so preserve last as an alternative prediction option.
5067 cpi->refresh_last_frame = 0;
5068 }
5069}
5070
5071#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07005072extern double av1_get_blockiness(const unsigned char *img1, int img1_pitch,
5073 const unsigned char *img2, int img2_pitch,
5074 int width, int height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005075
5076static void adjust_image_stat(double y, double u, double v, double all,
5077 ImageStat *s) {
5078 s->stat[Y] += y;
5079 s->stat[U] += u;
5080 s->stat[V] += v;
5081 s->stat[ALL] += all;
Yaowu Xuf883b422016-08-30 14:01:10 -07005082 s->worst = AOMMIN(s->worst, all);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005083}
5084
Yaowu Xuf883b422016-08-30 14:01:10 -07005085static void compute_internal_stats(AV1_COMP *cpi) {
5086 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005087 double samples = 0.0;
5088 uint32_t in_bit_depth = 8;
5089 uint32_t bit_depth = 8;
5090
Yaowu Xuf883b422016-08-30 14:01:10 -07005091#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005092 if (cm->use_highbitdepth) {
5093 in_bit_depth = cpi->oxcf.input_bit_depth;
5094 bit_depth = cm->bit_depth;
5095 }
5096#endif
5097 if (cm->show_frame) {
5098 const YV12_BUFFER_CONFIG *orig = cpi->Source;
5099 const YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show;
5100 double y, u, v, frame_all;
5101
5102 cpi->count++;
5103 if (cpi->b_calculate_psnr) {
5104 PSNR_STATS psnr;
5105 double frame_ssim2 = 0.0, weight = 0.0;
Yaowu Xuf883b422016-08-30 14:01:10 -07005106 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005107// TODO(yaowu): unify these two versions into one.
Yaowu Xuf883b422016-08-30 14:01:10 -07005108#if CONFIG_AOM_HIGHBITDEPTH
5109 aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005110#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005111 aom_calc_psnr(orig, recon, &psnr);
5112#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005113
5114 adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], psnr.psnr[0],
5115 &cpi->psnr);
5116 cpi->total_sq_error += psnr.sse[0];
5117 cpi->total_samples += psnr.samples[0];
5118 samples = psnr.samples[0];
5119// TODO(yaowu): unify these two versions into one.
Yaowu Xuf883b422016-08-30 14:01:10 -07005120#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005121 if (cm->use_highbitdepth)
5122 frame_ssim2 =
Yaowu Xuf883b422016-08-30 14:01:10 -07005123 aom_highbd_calc_ssim(orig, recon, &weight, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005124 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005125 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005126#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005127 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
5128#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005129
Yaowu Xuf883b422016-08-30 14:01:10 -07005130 cpi->worst_ssim = AOMMIN(cpi->worst_ssim, frame_ssim2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005131 cpi->summed_quality += frame_ssim2 * weight;
5132 cpi->summed_weights += weight;
5133
5134#if 0
5135 {
5136 FILE *f = fopen("q_used.stt", "a");
5137 fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
5138 cpi->common.current_video_frame, y2, u2, v2,
5139 frame_psnr2, frame_ssim2);
5140 fclose(f);
5141 }
5142#endif
5143 }
5144 if (cpi->b_calculate_blockiness) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005145#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 if (!cm->use_highbitdepth)
5147#endif
5148 {
5149 const double frame_blockiness =
Yaowu Xuf883b422016-08-30 14:01:10 -07005150 av1_get_blockiness(orig->y_buffer, orig->y_stride, recon->y_buffer,
5151 recon->y_stride, orig->y_width, orig->y_height);
5152 cpi->worst_blockiness = AOMMAX(cpi->worst_blockiness, frame_blockiness);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005153 cpi->total_blockiness += frame_blockiness;
5154 }
5155
5156 if (cpi->b_calculate_consistency) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005157#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005158 if (!cm->use_highbitdepth)
5159#endif
5160 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005161 const double this_inconsistency = aom_get_ssim_metrics(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005162 orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride,
5163 orig->y_width, orig->y_height, cpi->ssim_vars, &cpi->metrics, 1);
5164
5165 const double peak = (double)((1 << in_bit_depth) - 1);
5166 const double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07005167 aom_sse_to_psnr(samples, peak, cpi->total_inconsistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005168 if (consistency > 0.0)
5169 cpi->worst_consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07005170 AOMMIN(cpi->worst_consistency, consistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005171 cpi->total_inconsistency += this_inconsistency;
5172 }
5173 }
5174 }
5175
5176 frame_all =
Yaowu Xuf883b422016-08-30 14:01:10 -07005177 aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005178 adjust_image_stat(y, u, v, frame_all, &cpi->fastssim);
Yaowu Xuf883b422016-08-30 14:01:10 -07005179 frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005180 adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs);
5181 }
5182}
5183#endif // CONFIG_INTERNAL_STATS
5184
Yaowu Xuf883b422016-08-30 14:01:10 -07005185int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
5186 size_t *size, uint8_t *dest, int64_t *time_stamp,
5187 int64_t *time_end, int flush) {
5188 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
5189 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005190 BufferPool *const pool = cm->buffer_pool;
5191 RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07005192 struct aom_usec_timer cmptimer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005193 YV12_BUFFER_CONFIG *force_src_buffer = NULL;
5194 struct lookahead_entry *last_source = NULL;
5195 struct lookahead_entry *source = NULL;
5196 int arf_src_index;
5197#if CONFIG_EXT_REFS
5198 int brf_src_index;
5199#endif // CONFIG_EXT_REFS
5200 int i;
5201
5202#if CONFIG_BITSTREAM_DEBUG
5203 assert(cpi->oxcf.max_threads == 0 &&
5204 "bitstream debug tool does not support multithreading");
5205 bitstream_queue_record_write();
Angie Chiangcb9a9eb2016-09-01 16:10:50 -07005206 bitstream_queue_set_frame_write(cm->current_video_frame * 2 + cm->show_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005207#endif
5208
Yaowu Xuf883b422016-08-30 14:01:10 -07005209 aom_usec_timer_start(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005210
Yaowu Xuf883b422016-08-30 14:01:10 -07005211 av1_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005212
5213 // Is multi-arf enabled.
5214 // Note that at the moment multi_arf is only configured for 2 pass VBR
5215 if ((oxcf->pass == 2) && (cpi->oxcf.enable_auto_arf > 1))
5216 cpi->multi_arf_allowed = 1;
5217 else
5218 cpi->multi_arf_allowed = 0;
5219
5220 // Normal defaults
5221 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
5222 cm->refresh_frame_context =
5223 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
5224 ? REFRESH_FRAME_CONTEXT_FORWARD
5225 : REFRESH_FRAME_CONTEXT_BACKWARD;
5226
5227 cpi->refresh_last_frame = 1;
5228 cpi->refresh_golden_frame = 0;
5229#if CONFIG_EXT_REFS
5230 cpi->refresh_bwd_ref_frame = 0;
5231#endif // CONFIG_EXT_REFS
5232 cpi->refresh_alt_ref_frame = 0;
5233
5234#if CONFIG_EXT_REFS
5235 if (oxcf->pass == 2 && cm->show_existing_frame) {
5236 // Manage the source buffer and flush out the source frame that has been
5237 // coded already; Also get prepared for PSNR calculation if needed.
Yaowu Xuf883b422016-08-30 14:01:10 -07005238 if ((source = av1_lookahead_pop(cpi->lookahead, flush)) == NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239 *size = 0;
5240 return -1;
5241 }
5242 cpi->Source = &source->img;
5243 // TODO(zoeliu): To track down to determine whether it's needed to adjust
5244 // the frame rate.
5245 *time_stamp = source->ts_start;
5246 *time_end = source->ts_end;
5247
5248 // We need to adjust frame rate for an overlay frame
5249 if (cpi->rc.is_src_frame_alt_ref) {
5250 adjust_frame_rate(cpi, source);
5251 }
5252
5253 // Find a free buffer for the new frame, releasing the reference previously
5254 // held.
5255 if (cm->new_fb_idx != INVALID_IDX) {
5256 --pool->frame_bufs[cm->new_fb_idx].ref_count;
5257 }
5258 cm->new_fb_idx = get_free_fb(cm);
5259
5260 if (cm->new_fb_idx == INVALID_IDX) return -1;
5261
5262 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005263 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005264
5265 // Start with a 0 size frame.
5266 *size = 0;
5267
5268 // We need to update the gf_group for show_existing overlay frame
5269 if (cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005270 av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005271 }
5272
5273 Pass2Encode(cpi, size, dest, frame_flags);
5274
5275 if (cpi->b_calculate_psnr) generate_psnr_packet(cpi);
5276
5277#if CONFIG_INTERNAL_STATS
5278 compute_internal_stats(cpi);
5279 cpi->bytes += (int)(*size);
5280#endif // CONFIG_INTERNAL_STATS
5281
5282 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005283 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005284
5285 cm->show_existing_frame = 0;
5286 return 0;
5287 }
5288#endif // CONFIG_EXT_REFS
5289
5290 // Should we encode an arf frame.
5291 arf_src_index = get_arf_src_index(cpi);
5292 if (arf_src_index) {
5293 for (i = 0; i <= arf_src_index; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005294 struct lookahead_entry *e = av1_lookahead_peek(cpi->lookahead, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005295 // Avoid creating an alt-ref if there's a forced keyframe pending.
5296 if (e == NULL) {
5297 break;
Yaowu Xuf883b422016-08-30 14:01:10 -07005298 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005299 arf_src_index = 0;
5300 flush = 1;
5301 break;
5302 }
5303 }
5304 }
5305
5306 if (arf_src_index) {
5307 assert(arf_src_index <= rc->frames_to_key);
5308
Yaowu Xuf883b422016-08-30 14:01:10 -07005309 if ((source = av1_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005310 cpi->alt_ref_source = source;
5311
5312 if (oxcf->arnr_max_frames > 0) {
5313 // Produce the filtered ARF frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005314 av1_temporal_filter(cpi, arf_src_index);
5315 aom_extend_frame_borders(&cpi->alt_ref_buffer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005316 force_src_buffer = &cpi->alt_ref_buffer;
5317 }
5318
5319 cm->show_frame = 0;
5320 cm->intra_only = 0;
5321 cpi->refresh_alt_ref_frame = 1;
5322 cpi->refresh_golden_frame = 0;
5323 cpi->refresh_last_frame = 0;
5324 rc->is_src_frame_alt_ref = 0;
5325 }
5326 rc->source_alt_ref_pending = 0;
5327 }
5328
5329#if CONFIG_EXT_REFS
5330 rc->is_bwd_ref_frame = 0;
5331 brf_src_index = get_brf_src_index(cpi);
5332 if (brf_src_index) {
5333 assert(brf_src_index <= rc->frames_to_key);
Yaowu Xuf883b422016-08-30 14:01:10 -07005334 if ((source = av1_lookahead_peek(cpi->lookahead, brf_src_index)) != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335 cm->show_frame = 0;
5336 cm->intra_only = 0;
5337
5338 cpi->refresh_bwd_ref_frame = 1;
5339 cpi->refresh_last_frame = 0;
5340 cpi->refresh_golden_frame = 0;
5341 cpi->refresh_alt_ref_frame = 0;
5342
5343 rc->is_bwd_ref_frame = 1;
5344 }
5345 }
5346#endif // CONFIG_EXT_REFS
5347
5348 if (!source) {
5349 // Get last frame source.
5350 if (cm->current_video_frame > 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005351 if ((last_source = av1_lookahead_peek(cpi->lookahead, -1)) == NULL)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005352 return -1;
5353 }
5354
5355 // Read in the source frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005356 source = av1_lookahead_pop(cpi->lookahead, flush);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005357
5358 if (source != NULL) {
5359 cm->show_frame = 1;
5360 cm->intra_only = 0;
5361
5362 // Check to see if the frame should be encoded as an arf overlay.
5363 check_src_altref(cpi, source);
5364 }
5365 }
5366
5367 if (source) {
5368 cpi->un_scaled_source = cpi->Source =
5369 force_src_buffer ? force_src_buffer : &source->img;
5370
5371 cpi->unscaled_last_source = last_source != NULL ? &last_source->img : NULL;
5372
5373 *time_stamp = source->ts_start;
5374 *time_end = source->ts_end;
Yaowu Xuf883b422016-08-30 14:01:10 -07005375 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005376
5377 } else {
5378 *size = 0;
5379 if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005380 av1_end_first_pass(cpi); /* get last stats packet */
Yaowu Xuc27fc142016-08-22 16:08:15 -07005381 cpi->twopass.first_pass_done = 1;
5382 }
5383 return -1;
5384 }
5385
5386 if (source->ts_start < cpi->first_time_stamp_ever) {
5387 cpi->first_time_stamp_ever = source->ts_start;
5388 cpi->last_end_time_stamp_seen = source->ts_start;
5389 }
5390
5391 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005392 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005393
5394 // adjust frame rates based on timestamps given
5395 if (cm->show_frame) adjust_frame_rate(cpi, source);
5396
5397 // Find a free buffer for the new frame, releasing the reference previously
5398 // held.
5399 if (cm->new_fb_idx != INVALID_IDX) {
5400 --pool->frame_bufs[cm->new_fb_idx].ref_count;
5401 }
5402 cm->new_fb_idx = get_free_fb(cm);
5403
5404 if (cm->new_fb_idx == INVALID_IDX) return -1;
5405
5406 cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
5407
5408#if CONFIG_EXT_REFS
5409 if (oxcf->pass == 2) {
5410 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5411 cpi->alt_fb_idx = cpi->arf_map[gf_group->arf_ref_idx[gf_group->index]];
5412 }
5413#else
5414 if (cpi->multi_arf_allowed) {
5415 if (cm->frame_type == KEY_FRAME) {
5416 init_buffer_indices(cpi);
5417 } else if (oxcf->pass == 2) {
5418 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5419 cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
5420 }
5421 }
5422#endif
5423 // Start with a 0 size frame.
5424 *size = 0;
5425
5426 cpi->frame_flags = *frame_flags;
5427
5428 if (oxcf->pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005429 av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005430 } else if (oxcf->pass == 1) {
5431 set_frame_size(cpi);
5432 }
5433
5434 if (cpi->oxcf.pass != 0 || frame_is_intra_only(cm) == 1) {
5435 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i)
5436 cpi->scaled_ref_idx[i] = INVALID_IDX;
5437 }
5438
5439#if CONFIG_AOM_QM
5440 cm->using_qmatrix = cpi->oxcf.using_qm;
5441 cm->min_qmlevel = cpi->oxcf.qm_minlevel;
5442 cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
5443#endif
5444
5445 if (oxcf->pass == 1) {
5446 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07005447 av1_first_pass(cpi, source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005448 } else if (oxcf->pass == 2) {
5449 Pass2Encode(cpi, size, dest, frame_flags);
5450 } else {
5451 // One pass encode
5452 Pass0Encode(cpi, size, dest, frame_flags);
5453 }
5454
5455 if (!cm->error_resilient_mode)
5456 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
5457
5458 // No frame encoded, or frame was dropped, release scaled references.
5459 if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
5460 release_scaled_references(cpi);
5461 }
5462
5463 if (*size > 0) {
5464 cpi->droppable = !frame_is_reference(cpi);
5465 }
5466
Yaowu Xuf883b422016-08-30 14:01:10 -07005467 aom_usec_timer_mark(&cmptimer);
5468 cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005469
5470 if (cpi->b_calculate_psnr && oxcf->pass != 1 && cm->show_frame)
5471 generate_psnr_packet(cpi);
5472
5473#if CONFIG_INTERNAL_STATS
5474 if (oxcf->pass != 1) {
5475 compute_internal_stats(cpi);
5476 cpi->bytes += (int)(*size);
5477 }
5478#endif // CONFIG_INTERNAL_STATS
5479
Yaowu Xuf883b422016-08-30 14:01:10 -07005480 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005481
5482 return 0;
5483}
5484
Yaowu Xuf883b422016-08-30 14:01:10 -07005485int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest) {
5486 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005487 if (!cm->show_frame) {
5488 return -1;
5489 } else {
5490 int ret;
5491 if (cm->frame_to_show) {
5492 *dest = *cm->frame_to_show;
5493 dest->y_width = cm->width;
5494 dest->y_height = cm->height;
5495 dest->uv_width = cm->width >> cm->subsampling_x;
5496 dest->uv_height = cm->height >> cm->subsampling_y;
5497 ret = 0;
5498 } else {
5499 ret = -1;
5500 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005501 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005502 return ret;
5503 }
5504}
5505
Yaowu Xuf883b422016-08-30 14:01:10 -07005506int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005507 if (cpi->last_show_frame_buf_idx == INVALID_IDX) return -1;
5508
5509 *frame =
5510 cpi->common.buffer_pool->frame_bufs[cpi->last_show_frame_buf_idx].buf;
5511 return 0;
5512}
5513
Yaowu Xuf883b422016-08-30 14:01:10 -07005514int av1_set_internal_size(AV1_COMP *cpi, AOM_SCALING horiz_mode,
5515 AOM_SCALING vert_mode) {
5516 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005517 int hr = 0, hs = 0, vr = 0, vs = 0;
5518
5519 if (horiz_mode > ONETWO || vert_mode > ONETWO) return -1;
5520
5521 Scale2Ratio(horiz_mode, &hr, &hs);
5522 Scale2Ratio(vert_mode, &vr, &vs);
5523
5524 // always go to the next whole number
5525 cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs;
5526 cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs;
5527 assert(cm->width <= cpi->initial_width);
5528 assert(cm->height <= cpi->initial_height);
5529
5530 update_frame_size(cpi);
5531
5532 return 0;
5533}
5534
Yaowu Xuf883b422016-08-30 14:01:10 -07005535int av1_set_size_literal(AV1_COMP *cpi, unsigned int width,
5536 unsigned int height) {
5537 AV1_COMMON *cm = &cpi->common;
5538#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005539 check_initial_width(cpi, cm->use_highbitdepth, 1, 1);
5540#else
5541 check_initial_width(cpi, 1, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07005542#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005543
5544 if (width) {
5545 cm->width = width;
5546 if (cm->width > cpi->initial_width) {
5547 cm->width = cpi->initial_width;
5548 printf("Warning: Desired width too large, changed to %d\n", cm->width);
5549 }
5550 }
5551
5552 if (height) {
5553 cm->height = height;
5554 if (cm->height > cpi->initial_height) {
5555 cm->height = cpi->initial_height;
5556 printf("Warning: Desired height too large, changed to %d\n", cm->height);
5557 }
5558 }
5559 assert(cm->width <= cpi->initial_width);
5560 assert(cm->height <= cpi->initial_height);
5561
5562 update_frame_size(cpi);
5563
5564 return 0;
5565}
5566
Yaowu Xuf883b422016-08-30 14:01:10 -07005567int av1_get_quantizer(AV1_COMP *cpi) { return cpi->common.base_qindex; }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005568
Yaowu Xuf883b422016-08-30 14:01:10 -07005569void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005570 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005571 (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF)) {
5572 int ref = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005573
Yaowu Xuf883b422016-08-30 14:01:10 -07005574 if (flags & AOM_EFLAG_NO_REF_LAST) {
5575 ref ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005576#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005577 ref ^= AOM_LAST2_FLAG;
5578 ref ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005579#endif // CONFIG_EXT_REFS
5580 }
5581
Yaowu Xuf883b422016-08-30 14:01:10 -07005582 if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583
Yaowu Xuf883b422016-08-30 14:01:10 -07005584 if (flags & AOM_EFLAG_NO_REF_ARF) ref ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585
Yaowu Xuf883b422016-08-30 14:01:10 -07005586 av1_use_as_reference(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005587 }
5588
5589 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005590 (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
5591 AOM_EFLAG_FORCE_GF | AOM_EFLAG_FORCE_ARF)) {
5592 int upd = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005593
Yaowu Xuf883b422016-08-30 14:01:10 -07005594 if (flags & AOM_EFLAG_NO_UPD_LAST) {
5595 upd ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005596#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005597 upd ^= AOM_LAST2_FLAG;
5598 upd ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005599#endif // CONFIG_EXT_REFS
5600 }
5601
Yaowu Xuf883b422016-08-30 14:01:10 -07005602 if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005603
Yaowu Xuf883b422016-08-30 14:01:10 -07005604 if (flags & AOM_EFLAG_NO_UPD_ARF) upd ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005605
Yaowu Xuf883b422016-08-30 14:01:10 -07005606 av1_update_reference(cpi, upd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005607 }
5608
Yaowu Xuf883b422016-08-30 14:01:10 -07005609 if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
5610 av1_update_entropy(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005611 }
5612}