blob: 58e60db47c2e25a2776b6ec625b38a2481c5117a [file] [log] [blame]
Yaowu Xuc27fc142016-08-22 16:08:15 -07001/*
Urvang Joshi8a02d762016-07-28 15:51:12 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Yaowu Xuc27fc142016-08-22 16:08:15 -07003 *
Urvang Joshi8a02d762016-07-28 15:51:12 -07004 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
Yaowu Xuc27fc142016-08-22 16:08:15 -070010 */
11
12#include <limits.h>
13#include <math.h>
14#include <stdio.h>
15
Yaowu Xuf883b422016-08-30 14:01:10 -070016#include "./aom_config.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070017
18#include "av1/common/alloccommon.h"
19#if CONFIG_CLPF
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +020020#include "aom/aom_image.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "av1/common/clpf.h"
Steinar Midtskogend06588a2016-05-06 13:48:20 +020022#include "av1/encoder/clpf_rdo.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#endif
24#if CONFIG_DERING
25#include "av1/common/dering.h"
26#endif // CONFIG_DERING
27#include "av1/common/filter.h"
28#include "av1/common/idct.h"
29#include "av1/common/reconinter.h"
30#include "av1/common/reconintra.h"
31#include "av1/common/tile_common.h"
32
33#include "av1/encoder/aq_complexity.h"
34#include "av1/encoder/aq_cyclicrefresh.h"
35#include "av1/encoder/aq_variance.h"
36#include "av1/encoder/bitstream.h"
37#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -070038#include "aom_dsp/buf_ans.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070039#endif
40#include "av1/encoder/context_tree.h"
41#include "av1/encoder/encodeframe.h"
42#include "av1/encoder/encodemv.h"
43#include "av1/encoder/encoder.h"
44#include "av1/encoder/ethread.h"
45#include "av1/encoder/firstpass.h"
46#include "av1/encoder/mbgraph.h"
47#include "av1/encoder/picklpf.h"
48#if CONFIG_LOOP_RESTORATION
49#include "av1/encoder/pickrst.h"
50#endif // CONFIG_LOOP_RESTORATION
51#include "av1/encoder/ratectrl.h"
52#include "av1/encoder/rd.h"
53#include "av1/encoder/resize.h"
54#include "av1/encoder/segmentation.h"
55#include "av1/encoder/speed_features.h"
56#include "av1/encoder/temporal_filter.h"
57
Yaowu Xuf883b422016-08-30 14:01:10 -070058#include "./av1_rtcd.h"
59#include "./aom_dsp_rtcd.h"
60#include "./aom_scale_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070061#include "aom_dsp/psnr.h"
62#if CONFIG_INTERNAL_STATS
63#include "aom_dsp/ssim.h"
64#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070065#include "aom_dsp/aom_dsp_common.h"
66#include "aom_dsp/aom_filter.h"
Jingning Han1aab8182016-06-03 11:09:06 -070067#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070068#include "aom_ports/mem.h"
69#include "aom_ports/system_state.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070070#include "aom_scale/aom_scale.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070071#if CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070072#include "aom_util/debug_util.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070073#endif // CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070074
75#define AM_SEGMENT_ID_INACTIVE 7
76#define AM_SEGMENT_ID_ACTIVE 0
77
78#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
79
80#define ALTREF_HIGH_PRECISION_MV 1 // Whether to use high precision mv
81 // for altref computation.
82#define HIGH_PRECISION_MV_QTHRESH 200 // Q threshold for high precision
83 // mv. Choose a very high value for
84 // now so that HIGH_PRECISION is always
85 // chosen.
86// #define OUTPUT_YUV_REC
87#ifdef OUTPUT_YUV_DENOISED
88FILE *yuv_denoised_file = NULL;
89#endif
90#ifdef OUTPUT_YUV_SKINMAP
91FILE *yuv_skinmap_file = NULL;
92#endif
93#ifdef OUTPUT_YUV_REC
94FILE *yuv_rec_file;
95#define FILE_NAME_LEN 100
96#endif
97
98#if 0
99FILE *framepsnr;
100FILE *kf_list;
101FILE *keyfile;
102#endif
103
Urvang Joshib5ed3502016-10-17 16:38:05 -0700104#if CONFIG_INTERNAL_STATS
105typedef enum { Y, U, V, ALL } STAT_TYPE;
106#endif // CONFIG_INTERNAL_STATS
107
Yaowu Xuf883b422016-08-30 14:01:10 -0700108static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700109 switch (mode) {
110 case NORMAL:
111 *hr = 1;
112 *hs = 1;
113 break;
114 case FOURFIVE:
115 *hr = 4;
116 *hs = 5;
117 break;
118 case THREEFIVE:
119 *hr = 3;
120 *hs = 5;
121 break;
122 case ONETWO:
123 *hr = 1;
124 *hs = 2;
125 break;
126 default:
127 *hr = 1;
128 *hs = 1;
129 assert(0);
130 break;
131 }
132}
133
134// Mark all inactive blocks as active. Other segmentation features may be set
135// so memset cannot be used, instead only inactive blocks should be reset.
Yaowu Xuf883b422016-08-30 14:01:10 -0700136static void suppress_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137 unsigned char *const seg_map = cpi->segmentation_map;
138 int i;
139 if (cpi->active_map.enabled || cpi->active_map.update)
140 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
141 if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
142 seg_map[i] = AM_SEGMENT_ID_ACTIVE;
143}
144
Yaowu Xuf883b422016-08-30 14:01:10 -0700145static void apply_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700146 struct segmentation *const seg = &cpi->common.seg;
147 unsigned char *const seg_map = cpi->segmentation_map;
148 const unsigned char *const active_map = cpi->active_map.map;
149 int i;
150
151 assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
152
153 if (frame_is_intra_only(&cpi->common)) {
154 cpi->active_map.enabled = 0;
155 cpi->active_map.update = 1;
156 }
157
158 if (cpi->active_map.update) {
159 if (cpi->active_map.enabled) {
160 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
161 if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700162 av1_enable_segmentation(seg);
163 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
164 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700165 // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
166 // filter level being zero regardless of the value of seg->abs_delta.
Yaowu Xuf883b422016-08-30 14:01:10 -0700167 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
168 -MAX_LOOP_FILTER);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700169 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700170 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
171 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700172 if (seg->enabled) {
173 seg->update_data = 1;
174 seg->update_map = 1;
175 }
176 }
177 cpi->active_map.update = 0;
178 }
179}
180
Yaowu Xuf883b422016-08-30 14:01:10 -0700181int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
182 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700183 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
184 unsigned char *const active_map_8x8 = cpi->active_map.map;
185 const int mi_rows = cpi->common.mi_rows;
186 const int mi_cols = cpi->common.mi_cols;
187 cpi->active_map.update = 1;
188 if (new_map_16x16) {
189 int r, c;
190 for (r = 0; r < mi_rows; ++r) {
191 for (c = 0; c < mi_cols; ++c) {
192 active_map_8x8[r * mi_cols + c] =
193 new_map_16x16[(r >> 1) * cols + (c >> 1)]
194 ? AM_SEGMENT_ID_ACTIVE
195 : AM_SEGMENT_ID_INACTIVE;
196 }
197 }
198 cpi->active_map.enabled = 1;
199 } else {
200 cpi->active_map.enabled = 0;
201 }
202 return 0;
203 } else {
204 return -1;
205 }
206}
207
Yaowu Xuf883b422016-08-30 14:01:10 -0700208int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
209 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700210 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
211 new_map_16x16) {
212 unsigned char *const seg_map_8x8 = cpi->segmentation_map;
213 const int mi_rows = cpi->common.mi_rows;
214 const int mi_cols = cpi->common.mi_cols;
215 memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
216 if (cpi->active_map.enabled) {
217 int r, c;
218 for (r = 0; r < mi_rows; ++r) {
219 for (c = 0; c < mi_cols; ++c) {
220 // Cyclic refresh segments are considered active despite not having
221 // AM_SEGMENT_ID_ACTIVE
222 new_map_16x16[(r >> 1) * cols + (c >> 1)] |=
223 seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
224 }
225 }
226 }
227 return 0;
228 } else {
229 return -1;
230 }
231}
232
Yaowu Xuf883b422016-08-30 14:01:10 -0700233void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700234 MACROBLOCK *const mb = &cpi->td.mb;
235 cpi->common.allow_high_precision_mv = allow_high_precision_mv;
236
237#if CONFIG_REF_MV
238 if (cpi->common.allow_high_precision_mv) {
239 int i;
240 for (i = 0; i < NMV_CONTEXTS; ++i) {
241 mb->mv_cost_stack[i] = mb->nmvcost_hp[i];
242 mb->mvsadcost = mb->nmvsadcost_hp;
243 }
244 } else {
245 int i;
246 for (i = 0; i < NMV_CONTEXTS; ++i) {
247 mb->mv_cost_stack[i] = mb->nmvcost[i];
248 mb->mvsadcost = mb->nmvsadcost;
249 }
250 }
251#else
252 if (cpi->common.allow_high_precision_mv) {
253 mb->mvcost = mb->nmvcost_hp;
254 mb->mvsadcost = mb->nmvcost_hp;
255 } else {
256 mb->mvcost = mb->nmvcost;
257 mb->mvsadcost = mb->nmvcost;
258 }
259#endif
260}
261
Yaowu Xuf883b422016-08-30 14:01:10 -0700262static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700264 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700265 return BLOCK_64X64;
266
Yaowu Xuf883b422016-08-30 14:01:10 -0700267 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700268 return BLOCK_128X128;
269
Yaowu Xuf883b422016-08-30 14:01:10 -0700270 assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700271
272 assert(IMPLIES(cpi->common.tile_cols > 1,
273 cpi->common.tile_width % MAX_MIB_SIZE == 0));
274 assert(IMPLIES(cpi->common.tile_rows > 1,
275 cpi->common.tile_height % MAX_MIB_SIZE == 0));
276
277 // TODO(any): Possibly could improve this with a heuristic.
278 return BLOCK_128X128;
279#else
280 (void)cpi;
281 return BLOCK_64X64;
282#endif // CONFIG_EXT_PARTITION
283}
284
Yaowu Xuf883b422016-08-30 14:01:10 -0700285static void setup_frame(AV1_COMP *cpi) {
286 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700287 // Set up entropy context depending on frame type. The decoder mandates
288 // the use of the default context, index 0, for keyframes and inter
289 // frames where the error_resilient_mode or intra_only flag is set. For
290 // other inter-frames the encoder currently uses only two contexts;
291 // context 1 for ALTREF frames and context 0 for the others.
292 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700293 av1_setup_past_independence(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700294 } else {
295#if CONFIG_EXT_REFS
296 const GF_GROUP *gf_group = &cpi->twopass.gf_group;
297 if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
298 cm->frame_context_idx = EXT_ARF_FRAME;
299 else if (cpi->refresh_alt_ref_frame)
300 cm->frame_context_idx = ARF_FRAME;
301#else
302 if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu6cfaff92016-10-18 17:12:11 -0700303#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700304 else if (cpi->rc.is_src_frame_alt_ref)
305 cm->frame_context_idx = OVERLAY_FRAME;
306 else if (cpi->refresh_golden_frame)
307 cm->frame_context_idx = GLD_FRAME;
308#if CONFIG_EXT_REFS
309 else if (cpi->refresh_bwd_ref_frame)
310 cm->frame_context_idx = BRF_FRAME;
Zoe Liu6cfaff92016-10-18 17:12:11 -0700311#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700312 else
313 cm->frame_context_idx = REGULAR_FRAME;
314 }
315
316 if (cm->frame_type == KEY_FRAME) {
317 cpi->refresh_golden_frame = 1;
318 cpi->refresh_alt_ref_frame = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700319 av1_zero(cpi->interp_filter_selected);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700320 } else {
321 *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -0700322 av1_zero(cpi->interp_filter_selected[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700323 }
324
325 cpi->vaq_refresh = 0;
326
327 set_sb_size(cm, select_sb_size(cpi));
328}
329
Yaowu Xuf883b422016-08-30 14:01:10 -0700330static void av1_enc_setup_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700331 int i;
332 cm->mi = cm->mip + cm->mi_stride + 1;
333 memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
334 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
335 // Clear top border row
336 memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
337 // Clear left border column
338 for (i = 1; i < cm->mi_rows + 1; ++i)
339 memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
340
341 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
342 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
343
344 memset(cm->mi_grid_base, 0,
345 cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
346}
347
Yaowu Xuf883b422016-08-30 14:01:10 -0700348static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
349 cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700350 if (!cm->mip) return 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700351 cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700352 if (!cm->prev_mip) return 1;
353 cm->mi_alloc_size = mi_size;
354
Yaowu Xuf883b422016-08-30 14:01:10 -0700355 cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700356 if (!cm->mi_grid_base) return 1;
357 cm->prev_mi_grid_base =
Yaowu Xuf883b422016-08-30 14:01:10 -0700358 (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700359 if (!cm->prev_mi_grid_base) return 1;
360
361 return 0;
362}
363
Yaowu Xuf883b422016-08-30 14:01:10 -0700364static void av1_enc_free_mi(AV1_COMMON *cm) {
365 aom_free(cm->mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 cm->mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700367 aom_free(cm->prev_mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700368 cm->prev_mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700369 aom_free(cm->mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700370 cm->mi_grid_base = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700371 aom_free(cm->prev_mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700372 cm->prev_mi_grid_base = NULL;
373}
374
Yaowu Xuf883b422016-08-30 14:01:10 -0700375static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700376 // Current mip will be the prev_mip for the next frame.
377 MODE_INFO **temp_base = cm->prev_mi_grid_base;
378 MODE_INFO *temp = cm->prev_mip;
379 cm->prev_mip = cm->mip;
380 cm->mip = temp;
381
382 // Update the upper left visible macroblock ptrs.
383 cm->mi = cm->mip + cm->mi_stride + 1;
384 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
385
386 cm->prev_mi_grid_base = cm->mi_grid_base;
387 cm->mi_grid_base = temp_base;
388 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
389 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
390}
391
Yaowu Xuf883b422016-08-30 14:01:10 -0700392void av1_initialize_enc(void) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700393 static volatile int init_done = 0;
394
395 if (!init_done) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700396 av1_rtcd();
397 aom_dsp_rtcd();
398 aom_scale_rtcd();
399 av1_init_intra_predictors();
400 av1_init_me_luts();
401 av1_rc_init_minq_luts();
402 av1_entropy_mv_init();
403 av1_encode_token_init();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700404#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700405 av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700406#endif
407 init_done = 1;
408 }
409}
410
Yaowu Xuf883b422016-08-30 14:01:10 -0700411static void dealloc_compressor_data(AV1_COMP *cpi) {
412 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700413 int i;
414
Yaowu Xuf883b422016-08-30 14:01:10 -0700415 aom_free(cpi->mbmi_ext_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700416 cpi->mbmi_ext_base = NULL;
417
Yushin Cho77bba8d2016-11-04 16:36:56 -0700418#if CONFIG_PVQ
419 if (cpi->oxcf.pass != 1) {
420 const int tile_cols = 1 << cm->log2_tile_cols;
421 const int tile_rows = 1 << cm->log2_tile_rows;
422 int tile_col, tile_row;
423
424 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
425 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
426 TileDataEnc *tile_data =
427 &cpi->tile_data[tile_row * tile_cols + tile_col];
428 aom_free(tile_data->pvq_q.buf);
429 }
430 }
431#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700432 aom_free(cpi->tile_data);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700433 cpi->tile_data = NULL;
434
435 // Delete sementation map
Yaowu Xuf883b422016-08-30 14:01:10 -0700436 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700437 cpi->segmentation_map = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700438
Yaowu Xuf883b422016-08-30 14:01:10 -0700439 av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700440 cpi->cyclic_refresh = NULL;
441
Yaowu Xuf883b422016-08-30 14:01:10 -0700442 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700443 cpi->active_map.map = NULL;
444
445 // Free up-sampled reference buffers.
446 for (i = 0; i < (REF_FRAMES + 1); i++)
Yaowu Xuf883b422016-08-30 14:01:10 -0700447 aom_free_frame_buffer(&cpi->upsampled_ref_bufs[i].buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700448
Yaowu Xuf883b422016-08-30 14:01:10 -0700449 av1_free_ref_frame_buffers(cm->buffer_pool);
450 av1_free_context_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700451
Yaowu Xuf883b422016-08-30 14:01:10 -0700452 aom_free_frame_buffer(&cpi->last_frame_uf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700453#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700454 aom_free_frame_buffer(&cpi->last_frame_db);
455 av1_free_restoration_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700456#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700457 aom_free_frame_buffer(&cpi->scaled_source);
458 aom_free_frame_buffer(&cpi->scaled_last_source);
459 aom_free_frame_buffer(&cpi->alt_ref_buffer);
460 av1_lookahead_destroy(cpi->lookahead);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700461
Yaowu Xuf883b422016-08-30 14:01:10 -0700462 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700463 cpi->tile_tok[0][0] = 0;
464
Yaowu Xuf883b422016-08-30 14:01:10 -0700465 av1_free_pc_tree(&cpi->td);
466 av1_free_var_tree(&cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700467
Urvang Joshib100db72016-10-12 16:28:56 -0700468#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700469 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -0700470 aom_free(cpi->td.mb.palette_buffer);
Urvang Joshib100db72016-10-12 16:28:56 -0700471#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700472
473 if (cpi->source_diff_var != NULL) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700474 aom_free(cpi->source_diff_var);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700475 cpi->source_diff_var = NULL;
476 }
477#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -0700478 aom_buf_ans_free(&cpi->buf_ans);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700479#endif // CONFIG_ANS
480}
481
Yaowu Xuf883b422016-08-30 14:01:10 -0700482static void save_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700483 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700484 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700485#if CONFIG_REF_MV
486 int i;
487#endif
488
489// Stores a snapshot of key state variables which can subsequently be
Yaowu Xuf883b422016-08-30 14:01:10 -0700490// restored with a call to av1_restore_coding_context. These functions are
491// intended for use in a re-code loop in av1_compress_frame where the
Yaowu Xuc27fc142016-08-22 16:08:15 -0700492// quantizer value is adjusted between loop iterations.
493#if CONFIG_REF_MV
494 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700495 av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
Urvang Joshibffc0b52016-07-25 13:38:49 -0700496 av1_copy(cc->nmv_costs, cpi->nmv_costs);
497 av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700498 }
499#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700500 av1_copy(cc->nmvjointcost, cpi->td.mb.nmvjointcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700501#endif
502
Urvang Joshibffc0b52016-07-25 13:38:49 -0700503 av1_copy(cc->nmvcosts, cpi->nmvcosts);
504 av1_copy(cc->nmvcosts_hp, cpi->nmvcosts_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700505
Yaowu Xuf883b422016-08-30 14:01:10 -0700506 av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
507 av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700508
509 cc->fc = *cm->fc;
510}
511
Yaowu Xuf883b422016-08-30 14:01:10 -0700512static void restore_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700513 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700514 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700515#if CONFIG_REF_MV
516 int i;
517#endif
518
519// Restore key state variables to the snapshot state stored in the
Yaowu Xuf883b422016-08-30 14:01:10 -0700520// previous call to av1_save_coding_context.
Yaowu Xuc27fc142016-08-22 16:08:15 -0700521#if CONFIG_REF_MV
522 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700523 av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
Urvang Joshibffc0b52016-07-25 13:38:49 -0700524 av1_copy(cpi->nmv_costs, cc->nmv_costs);
525 av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700526 }
527#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700528 av1_copy(cpi->td.mb.nmvjointcost, cc->nmvjointcost);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700529#endif
530
Urvang Joshibffc0b52016-07-25 13:38:49 -0700531 av1_copy(cpi->nmvcosts, cc->nmvcosts);
532 av1_copy(cpi->nmvcosts_hp, cc->nmvcosts_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700533
Yaowu Xuf883b422016-08-30 14:01:10 -0700534 av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
535 av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700536
537 *cm->fc = cc->fc;
538}
539
Yaowu Xuf883b422016-08-30 14:01:10 -0700540static void configure_static_seg_features(AV1_COMP *cpi) {
541 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700542 const RATE_CONTROL *const rc = &cpi->rc;
543 struct segmentation *const seg = &cm->seg;
544
545 int high_q = (int)(rc->avg_q > 48.0);
546 int qi_delta;
547
548 // Disable and clear down for KF
549 if (cm->frame_type == KEY_FRAME) {
550 // Clear down the global segmentation map
551 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
552 seg->update_map = 0;
553 seg->update_data = 0;
554 cpi->static_mb_pct = 0;
555
556 // Disable segmentation
Yaowu Xuf883b422016-08-30 14:01:10 -0700557 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700558
559 // Clear down the segment features.
Yaowu Xuf883b422016-08-30 14:01:10 -0700560 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700561 } else if (cpi->refresh_alt_ref_frame) {
562 // If this is an alt ref frame
563 // Clear down the global segmentation map
564 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
565 seg->update_map = 0;
566 seg->update_data = 0;
567 cpi->static_mb_pct = 0;
568
569 // Disable segmentation and individual segment features by default
Yaowu Xuf883b422016-08-30 14:01:10 -0700570 av1_disable_segmentation(seg);
571 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700572
573 // Scan frames from current to arf frame.
574 // This function re-enables segmentation if appropriate.
Yaowu Xuf883b422016-08-30 14:01:10 -0700575 av1_update_mbgraph_stats(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700576
577 // If segmentation was enabled set those features needed for the
578 // arf itself.
579 if (seg->enabled) {
580 seg->update_map = 1;
581 seg->update_data = 1;
582
583 qi_delta =
Yaowu Xuf883b422016-08-30 14:01:10 -0700584 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
585 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
586 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700587
Yaowu Xuf883b422016-08-30 14:01:10 -0700588 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
589 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700590
591 // Where relevant assume segment data is delta data
592 seg->abs_delta = SEGMENT_DELTADATA;
593 }
594 } else if (seg->enabled) {
595 // All other frames if segmentation has been enabled
596
597 // First normal frame in a valid gf or alt ref group
598 if (rc->frames_since_golden == 0) {
599 // Set up segment features for normal frames in an arf group
600 if (rc->source_alt_ref_active) {
601 seg->update_map = 0;
602 seg->update_data = 1;
603 seg->abs_delta = SEGMENT_DELTADATA;
604
Yaowu Xuf883b422016-08-30 14:01:10 -0700605 qi_delta =
606 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
607 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
608 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700609
Yaowu Xuf883b422016-08-30 14:01:10 -0700610 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
611 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700612
613 // Segment coding disabled for compred testing
614 if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700615 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
616 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
617 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700618 }
619 } else {
620 // Disable segmentation and clear down features if alt ref
621 // is not active for this group
622
Yaowu Xuf883b422016-08-30 14:01:10 -0700623 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700624
625 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
626
627 seg->update_map = 0;
628 seg->update_data = 0;
629
Yaowu Xuf883b422016-08-30 14:01:10 -0700630 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700631 }
632 } else if (rc->is_src_frame_alt_ref) {
633 // Special case where we are coding over the top of a previous
634 // alt ref frame.
635 // Segment coding disabled for compred testing
636
637 // Enable ref frame features for segment 0 as well
Yaowu Xuf883b422016-08-30 14:01:10 -0700638 av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
639 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700640
641 // All mbs should use ALTREF_FRAME
Yaowu Xuf883b422016-08-30 14:01:10 -0700642 av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
643 av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
644 av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
645 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700646
647 // Skip all MBs if high Q (0,0 mv and skip coeffs)
648 if (high_q) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700649 av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
650 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700651 }
652 // Enable data update
653 seg->update_data = 1;
654 } else {
655 // All other frames.
656
657 // No updates.. leave things as they are.
658 seg->update_map = 0;
659 seg->update_data = 0;
660 }
661 }
662}
663
Yaowu Xuf883b422016-08-30 14:01:10 -0700664static void update_reference_segmentation_map(AV1_COMP *cpi) {
665 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700666 MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
667 uint8_t *cache_ptr = cm->last_frame_seg_map;
668 int row, col;
669
670 for (row = 0; row < cm->mi_rows; row++) {
671 MODE_INFO **mi_8x8 = mi_8x8_ptr;
672 uint8_t *cache = cache_ptr;
673 for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
674 cache[0] = mi_8x8[0]->mbmi.segment_id;
675 mi_8x8_ptr += cm->mi_stride;
676 cache_ptr += cm->mi_cols;
677 }
678}
679
Yaowu Xuf883b422016-08-30 14:01:10 -0700680static void alloc_raw_frame_buffers(AV1_COMP *cpi) {
681 AV1_COMMON *cm = &cpi->common;
682 const AV1EncoderConfig *oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700683
684 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700685 cpi->lookahead = av1_lookahead_init(oxcf->width, oxcf->height,
686 cm->subsampling_x, cm->subsampling_y,
687#if CONFIG_AOM_HIGHBITDEPTH
688 cm->use_highbitdepth,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700689#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700690 oxcf->lag_in_frames);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700691 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700692 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700693 "Failed to allocate lag buffers");
694
695 // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xuf883b422016-08-30 14:01:10 -0700696 if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700697 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700698#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700699 cm->use_highbitdepth,
700#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700701 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
702 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700703 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700704 "Failed to allocate altref buffer");
705}
706
Yaowu Xuf883b422016-08-30 14:01:10 -0700707static void alloc_util_frame_buffers(AV1_COMP *cpi) {
708 AV1_COMMON *const cm = &cpi->common;
709 if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700710 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700711#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700712 cm->use_highbitdepth,
713#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700714 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
715 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700716 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700717 "Failed to allocate last frame buffer");
718
719#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700720 if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700721 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700722#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700723 cm->use_highbitdepth,
724#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700725 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
726 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700727 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700728 "Failed to allocate last frame deblocked buffer");
729#endif // CONFIG_LOOP_RESTORATION
730
Yaowu Xuf883b422016-08-30 14:01:10 -0700731 if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700732 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700733#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700734 cm->use_highbitdepth,
735#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700736 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
737 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700738 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700739 "Failed to allocate scaled source buffer");
740
Yaowu Xuf883b422016-08-30 14:01:10 -0700741 if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700742 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -0700743#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700744 cm->use_highbitdepth,
745#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700746 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
747 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700748 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700749 "Failed to allocate scaled last source buffer");
750}
751
Yaowu Xuf883b422016-08-30 14:01:10 -0700752static int alloc_context_buffers_ext(AV1_COMP *cpi) {
753 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700754 int mi_size = cm->mi_cols * cm->mi_rows;
755
Yaowu Xuf883b422016-08-30 14:01:10 -0700756 cpi->mbmi_ext_base = aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700757 if (!cpi->mbmi_ext_base) return 1;
758
759 return 0;
760}
761
Yaowu Xuf883b422016-08-30 14:01:10 -0700762void av1_alloc_compressor_data(AV1_COMP *cpi) {
763 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700764
Yaowu Xuf883b422016-08-30 14:01:10 -0700765 av1_alloc_context_buffers(cm, cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700766
767 alloc_context_buffers_ext(cpi);
768
Yaowu Xuf883b422016-08-30 14:01:10 -0700769 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700770
771 {
772 unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
773 CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700774 aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700775#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -0700776 aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, tokens);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700777#endif // CONFIG_ANS
778 }
779
Yaowu Xuf883b422016-08-30 14:01:10 -0700780 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700781}
782
Yaowu Xuf883b422016-08-30 14:01:10 -0700783void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700784 cpi->framerate = framerate < 0.1 ? 30 : framerate;
Yaowu Xuf883b422016-08-30 14:01:10 -0700785 av1_rc_update_framerate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700786}
787
Yaowu Xuf883b422016-08-30 14:01:10 -0700788static void set_tile_info(AV1_COMP *cpi) {
789 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700790
791#if CONFIG_EXT_TILE
792#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700793 if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700794 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
795 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
796 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
797 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
798 } else {
799 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
800 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
801 cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
802 cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
803 }
804#else
805 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
806 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
807 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
808 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
809#endif // CONFIG_EXT_PARTITION
810
Yaowu Xuf883b422016-08-30 14:01:10 -0700811 cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
812 cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813
814 assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
815 assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
816
817 // Get the number of tiles
818 cm->tile_cols = 1;
819 while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
820
821 cm->tile_rows = 1;
822 while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
823#else
824 int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xuf883b422016-08-30 14:01:10 -0700825 av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700826
827 cm->log2_tile_cols =
828 clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
829 cm->log2_tile_rows = cpi->oxcf.tile_rows;
830
831 cm->tile_cols = 1 << cm->log2_tile_cols;
832 cm->tile_rows = 1 << cm->log2_tile_rows;
833
834 cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
835 cm->tile_width >>= cm->log2_tile_cols;
836 cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
837 cm->tile_height >>= cm->log2_tile_rows;
838
839 // round to integer multiples of max superblock size
840 cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
841 cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
842#endif // CONFIG_EXT_TILE
843}
844
Yaowu Xuf883b422016-08-30 14:01:10 -0700845static void update_frame_size(AV1_COMP *cpi) {
846 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700847 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
848
Yaowu Xuf883b422016-08-30 14:01:10 -0700849 av1_set_mb_mi(cm, cm->width, cm->height);
850 av1_init_context_buffers(cm);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700851 av1_init_macroblockd(cm, xd,
852#if CONFIG_PVQ
853 NULL,
854#endif
855 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700856 memset(cpi->mbmi_ext_base, 0,
857 cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
858
859 set_tile_info(cpi);
860}
861
Yaowu Xuf883b422016-08-30 14:01:10 -0700862static void init_buffer_indices(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700863#if CONFIG_EXT_REFS
864 int fb_idx;
865 for (fb_idx = 0; fb_idx < LAST_REF_FRAMES; ++fb_idx)
866 cpi->lst_fb_idxes[fb_idx] = fb_idx;
867 cpi->gld_fb_idx = LAST_REF_FRAMES;
868 cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
869 cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
870 for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
871 cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
872#else
873 cpi->lst_fb_idx = 0;
874 cpi->gld_fb_idx = 1;
875 cpi->alt_fb_idx = 2;
876#endif // CONFIG_EXT_REFS
877}
878
Yaowu Xuf883b422016-08-30 14:01:10 -0700879static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
880 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700881
882 cpi->oxcf = *oxcf;
883 cpi->framerate = oxcf->init_framerate;
884
885 cm->profile = oxcf->profile;
886 cm->bit_depth = oxcf->bit_depth;
Yaowu Xuf883b422016-08-30 14:01:10 -0700887#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700888 cm->use_highbitdepth = oxcf->use_highbitdepth;
889#endif
890 cm->color_space = oxcf->color_space;
891 cm->color_range = oxcf->color_range;
892
893 cm->width = oxcf->width;
894 cm->height = oxcf->height;
Yaowu Xuf883b422016-08-30 14:01:10 -0700895 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700896
897 // Single thread case: use counts in common.
898 cpi->td.counts = &cm->counts;
899
900 // change includes all joint functionality
Yaowu Xuf883b422016-08-30 14:01:10 -0700901 av1_change_config(cpi, oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700902
903 cpi->static_mb_pct = 0;
904 cpi->ref_frame_flags = 0;
905
906 init_buffer_indices(cpi);
907}
908
909static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xuf883b422016-08-30 14:01:10 -0700910 const AV1EncoderConfig *oxcf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700911 const int64_t bandwidth = oxcf->target_bandwidth;
912 const int64_t starting = oxcf->starting_buffer_level_ms;
913 const int64_t optimal = oxcf->optimal_buffer_level_ms;
914 const int64_t maximum = oxcf->maximum_buffer_size_ms;
915
916 rc->starting_buffer_level = starting * bandwidth / 1000;
917 rc->optimal_buffer_level =
918 (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
919 rc->maximum_buffer_size =
920 (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
921}
922
Yaowu Xuf883b422016-08-30 14:01:10 -0700923#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700924#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
925 cpi->fn_ptr[BT].sdf = SDF; \
926 cpi->fn_ptr[BT].sdaf = SDAF; \
927 cpi->fn_ptr[BT].vf = VF; \
928 cpi->fn_ptr[BT].svf = SVF; \
929 cpi->fn_ptr[BT].svaf = SVAF; \
930 cpi->fn_ptr[BT].sdx3f = SDX3F; \
931 cpi->fn_ptr[BT].sdx8f = SDX8F; \
932 cpi->fn_ptr[BT].sdx4df = SDX4DF;
933
934#define MAKE_BFP_SAD_WRAPPER(fnname) \
935 static unsigned int fnname##_bits8(const uint8_t *src_ptr, \
936 int source_stride, \
937 const uint8_t *ref_ptr, int ref_stride) { \
938 return fnname(src_ptr, source_stride, ref_ptr, ref_stride); \
939 } \
940 static unsigned int fnname##_bits10( \
941 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
942 int ref_stride) { \
943 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2; \
944 } \
945 static unsigned int fnname##_bits12( \
946 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
947 int ref_stride) { \
948 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4; \
949 }
950
951#define MAKE_BFP_SADAVG_WRAPPER(fnname) \
952 static unsigned int fnname##_bits8( \
953 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
954 int ref_stride, const uint8_t *second_pred) { \
955 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred); \
956 } \
957 static unsigned int fnname##_bits10( \
958 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
959 int ref_stride, const uint8_t *second_pred) { \
960 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
961 2; \
962 } \
963 static unsigned int fnname##_bits12( \
964 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
965 int ref_stride, const uint8_t *second_pred) { \
966 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
967 4; \
968 }
969
970#define MAKE_BFP_SAD3_WRAPPER(fnname) \
971 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
972 const uint8_t *ref_ptr, int ref_stride, \
973 unsigned int *sad_array) { \
974 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
975 } \
976 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
977 const uint8_t *ref_ptr, int ref_stride, \
978 unsigned int *sad_array) { \
979 int i; \
980 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
981 for (i = 0; i < 3; i++) sad_array[i] >>= 2; \
982 } \
983 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
984 const uint8_t *ref_ptr, int ref_stride, \
985 unsigned int *sad_array) { \
986 int i; \
987 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
988 for (i = 0; i < 3; i++) sad_array[i] >>= 4; \
989 }
990
991#define MAKE_BFP_SAD8_WRAPPER(fnname) \
992 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
993 const uint8_t *ref_ptr, int ref_stride, \
994 unsigned int *sad_array) { \
995 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
996 } \
997 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
998 const uint8_t *ref_ptr, int ref_stride, \
999 unsigned int *sad_array) { \
1000 int i; \
1001 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1002 for (i = 0; i < 8; i++) sad_array[i] >>= 2; \
1003 } \
1004 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1005 const uint8_t *ref_ptr, int ref_stride, \
1006 unsigned int *sad_array) { \
1007 int i; \
1008 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1009 for (i = 0; i < 8; i++) sad_array[i] >>= 4; \
1010 }
1011#define MAKE_BFP_SAD4D_WRAPPER(fnname) \
1012 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1013 const uint8_t *const ref_ptr[], int ref_stride, \
1014 unsigned int *sad_array) { \
1015 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1016 } \
1017 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1018 const uint8_t *const ref_ptr[], int ref_stride, \
1019 unsigned int *sad_array) { \
1020 int i; \
1021 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1022 for (i = 0; i < 4; i++) sad_array[i] >>= 2; \
1023 } \
1024 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1025 const uint8_t *const ref_ptr[], int ref_stride, \
1026 unsigned int *sad_array) { \
1027 int i; \
1028 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1029 for (i = 0; i < 4; i++) sad_array[i] >>= 4; \
1030 }
1031
1032#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001033MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x128)
1034MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x128_avg)
1035MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad128x128x3)
1036MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad128x128x8)
1037MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x128x4d)
1038MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x64)
1039MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x64_avg)
1040MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x64x4d)
1041MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x128)
1042MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x128_avg)
1043MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001044#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001045MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x16)
1046MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x16_avg)
1047MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x16x4d)
1048MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x32)
1049MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x32_avg)
1050MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x32x4d)
1051MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x32)
1052MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x32_avg)
1053MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x32x4d)
1054MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x64)
1055MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x64_avg)
1056MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x64x4d)
1057MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x32)
1058MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x32_avg)
1059MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad32x32x3)
1060MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad32x32x8)
1061MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x32x4d)
1062MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x64)
1063MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x64_avg)
1064MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad64x64x3)
1065MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad64x64x8)
1066MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x64x4d)
1067MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x16)
1068MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x16_avg)
1069MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x16x3)
1070MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x16x8)
1071MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x16x4d)
1072MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x8)
1073MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x8_avg)
1074MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x8x3)
1075MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x8x8)
1076MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x8x4d)
1077MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x16)
1078MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x16_avg)
1079MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x16x3)
1080MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x16x8)
1081MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x16x4d)
1082MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x8)
1083MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x8_avg)
1084MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x8x3)
1085MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x8x8)
1086MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x8x4d)
1087MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x4)
1088MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x4_avg)
1089MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x4x8)
1090MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x4x4d)
1091MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x8)
1092MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x8_avg)
1093MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x8x8)
1094MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x8x4d)
1095MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x4)
1096MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x4_avg)
1097MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad4x4x3)
1098MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x4x8)
1099MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001100
1101#if CONFIG_EXT_INTER
1102#define HIGHBD_MBFP(BT, MSDF, MVF, MSVF) \
1103 cpi->fn_ptr[BT].msdf = MSDF; \
1104 cpi->fn_ptr[BT].mvf = MVF; \
1105 cpi->fn_ptr[BT].msvf = MSVF;
1106
1107#define MAKE_MBFP_SAD_WRAPPER(fnname) \
1108 static unsigned int fnname##_bits8( \
1109 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1110 int ref_stride, const uint8_t *m, int m_stride) { \
1111 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride); \
1112 } \
1113 static unsigned int fnname##_bits10( \
1114 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1115 int ref_stride, const uint8_t *m, int m_stride) { \
1116 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride) >> \
1117 2; \
1118 } \
1119 static unsigned int fnname##_bits12( \
1120 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1121 int ref_stride, const uint8_t *m, int m_stride) { \
1122 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, m, m_stride) >> \
1123 4; \
1124 }
1125
1126#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001127MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad128x128)
1128MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad128x64)
1129MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001130#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001131MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x64)
1132MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad64x32)
1133MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x64)
1134MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x32)
1135MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad32x16)
1136MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x32)
1137MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x16)
1138MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad16x8)
1139MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x16)
1140MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x8)
1141MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad8x4)
1142MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad4x8)
1143MAKE_MBFP_SAD_WRAPPER(aom_highbd_masked_sad4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001144#endif // CONFIG_EXT_INTER
1145
Yue Chencb60b182016-10-13 15:18:22 -07001146#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001147#define HIGHBD_OBFP(BT, OSDF, OVF, OSVF) \
1148 cpi->fn_ptr[BT].osdf = OSDF; \
1149 cpi->fn_ptr[BT].ovf = OVF; \
1150 cpi->fn_ptr[BT].osvf = OSVF;
1151
1152#define MAKE_OBFP_SAD_WRAPPER(fnname) \
1153 static unsigned int fnname##_bits8(const uint8_t *ref, int ref_stride, \
1154 const int32_t *wsrc, \
1155 const int32_t *msk) { \
1156 return fnname(ref, ref_stride, wsrc, msk); \
1157 } \
1158 static unsigned int fnname##_bits10(const uint8_t *ref, int ref_stride, \
1159 const int32_t *wsrc, \
1160 const int32_t *msk) { \
1161 return fnname(ref, ref_stride, wsrc, msk) >> 2; \
1162 } \
1163 static unsigned int fnname##_bits12(const uint8_t *ref, int ref_stride, \
1164 const int32_t *wsrc, \
1165 const int32_t *msk) { \
1166 return fnname(ref, ref_stride, wsrc, msk) >> 4; \
1167 }
1168
1169#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001170MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x128)
1171MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x64)
1172MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001173#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001174MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x64)
1175MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x32)
1176MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x64)
1177MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x32)
1178MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x16)
1179MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x32)
1180MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x16)
1181MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x8)
1182MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x16)
1183MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x8)
1184MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x4)
1185MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x8)
1186MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001187#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001188
Yaowu Xuf883b422016-08-30 14:01:10 -07001189static void highbd_set_var_fns(AV1_COMP *const cpi) {
1190 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001191 if (cm->use_highbitdepth) {
1192 switch (cm->bit_depth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001193 case AOM_BITS_8:
1194 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits8,
1195 aom_highbd_sad32x16_avg_bits8, aom_highbd_8_variance32x16,
1196 aom_highbd_8_sub_pixel_variance32x16,
1197 aom_highbd_8_sub_pixel_avg_variance32x16, NULL, NULL,
1198 aom_highbd_sad32x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001199
Yaowu Xuf883b422016-08-30 14:01:10 -07001200 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits8,
1201 aom_highbd_sad16x32_avg_bits8, aom_highbd_8_variance16x32,
1202 aom_highbd_8_sub_pixel_variance16x32,
1203 aom_highbd_8_sub_pixel_avg_variance16x32, NULL, NULL,
1204 aom_highbd_sad16x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001205
Yaowu Xuf883b422016-08-30 14:01:10 -07001206 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits8,
1207 aom_highbd_sad64x32_avg_bits8, aom_highbd_8_variance64x32,
1208 aom_highbd_8_sub_pixel_variance64x32,
1209 aom_highbd_8_sub_pixel_avg_variance64x32, NULL, NULL,
1210 aom_highbd_sad64x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001211
Yaowu Xuf883b422016-08-30 14:01:10 -07001212 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits8,
1213 aom_highbd_sad32x64_avg_bits8, aom_highbd_8_variance32x64,
1214 aom_highbd_8_sub_pixel_variance32x64,
1215 aom_highbd_8_sub_pixel_avg_variance32x64, NULL, NULL,
1216 aom_highbd_sad32x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001217
Yaowu Xuf883b422016-08-30 14:01:10 -07001218 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits8,
1219 aom_highbd_sad32x32_avg_bits8, aom_highbd_8_variance32x32,
1220 aom_highbd_8_sub_pixel_variance32x32,
1221 aom_highbd_8_sub_pixel_avg_variance32x32,
1222 aom_highbd_sad32x32x3_bits8, aom_highbd_sad32x32x8_bits8,
1223 aom_highbd_sad32x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224
Yaowu Xuf883b422016-08-30 14:01:10 -07001225 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits8,
1226 aom_highbd_sad64x64_avg_bits8, aom_highbd_8_variance64x64,
1227 aom_highbd_8_sub_pixel_variance64x64,
1228 aom_highbd_8_sub_pixel_avg_variance64x64,
1229 aom_highbd_sad64x64x3_bits8, aom_highbd_sad64x64x8_bits8,
1230 aom_highbd_sad64x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001231
Yaowu Xuf883b422016-08-30 14:01:10 -07001232 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits8,
1233 aom_highbd_sad16x16_avg_bits8, aom_highbd_8_variance16x16,
1234 aom_highbd_8_sub_pixel_variance16x16,
1235 aom_highbd_8_sub_pixel_avg_variance16x16,
1236 aom_highbd_sad16x16x3_bits8, aom_highbd_sad16x16x8_bits8,
1237 aom_highbd_sad16x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001238
1239 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001240 BLOCK_16X8, aom_highbd_sad16x8_bits8, aom_highbd_sad16x8_avg_bits8,
1241 aom_highbd_8_variance16x8, aom_highbd_8_sub_pixel_variance16x8,
1242 aom_highbd_8_sub_pixel_avg_variance16x8, aom_highbd_sad16x8x3_bits8,
1243 aom_highbd_sad16x8x8_bits8, aom_highbd_sad16x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001244
1245 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001246 BLOCK_8X16, aom_highbd_sad8x16_bits8, aom_highbd_sad8x16_avg_bits8,
1247 aom_highbd_8_variance8x16, aom_highbd_8_sub_pixel_variance8x16,
1248 aom_highbd_8_sub_pixel_avg_variance8x16, aom_highbd_sad8x16x3_bits8,
1249 aom_highbd_sad8x16x8_bits8, aom_highbd_sad8x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001250
1251 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001252 BLOCK_8X8, aom_highbd_sad8x8_bits8, aom_highbd_sad8x8_avg_bits8,
1253 aom_highbd_8_variance8x8, aom_highbd_8_sub_pixel_variance8x8,
1254 aom_highbd_8_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits8,
1255 aom_highbd_sad8x8x8_bits8, aom_highbd_sad8x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001256
Yaowu Xuf883b422016-08-30 14:01:10 -07001257 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits8,
1258 aom_highbd_sad8x4_avg_bits8, aom_highbd_8_variance8x4,
1259 aom_highbd_8_sub_pixel_variance8x4,
1260 aom_highbd_8_sub_pixel_avg_variance8x4, NULL,
1261 aom_highbd_sad8x4x8_bits8, aom_highbd_sad8x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001262
Yaowu Xuf883b422016-08-30 14:01:10 -07001263 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits8,
1264 aom_highbd_sad4x8_avg_bits8, aom_highbd_8_variance4x8,
1265 aom_highbd_8_sub_pixel_variance4x8,
1266 aom_highbd_8_sub_pixel_avg_variance4x8, NULL,
1267 aom_highbd_sad4x8x8_bits8, aom_highbd_sad4x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001268
1269 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001270 BLOCK_4X4, aom_highbd_sad4x4_bits8, aom_highbd_sad4x4_avg_bits8,
1271 aom_highbd_8_variance4x4, aom_highbd_8_sub_pixel_variance4x4,
1272 aom_highbd_8_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits8,
1273 aom_highbd_sad4x4x8_bits8, aom_highbd_sad4x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001274
1275#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001276 HIGHBD_BFP(BLOCK_128X128, aom_highbd_sad128x128_bits8,
1277 aom_highbd_sad128x128_avg_bits8,
1278 aom_highbd_8_variance128x128,
1279 aom_highbd_8_sub_pixel_variance128x128,
1280 aom_highbd_8_sub_pixel_avg_variance128x128,
1281 aom_highbd_sad128x128x3_bits8, aom_highbd_sad128x128x8_bits8,
1282 aom_highbd_sad128x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001283
Yaowu Xuf883b422016-08-30 14:01:10 -07001284 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits8,
1285 aom_highbd_sad128x64_avg_bits8, aom_highbd_8_variance128x64,
1286 aom_highbd_8_sub_pixel_variance128x64,
1287 aom_highbd_8_sub_pixel_avg_variance128x64, NULL, NULL,
1288 aom_highbd_sad128x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001289
Yaowu Xuf883b422016-08-30 14:01:10 -07001290 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits8,
1291 aom_highbd_sad64x128_avg_bits8, aom_highbd_8_variance64x128,
1292 aom_highbd_8_sub_pixel_variance64x128,
1293 aom_highbd_8_sub_pixel_avg_variance64x128, NULL, NULL,
1294 aom_highbd_sad64x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001295#endif // CONFIG_EXT_PARTITION
1296
1297#if CONFIG_EXT_INTER
1298#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001299 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits8,
1300 aom_highbd_masked_variance128x128,
1301 aom_highbd_masked_sub_pixel_variance128x128)
1302 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits8,
1303 aom_highbd_masked_variance128x64,
1304 aom_highbd_masked_sub_pixel_variance128x64)
1305 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits8,
1306 aom_highbd_masked_variance64x128,
1307 aom_highbd_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001308#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001309 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits8,
1310 aom_highbd_masked_variance64x64,
1311 aom_highbd_masked_sub_pixel_variance64x64)
1312 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits8,
1313 aom_highbd_masked_variance64x32,
1314 aom_highbd_masked_sub_pixel_variance64x32)
1315 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits8,
1316 aom_highbd_masked_variance32x64,
1317 aom_highbd_masked_sub_pixel_variance32x64)
1318 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits8,
1319 aom_highbd_masked_variance32x32,
1320 aom_highbd_masked_sub_pixel_variance32x32)
1321 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits8,
1322 aom_highbd_masked_variance32x16,
1323 aom_highbd_masked_sub_pixel_variance32x16)
1324 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits8,
1325 aom_highbd_masked_variance16x32,
1326 aom_highbd_masked_sub_pixel_variance16x32)
1327 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits8,
1328 aom_highbd_masked_variance16x16,
1329 aom_highbd_masked_sub_pixel_variance16x16)
1330 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits8,
1331 aom_highbd_masked_variance8x16,
1332 aom_highbd_masked_sub_pixel_variance8x16)
1333 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits8,
1334 aom_highbd_masked_variance16x8,
1335 aom_highbd_masked_sub_pixel_variance16x8)
1336 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits8,
1337 aom_highbd_masked_variance8x8,
1338 aom_highbd_masked_sub_pixel_variance8x8)
1339 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits8,
1340 aom_highbd_masked_variance4x8,
1341 aom_highbd_masked_sub_pixel_variance4x8)
1342 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits8,
1343 aom_highbd_masked_variance8x4,
1344 aom_highbd_masked_sub_pixel_variance8x4)
1345 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits8,
1346 aom_highbd_masked_variance4x4,
1347 aom_highbd_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001348#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001349#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001350#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001351 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits8,
1352 aom_highbd_obmc_variance128x128,
1353 aom_highbd_obmc_sub_pixel_variance128x128)
1354 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits8,
1355 aom_highbd_obmc_variance128x64,
1356 aom_highbd_obmc_sub_pixel_variance128x64)
1357 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits8,
1358 aom_highbd_obmc_variance64x128,
1359 aom_highbd_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001360#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001361 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits8,
1362 aom_highbd_obmc_variance64x64,
1363 aom_highbd_obmc_sub_pixel_variance64x64)
1364 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits8,
1365 aom_highbd_obmc_variance64x32,
1366 aom_highbd_obmc_sub_pixel_variance64x32)
1367 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits8,
1368 aom_highbd_obmc_variance32x64,
1369 aom_highbd_obmc_sub_pixel_variance32x64)
1370 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits8,
1371 aom_highbd_obmc_variance32x32,
1372 aom_highbd_obmc_sub_pixel_variance32x32)
1373 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits8,
1374 aom_highbd_obmc_variance32x16,
1375 aom_highbd_obmc_sub_pixel_variance32x16)
1376 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits8,
1377 aom_highbd_obmc_variance16x32,
1378 aom_highbd_obmc_sub_pixel_variance16x32)
1379 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits8,
1380 aom_highbd_obmc_variance16x16,
1381 aom_highbd_obmc_sub_pixel_variance16x16)
1382 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits8,
1383 aom_highbd_obmc_variance8x16,
1384 aom_highbd_obmc_sub_pixel_variance8x16)
1385 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits8,
1386 aom_highbd_obmc_variance16x8,
1387 aom_highbd_obmc_sub_pixel_variance16x8)
1388 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits8,
1389 aom_highbd_obmc_variance8x8,
1390 aom_highbd_obmc_sub_pixel_variance8x8)
1391 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits8,
1392 aom_highbd_obmc_variance4x8,
1393 aom_highbd_obmc_sub_pixel_variance4x8)
1394 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits8,
1395 aom_highbd_obmc_variance8x4,
1396 aom_highbd_obmc_sub_pixel_variance8x4)
1397 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits8,
1398 aom_highbd_obmc_variance4x4,
1399 aom_highbd_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001400#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001401 break;
1402
Yaowu Xuf883b422016-08-30 14:01:10 -07001403 case AOM_BITS_10:
1404 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits10,
1405 aom_highbd_sad32x16_avg_bits10, aom_highbd_10_variance32x16,
1406 aom_highbd_10_sub_pixel_variance32x16,
1407 aom_highbd_10_sub_pixel_avg_variance32x16, NULL, NULL,
1408 aom_highbd_sad32x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001409
Yaowu Xuf883b422016-08-30 14:01:10 -07001410 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits10,
1411 aom_highbd_sad16x32_avg_bits10, aom_highbd_10_variance16x32,
1412 aom_highbd_10_sub_pixel_variance16x32,
1413 aom_highbd_10_sub_pixel_avg_variance16x32, NULL, NULL,
1414 aom_highbd_sad16x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001415
Yaowu Xuf883b422016-08-30 14:01:10 -07001416 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits10,
1417 aom_highbd_sad64x32_avg_bits10, aom_highbd_10_variance64x32,
1418 aom_highbd_10_sub_pixel_variance64x32,
1419 aom_highbd_10_sub_pixel_avg_variance64x32, NULL, NULL,
1420 aom_highbd_sad64x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001421
Yaowu Xuf883b422016-08-30 14:01:10 -07001422 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits10,
1423 aom_highbd_sad32x64_avg_bits10, aom_highbd_10_variance32x64,
1424 aom_highbd_10_sub_pixel_variance32x64,
1425 aom_highbd_10_sub_pixel_avg_variance32x64, NULL, NULL,
1426 aom_highbd_sad32x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001427
Yaowu Xuf883b422016-08-30 14:01:10 -07001428 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits10,
1429 aom_highbd_sad32x32_avg_bits10, aom_highbd_10_variance32x32,
1430 aom_highbd_10_sub_pixel_variance32x32,
1431 aom_highbd_10_sub_pixel_avg_variance32x32,
1432 aom_highbd_sad32x32x3_bits10, aom_highbd_sad32x32x8_bits10,
1433 aom_highbd_sad32x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001434
Yaowu Xuf883b422016-08-30 14:01:10 -07001435 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits10,
1436 aom_highbd_sad64x64_avg_bits10, aom_highbd_10_variance64x64,
1437 aom_highbd_10_sub_pixel_variance64x64,
1438 aom_highbd_10_sub_pixel_avg_variance64x64,
1439 aom_highbd_sad64x64x3_bits10, aom_highbd_sad64x64x8_bits10,
1440 aom_highbd_sad64x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001441
Yaowu Xuf883b422016-08-30 14:01:10 -07001442 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits10,
1443 aom_highbd_sad16x16_avg_bits10, aom_highbd_10_variance16x16,
1444 aom_highbd_10_sub_pixel_variance16x16,
1445 aom_highbd_10_sub_pixel_avg_variance16x16,
1446 aom_highbd_sad16x16x3_bits10, aom_highbd_sad16x16x8_bits10,
1447 aom_highbd_sad16x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001448
Yaowu Xuf883b422016-08-30 14:01:10 -07001449 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits10,
1450 aom_highbd_sad16x8_avg_bits10, aom_highbd_10_variance16x8,
1451 aom_highbd_10_sub_pixel_variance16x8,
1452 aom_highbd_10_sub_pixel_avg_variance16x8,
1453 aom_highbd_sad16x8x3_bits10, aom_highbd_sad16x8x8_bits10,
1454 aom_highbd_sad16x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001455
Yaowu Xuf883b422016-08-30 14:01:10 -07001456 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits10,
1457 aom_highbd_sad8x16_avg_bits10, aom_highbd_10_variance8x16,
1458 aom_highbd_10_sub_pixel_variance8x16,
1459 aom_highbd_10_sub_pixel_avg_variance8x16,
1460 aom_highbd_sad8x16x3_bits10, aom_highbd_sad8x16x8_bits10,
1461 aom_highbd_sad8x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001462
1463 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001464 BLOCK_8X8, aom_highbd_sad8x8_bits10, aom_highbd_sad8x8_avg_bits10,
1465 aom_highbd_10_variance8x8, aom_highbd_10_sub_pixel_variance8x8,
1466 aom_highbd_10_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits10,
1467 aom_highbd_sad8x8x8_bits10, aom_highbd_sad8x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001468
Yaowu Xuf883b422016-08-30 14:01:10 -07001469 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits10,
1470 aom_highbd_sad8x4_avg_bits10, aom_highbd_10_variance8x4,
1471 aom_highbd_10_sub_pixel_variance8x4,
1472 aom_highbd_10_sub_pixel_avg_variance8x4, NULL,
1473 aom_highbd_sad8x4x8_bits10, aom_highbd_sad8x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001474
Yaowu Xuf883b422016-08-30 14:01:10 -07001475 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits10,
1476 aom_highbd_sad4x8_avg_bits10, aom_highbd_10_variance4x8,
1477 aom_highbd_10_sub_pixel_variance4x8,
1478 aom_highbd_10_sub_pixel_avg_variance4x8, NULL,
1479 aom_highbd_sad4x8x8_bits10, aom_highbd_sad4x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001480
1481 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001482 BLOCK_4X4, aom_highbd_sad4x4_bits10, aom_highbd_sad4x4_avg_bits10,
1483 aom_highbd_10_variance4x4, aom_highbd_10_sub_pixel_variance4x4,
1484 aom_highbd_10_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits10,
1485 aom_highbd_sad4x4x8_bits10, aom_highbd_sad4x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001486
1487#if CONFIG_EXT_PARTITION
1488 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001489 BLOCK_128X128, aom_highbd_sad128x128_bits10,
1490 aom_highbd_sad128x128_avg_bits10, aom_highbd_10_variance128x128,
1491 aom_highbd_10_sub_pixel_variance128x128,
1492 aom_highbd_10_sub_pixel_avg_variance128x128,
1493 aom_highbd_sad128x128x3_bits10, aom_highbd_sad128x128x8_bits10,
1494 aom_highbd_sad128x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001495
Yaowu Xuf883b422016-08-30 14:01:10 -07001496 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits10,
1497 aom_highbd_sad128x64_avg_bits10,
1498 aom_highbd_10_variance128x64,
1499 aom_highbd_10_sub_pixel_variance128x64,
1500 aom_highbd_10_sub_pixel_avg_variance128x64, NULL, NULL,
1501 aom_highbd_sad128x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001502
Yaowu Xuf883b422016-08-30 14:01:10 -07001503 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits10,
1504 aom_highbd_sad64x128_avg_bits10,
1505 aom_highbd_10_variance64x128,
1506 aom_highbd_10_sub_pixel_variance64x128,
1507 aom_highbd_10_sub_pixel_avg_variance64x128, NULL, NULL,
1508 aom_highbd_sad64x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001509#endif // CONFIG_EXT_PARTITION
1510
1511#if CONFIG_EXT_INTER
1512#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001513 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits10,
1514 aom_highbd_10_masked_variance128x128,
1515 aom_highbd_10_masked_sub_pixel_variance128x128)
1516 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits10,
1517 aom_highbd_10_masked_variance128x64,
1518 aom_highbd_10_masked_sub_pixel_variance128x64)
1519 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits10,
1520 aom_highbd_10_masked_variance64x128,
1521 aom_highbd_10_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001522#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001523 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits10,
1524 aom_highbd_10_masked_variance64x64,
1525 aom_highbd_10_masked_sub_pixel_variance64x64)
1526 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits10,
1527 aom_highbd_10_masked_variance64x32,
1528 aom_highbd_10_masked_sub_pixel_variance64x32)
1529 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits10,
1530 aom_highbd_10_masked_variance32x64,
1531 aom_highbd_10_masked_sub_pixel_variance32x64)
1532 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits10,
1533 aom_highbd_10_masked_variance32x32,
1534 aom_highbd_10_masked_sub_pixel_variance32x32)
1535 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits10,
1536 aom_highbd_10_masked_variance32x16,
1537 aom_highbd_10_masked_sub_pixel_variance32x16)
1538 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits10,
1539 aom_highbd_10_masked_variance16x32,
1540 aom_highbd_10_masked_sub_pixel_variance16x32)
1541 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits10,
1542 aom_highbd_10_masked_variance16x16,
1543 aom_highbd_10_masked_sub_pixel_variance16x16)
1544 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits10,
1545 aom_highbd_10_masked_variance8x16,
1546 aom_highbd_10_masked_sub_pixel_variance8x16)
1547 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits10,
1548 aom_highbd_10_masked_variance16x8,
1549 aom_highbd_10_masked_sub_pixel_variance16x8)
1550 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits10,
1551 aom_highbd_10_masked_variance8x8,
1552 aom_highbd_10_masked_sub_pixel_variance8x8)
1553 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits10,
1554 aom_highbd_10_masked_variance4x8,
1555 aom_highbd_10_masked_sub_pixel_variance4x8)
1556 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits10,
1557 aom_highbd_10_masked_variance8x4,
1558 aom_highbd_10_masked_sub_pixel_variance8x4)
1559 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits10,
1560 aom_highbd_10_masked_variance4x4,
1561 aom_highbd_10_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001562#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001563#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001564#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001565 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits10,
1566 aom_highbd_10_obmc_variance128x128,
1567 aom_highbd_10_obmc_sub_pixel_variance128x128)
1568 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits10,
1569 aom_highbd_10_obmc_variance128x64,
1570 aom_highbd_10_obmc_sub_pixel_variance128x64)
1571 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits10,
1572 aom_highbd_10_obmc_variance64x128,
1573 aom_highbd_10_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001574#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001575 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits10,
1576 aom_highbd_10_obmc_variance64x64,
1577 aom_highbd_10_obmc_sub_pixel_variance64x64)
1578 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits10,
1579 aom_highbd_10_obmc_variance64x32,
1580 aom_highbd_10_obmc_sub_pixel_variance64x32)
1581 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits10,
1582 aom_highbd_10_obmc_variance32x64,
1583 aom_highbd_10_obmc_sub_pixel_variance32x64)
1584 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits10,
1585 aom_highbd_10_obmc_variance32x32,
1586 aom_highbd_10_obmc_sub_pixel_variance32x32)
1587 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits10,
1588 aom_highbd_10_obmc_variance32x16,
1589 aom_highbd_10_obmc_sub_pixel_variance32x16)
1590 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits10,
1591 aom_highbd_10_obmc_variance16x32,
1592 aom_highbd_10_obmc_sub_pixel_variance16x32)
1593 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits10,
1594 aom_highbd_10_obmc_variance16x16,
1595 aom_highbd_10_obmc_sub_pixel_variance16x16)
1596 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits10,
1597 aom_highbd_10_obmc_variance8x16,
1598 aom_highbd_10_obmc_sub_pixel_variance8x16)
1599 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits10,
1600 aom_highbd_10_obmc_variance16x8,
1601 aom_highbd_10_obmc_sub_pixel_variance16x8)
1602 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits10,
1603 aom_highbd_10_obmc_variance8x8,
1604 aom_highbd_10_obmc_sub_pixel_variance8x8)
1605 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits10,
1606 aom_highbd_10_obmc_variance4x8,
1607 aom_highbd_10_obmc_sub_pixel_variance4x8)
1608 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits10,
1609 aom_highbd_10_obmc_variance8x4,
1610 aom_highbd_10_obmc_sub_pixel_variance8x4)
1611 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits10,
1612 aom_highbd_10_obmc_variance4x4,
1613 aom_highbd_10_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001614#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001615 break;
1616
Yaowu Xuf883b422016-08-30 14:01:10 -07001617 case AOM_BITS_12:
1618 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits12,
1619 aom_highbd_sad32x16_avg_bits12, aom_highbd_12_variance32x16,
1620 aom_highbd_12_sub_pixel_variance32x16,
1621 aom_highbd_12_sub_pixel_avg_variance32x16, NULL, NULL,
1622 aom_highbd_sad32x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001623
Yaowu Xuf883b422016-08-30 14:01:10 -07001624 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits12,
1625 aom_highbd_sad16x32_avg_bits12, aom_highbd_12_variance16x32,
1626 aom_highbd_12_sub_pixel_variance16x32,
1627 aom_highbd_12_sub_pixel_avg_variance16x32, NULL, NULL,
1628 aom_highbd_sad16x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001629
Yaowu Xuf883b422016-08-30 14:01:10 -07001630 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits12,
1631 aom_highbd_sad64x32_avg_bits12, aom_highbd_12_variance64x32,
1632 aom_highbd_12_sub_pixel_variance64x32,
1633 aom_highbd_12_sub_pixel_avg_variance64x32, NULL, NULL,
1634 aom_highbd_sad64x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001635
Yaowu Xuf883b422016-08-30 14:01:10 -07001636 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits12,
1637 aom_highbd_sad32x64_avg_bits12, aom_highbd_12_variance32x64,
1638 aom_highbd_12_sub_pixel_variance32x64,
1639 aom_highbd_12_sub_pixel_avg_variance32x64, NULL, NULL,
1640 aom_highbd_sad32x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001641
Yaowu Xuf883b422016-08-30 14:01:10 -07001642 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits12,
1643 aom_highbd_sad32x32_avg_bits12, aom_highbd_12_variance32x32,
1644 aom_highbd_12_sub_pixel_variance32x32,
1645 aom_highbd_12_sub_pixel_avg_variance32x32,
1646 aom_highbd_sad32x32x3_bits12, aom_highbd_sad32x32x8_bits12,
1647 aom_highbd_sad32x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001648
Yaowu Xuf883b422016-08-30 14:01:10 -07001649 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits12,
1650 aom_highbd_sad64x64_avg_bits12, aom_highbd_12_variance64x64,
1651 aom_highbd_12_sub_pixel_variance64x64,
1652 aom_highbd_12_sub_pixel_avg_variance64x64,
1653 aom_highbd_sad64x64x3_bits12, aom_highbd_sad64x64x8_bits12,
1654 aom_highbd_sad64x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001655
Yaowu Xuf883b422016-08-30 14:01:10 -07001656 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits12,
1657 aom_highbd_sad16x16_avg_bits12, aom_highbd_12_variance16x16,
1658 aom_highbd_12_sub_pixel_variance16x16,
1659 aom_highbd_12_sub_pixel_avg_variance16x16,
1660 aom_highbd_sad16x16x3_bits12, aom_highbd_sad16x16x8_bits12,
1661 aom_highbd_sad16x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001662
Yaowu Xuf883b422016-08-30 14:01:10 -07001663 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits12,
1664 aom_highbd_sad16x8_avg_bits12, aom_highbd_12_variance16x8,
1665 aom_highbd_12_sub_pixel_variance16x8,
1666 aom_highbd_12_sub_pixel_avg_variance16x8,
1667 aom_highbd_sad16x8x3_bits12, aom_highbd_sad16x8x8_bits12,
1668 aom_highbd_sad16x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001669
Yaowu Xuf883b422016-08-30 14:01:10 -07001670 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits12,
1671 aom_highbd_sad8x16_avg_bits12, aom_highbd_12_variance8x16,
1672 aom_highbd_12_sub_pixel_variance8x16,
1673 aom_highbd_12_sub_pixel_avg_variance8x16,
1674 aom_highbd_sad8x16x3_bits12, aom_highbd_sad8x16x8_bits12,
1675 aom_highbd_sad8x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001676
1677 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001678 BLOCK_8X8, aom_highbd_sad8x8_bits12, aom_highbd_sad8x8_avg_bits12,
1679 aom_highbd_12_variance8x8, aom_highbd_12_sub_pixel_variance8x8,
1680 aom_highbd_12_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits12,
1681 aom_highbd_sad8x8x8_bits12, aom_highbd_sad8x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001682
Yaowu Xuf883b422016-08-30 14:01:10 -07001683 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits12,
1684 aom_highbd_sad8x4_avg_bits12, aom_highbd_12_variance8x4,
1685 aom_highbd_12_sub_pixel_variance8x4,
1686 aom_highbd_12_sub_pixel_avg_variance8x4, NULL,
1687 aom_highbd_sad8x4x8_bits12, aom_highbd_sad8x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001688
Yaowu Xuf883b422016-08-30 14:01:10 -07001689 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits12,
1690 aom_highbd_sad4x8_avg_bits12, aom_highbd_12_variance4x8,
1691 aom_highbd_12_sub_pixel_variance4x8,
1692 aom_highbd_12_sub_pixel_avg_variance4x8, NULL,
1693 aom_highbd_sad4x8x8_bits12, aom_highbd_sad4x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001694
1695 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001696 BLOCK_4X4, aom_highbd_sad4x4_bits12, aom_highbd_sad4x4_avg_bits12,
1697 aom_highbd_12_variance4x4, aom_highbd_12_sub_pixel_variance4x4,
1698 aom_highbd_12_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits12,
1699 aom_highbd_sad4x4x8_bits12, aom_highbd_sad4x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001700
1701#if CONFIG_EXT_PARTITION
1702 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001703 BLOCK_128X128, aom_highbd_sad128x128_bits12,
1704 aom_highbd_sad128x128_avg_bits12, aom_highbd_12_variance128x128,
1705 aom_highbd_12_sub_pixel_variance128x128,
1706 aom_highbd_12_sub_pixel_avg_variance128x128,
1707 aom_highbd_sad128x128x3_bits12, aom_highbd_sad128x128x8_bits12,
1708 aom_highbd_sad128x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001709
Yaowu Xuf883b422016-08-30 14:01:10 -07001710 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits12,
1711 aom_highbd_sad128x64_avg_bits12,
1712 aom_highbd_12_variance128x64,
1713 aom_highbd_12_sub_pixel_variance128x64,
1714 aom_highbd_12_sub_pixel_avg_variance128x64, NULL, NULL,
1715 aom_highbd_sad128x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001716
Yaowu Xuf883b422016-08-30 14:01:10 -07001717 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits12,
1718 aom_highbd_sad64x128_avg_bits12,
1719 aom_highbd_12_variance64x128,
1720 aom_highbd_12_sub_pixel_variance64x128,
1721 aom_highbd_12_sub_pixel_avg_variance64x128, NULL, NULL,
1722 aom_highbd_sad64x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001723#endif // CONFIG_EXT_PARTITION
1724
1725#if CONFIG_EXT_INTER
1726#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001727 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits12,
1728 aom_highbd_12_masked_variance128x128,
1729 aom_highbd_12_masked_sub_pixel_variance128x128)
1730 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits12,
1731 aom_highbd_12_masked_variance128x64,
1732 aom_highbd_12_masked_sub_pixel_variance128x64)
1733 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits12,
1734 aom_highbd_12_masked_variance64x128,
1735 aom_highbd_12_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001736#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001737 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits12,
1738 aom_highbd_12_masked_variance64x64,
1739 aom_highbd_12_masked_sub_pixel_variance64x64)
1740 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits12,
1741 aom_highbd_12_masked_variance64x32,
1742 aom_highbd_12_masked_sub_pixel_variance64x32)
1743 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits12,
1744 aom_highbd_12_masked_variance32x64,
1745 aom_highbd_12_masked_sub_pixel_variance32x64)
1746 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits12,
1747 aom_highbd_12_masked_variance32x32,
1748 aom_highbd_12_masked_sub_pixel_variance32x32)
1749 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits12,
1750 aom_highbd_12_masked_variance32x16,
1751 aom_highbd_12_masked_sub_pixel_variance32x16)
1752 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits12,
1753 aom_highbd_12_masked_variance16x32,
1754 aom_highbd_12_masked_sub_pixel_variance16x32)
1755 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits12,
1756 aom_highbd_12_masked_variance16x16,
1757 aom_highbd_12_masked_sub_pixel_variance16x16)
1758 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits12,
1759 aom_highbd_12_masked_variance8x16,
1760 aom_highbd_12_masked_sub_pixel_variance8x16)
1761 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits12,
1762 aom_highbd_12_masked_variance16x8,
1763 aom_highbd_12_masked_sub_pixel_variance16x8)
1764 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits12,
1765 aom_highbd_12_masked_variance8x8,
1766 aom_highbd_12_masked_sub_pixel_variance8x8)
1767 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits12,
1768 aom_highbd_12_masked_variance4x8,
1769 aom_highbd_12_masked_sub_pixel_variance4x8)
1770 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits12,
1771 aom_highbd_12_masked_variance8x4,
1772 aom_highbd_12_masked_sub_pixel_variance8x4)
1773 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits12,
1774 aom_highbd_12_masked_variance4x4,
1775 aom_highbd_12_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001776#endif // CONFIG_EXT_INTER
1777
Yue Chencb60b182016-10-13 15:18:22 -07001778#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001779#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001780 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits12,
1781 aom_highbd_12_obmc_variance128x128,
1782 aom_highbd_12_obmc_sub_pixel_variance128x128)
1783 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits12,
1784 aom_highbd_12_obmc_variance128x64,
1785 aom_highbd_12_obmc_sub_pixel_variance128x64)
1786 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits12,
1787 aom_highbd_12_obmc_variance64x128,
1788 aom_highbd_12_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001789#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001790 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits12,
1791 aom_highbd_12_obmc_variance64x64,
1792 aom_highbd_12_obmc_sub_pixel_variance64x64)
1793 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits12,
1794 aom_highbd_12_obmc_variance64x32,
1795 aom_highbd_12_obmc_sub_pixel_variance64x32)
1796 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits12,
1797 aom_highbd_12_obmc_variance32x64,
1798 aom_highbd_12_obmc_sub_pixel_variance32x64)
1799 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits12,
1800 aom_highbd_12_obmc_variance32x32,
1801 aom_highbd_12_obmc_sub_pixel_variance32x32)
1802 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits12,
1803 aom_highbd_12_obmc_variance32x16,
1804 aom_highbd_12_obmc_sub_pixel_variance32x16)
1805 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits12,
1806 aom_highbd_12_obmc_variance16x32,
1807 aom_highbd_12_obmc_sub_pixel_variance16x32)
1808 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits12,
1809 aom_highbd_12_obmc_variance16x16,
1810 aom_highbd_12_obmc_sub_pixel_variance16x16)
1811 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits12,
1812 aom_highbd_12_obmc_variance8x16,
1813 aom_highbd_12_obmc_sub_pixel_variance8x16)
1814 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits12,
1815 aom_highbd_12_obmc_variance16x8,
1816 aom_highbd_12_obmc_sub_pixel_variance16x8)
1817 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits12,
1818 aom_highbd_12_obmc_variance8x8,
1819 aom_highbd_12_obmc_sub_pixel_variance8x8)
1820 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits12,
1821 aom_highbd_12_obmc_variance4x8,
1822 aom_highbd_12_obmc_sub_pixel_variance4x8)
1823 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits12,
1824 aom_highbd_12_obmc_variance8x4,
1825 aom_highbd_12_obmc_sub_pixel_variance8x4)
1826 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits12,
1827 aom_highbd_12_obmc_variance4x4,
1828 aom_highbd_12_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001829#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001830 break;
1831
1832 default:
1833 assert(0 &&
Yaowu Xuf883b422016-08-30 14:01:10 -07001834 "cm->bit_depth should be AOM_BITS_8, "
1835 "AOM_BITS_10 or AOM_BITS_12");
Yaowu Xuc27fc142016-08-22 16:08:15 -07001836 }
1837 }
1838}
Yaowu Xuf883b422016-08-30 14:01:10 -07001839#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001840
Yaowu Xuf883b422016-08-30 14:01:10 -07001841static void realloc_segmentation_maps(AV1_COMP *cpi) {
1842 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001843
1844 // Create the encoder segmentation map and set all entries to 0
Yaowu Xuf883b422016-08-30 14:01:10 -07001845 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001846 CHECK_MEM_ERROR(cm, cpi->segmentation_map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001847 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001848
1849 // Create a map used for cyclic background refresh.
Yaowu Xuf883b422016-08-30 14:01:10 -07001850 if (cpi->cyclic_refresh) av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001851 CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
Yaowu Xuf883b422016-08-30 14:01:10 -07001852 av1_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001853
1854 // Create a map used to mark inactive areas.
Yaowu Xuf883b422016-08-30 14:01:10 -07001855 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001856 CHECK_MEM_ERROR(cm, cpi->active_map.map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001857 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001858}
1859
Yaowu Xuf883b422016-08-30 14:01:10 -07001860void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
1861 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001862 RATE_CONTROL *const rc = &cpi->rc;
1863
1864 if (cm->profile != oxcf->profile) cm->profile = oxcf->profile;
1865 cm->bit_depth = oxcf->bit_depth;
1866 cm->color_space = oxcf->color_space;
1867 cm->color_range = oxcf->color_range;
1868
1869 if (cm->profile <= PROFILE_1)
Yaowu Xuf883b422016-08-30 14:01:10 -07001870 assert(cm->bit_depth == AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001871 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001872 assert(cm->bit_depth > AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001873
1874 cpi->oxcf = *oxcf;
Yaowu Xuf883b422016-08-30 14:01:10 -07001875#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001876 cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
Yaowu Xuf883b422016-08-30 14:01:10 -07001877#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001878#if CONFIG_GLOBAL_MOTION
1879 cpi->td.mb.e_mbd.global_motion = cm->global_motion;
1880#endif // CONFIG_GLOBAL_MOTION
1881
Yaowu Xuf883b422016-08-30 14:01:10 -07001882 if ((oxcf->pass == 0) && (oxcf->rc_mode == AOM_Q)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001883 rc->baseline_gf_interval = FIXED_GF_INTERVAL;
1884 } else {
1885 rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
1886 }
1887
1888 cpi->refresh_last_frame = 1;
1889 cpi->refresh_golden_frame = 0;
1890#if CONFIG_EXT_REFS
1891 cpi->refresh_bwd_ref_frame = 0;
1892#endif // CONFIG_EXT_REFS
1893
1894 cm->refresh_frame_context =
1895 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
1896 ? REFRESH_FRAME_CONTEXT_FORWARD
1897 : REFRESH_FRAME_CONTEXT_BACKWARD;
1898 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
1899
Urvang Joshib100db72016-10-12 16:28:56 -07001900#if CONFIG_PALETTE
Yaowu Xuf883b422016-08-30 14:01:10 -07001901 cm->allow_screen_content_tools = (cpi->oxcf.content == AOM_CONTENT_SCREEN);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001902 if (cm->allow_screen_content_tools) {
1903 MACROBLOCK *x = &cpi->td.mb;
1904 if (x->palette_buffer == 0) {
1905 CHECK_MEM_ERROR(cm, x->palette_buffer,
Yaowu Xuf883b422016-08-30 14:01:10 -07001906 aom_memalign(16, sizeof(*x->palette_buffer)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001907 }
1908 // Reallocate the pc_tree, as it's contents depends on
1909 // the state of cm->allow_screen_content_tools
Yaowu Xuf883b422016-08-30 14:01:10 -07001910 av1_free_pc_tree(&cpi->td);
1911 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001912 }
Urvang Joshib100db72016-10-12 16:28:56 -07001913#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07001914
Yaowu Xuf883b422016-08-30 14:01:10 -07001915 av1_reset_segment_features(cm);
1916 av1_set_high_precision_mv(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001917
Yaowu Xuc27fc142016-08-22 16:08:15 -07001918 set_rc_buffer_sizes(rc, &cpi->oxcf);
1919
1920 // Under a configuration change, where maximum_buffer_size may change,
1921 // keep buffer level clipped to the maximum allowed buffer size.
Yaowu Xuf883b422016-08-30 14:01:10 -07001922 rc->bits_off_target = AOMMIN(rc->bits_off_target, rc->maximum_buffer_size);
1923 rc->buffer_level = AOMMIN(rc->buffer_level, rc->maximum_buffer_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001924
1925 // Set up frame rate and related parameters rate control values.
Yaowu Xuf883b422016-08-30 14:01:10 -07001926 av1_new_framerate(cpi, cpi->framerate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001927
1928 // Set absolute upper and lower quality limits
1929 rc->worst_quality = cpi->oxcf.worst_allowed_q;
1930 rc->best_quality = cpi->oxcf.best_allowed_q;
1931
1932 cm->interp_filter = cpi->sf.default_interp_filter;
1933
1934 if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) {
1935 cm->render_width = cpi->oxcf.render_width;
1936 cm->render_height = cpi->oxcf.render_height;
1937 } else {
1938 cm->render_width = cpi->oxcf.width;
1939 cm->render_height = cpi->oxcf.height;
1940 }
1941 cm->width = cpi->oxcf.width;
1942 cm->height = cpi->oxcf.height;
1943
1944 if (cpi->initial_width) {
1945 if (cm->width > cpi->initial_width || cm->height > cpi->initial_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001946 av1_free_context_buffers(cm);
1947 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001948 realloc_segmentation_maps(cpi);
1949 cpi->initial_width = cpi->initial_height = 0;
1950 }
1951 }
1952 update_frame_size(cpi);
1953
1954 cpi->alt_ref_source = NULL;
1955 rc->is_src_frame_alt_ref = 0;
1956
1957#if CONFIG_EXT_REFS
1958 rc->is_bwd_ref_frame = 0;
1959 rc->is_last_bipred_frame = 0;
1960 rc->is_bipred_frame = 0;
1961#endif // CONFIG_EXT_REFS
1962
1963#if 0
1964 // Experimental RD Code
1965 cpi->frame_distortion = 0;
1966 cpi->last_frame_distortion = 0;
1967#endif
1968
1969 set_tile_info(cpi);
1970
1971 cpi->ext_refresh_frame_flags_pending = 0;
1972 cpi->ext_refresh_frame_context_pending = 0;
1973
Yaowu Xuf883b422016-08-30 14:01:10 -07001974#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001975 highbd_set_var_fns(cpi);
1976#endif
1977}
1978
1979#ifndef M_LOG2_E
1980#define M_LOG2_E 0.693147180559945309417
1981#endif
1982#define log2f(x) (log(x) / (float)M_LOG2_E)
1983
1984#if !CONFIG_REF_MV
1985static void cal_nmvjointsadcost(int *mvjointsadcost) {
1986 mvjointsadcost[0] = 600;
1987 mvjointsadcost[1] = 300;
1988 mvjointsadcost[2] = 300;
1989 mvjointsadcost[3] = 300;
1990}
1991#endif
1992
1993static void cal_nmvsadcosts(int *mvsadcost[2]) {
1994 int i = 1;
1995
1996 mvsadcost[0][0] = 0;
1997 mvsadcost[1][0] = 0;
1998
1999 do {
2000 double z = 256 * (2 * (log2f(8 * i) + .6));
2001 mvsadcost[0][i] = (int)z;
2002 mvsadcost[1][i] = (int)z;
2003 mvsadcost[0][-i] = (int)z;
2004 mvsadcost[1][-i] = (int)z;
2005 } while (++i <= MV_MAX);
2006}
2007
2008static void cal_nmvsadcosts_hp(int *mvsadcost[2]) {
2009 int i = 1;
2010
2011 mvsadcost[0][0] = 0;
2012 mvsadcost[1][0] = 0;
2013
2014 do {
2015 double z = 256 * (2 * (log2f(8 * i) + .6));
2016 mvsadcost[0][i] = (int)z;
2017 mvsadcost[1][i] = (int)z;
2018 mvsadcost[0][-i] = (int)z;
2019 mvsadcost[1][-i] = (int)z;
2020 } while (++i <= MV_MAX);
2021}
2022
Yaowu Xuf883b422016-08-30 14:01:10 -07002023static INLINE void init_upsampled_ref_frame_bufs(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002024 int i;
2025
2026 for (i = 0; i < (REF_FRAMES + 1); ++i) {
2027 cpi->upsampled_ref_bufs[i].ref_count = 0;
2028 cpi->upsampled_ref_idx[i] = INVALID_IDX;
2029 }
2030}
2031
Yaowu Xuf883b422016-08-30 14:01:10 -07002032AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
2033 BufferPool *const pool) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002034 unsigned int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07002035 AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));
2036 AV1_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002037
2038 if (!cm) return NULL;
2039
Yaowu Xuf883b422016-08-30 14:01:10 -07002040 av1_zero(*cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002041
2042 if (setjmp(cm->error.jmp)) {
2043 cm->error.setjmp = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07002044 av1_remove_compressor(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002045 return 0;
2046 }
2047
2048 cm->error.setjmp = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002049 cm->alloc_mi = av1_enc_alloc_mi;
2050 cm->free_mi = av1_enc_free_mi;
2051 cm->setup_mi = av1_enc_setup_mi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002052
Angie Chianga5d96c42016-10-21 16:16:56 -07002053 CHECK_MEM_ERROR(cm, cm->fc,
2054 (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
2055 CHECK_MEM_ERROR(cm, cm->frame_contexts,
2056 (FRAME_CONTEXT *)aom_memalign(
2057 32, FRAME_CONTEXTS * sizeof(*cm->frame_contexts)));
2058 memset(cm->fc, 0, sizeof(*cm->fc));
2059 memset(cm->frame_contexts, 0, FRAME_CONTEXTS * sizeof(*cm->frame_contexts));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002060
2061 cpi->resize_state = 0;
2062 cpi->resize_avg_qp = 0;
2063 cpi->resize_buffer_underflow = 0;
2064 cpi->common.buffer_pool = pool;
2065
2066 init_config(cpi, oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07002067 av1_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002068
2069 cm->current_video_frame = 0;
2070 cpi->partition_search_skippable_frame = 0;
2071 cpi->tile_data = NULL;
2072 cpi->last_show_frame_buf_idx = INVALID_IDX;
2073
2074 realloc_segmentation_maps(cpi);
2075
2076#if CONFIG_REF_MV
2077 for (i = 0; i < NMV_CONTEXTS; ++i) {
Urvang Joshibffc0b52016-07-25 13:38:49 -07002078 memset(cpi->nmv_costs, 0, sizeof(cpi->nmv_costs));
2079 memset(cpi->nmv_costs_hp, 0, sizeof(cpi->nmv_costs_hp));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002080 }
2081#endif
2082
Urvang Joshibffc0b52016-07-25 13:38:49 -07002083 memset(cpi->nmvcosts, 0, sizeof(cpi->nmvcosts));
2084 memset(cpi->nmvcosts_hp, 0, sizeof(cpi->nmvcosts_hp));
2085 memset(cpi->nmvsadcosts, 0, sizeof(cpi->nmvsadcosts));
2086 memset(cpi->nmvsadcosts_hp, 0, sizeof(cpi->nmvsadcosts_hp));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002087
2088 for (i = 0; i < (sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]));
2089 i++) {
2090 CHECK_MEM_ERROR(
2091 cm, cpi->mbgraph_stats[i].mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07002092 aom_calloc(cm->MBs * sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002093 }
2094
2095#if CONFIG_FP_MB_STATS
2096 cpi->use_fp_mb_stats = 0;
2097 if (cpi->use_fp_mb_stats) {
2098 // a place holder used to store the first pass mb stats in the first pass
2099 CHECK_MEM_ERROR(cm, cpi->twopass.frame_mb_stats_buf,
Yaowu Xuf883b422016-08-30 14:01:10 -07002100 aom_calloc(cm->MBs * sizeof(uint8_t), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002101 } else {
2102 cpi->twopass.frame_mb_stats_buf = NULL;
2103 }
2104#endif
2105
2106 cpi->refresh_alt_ref_frame = 0;
2107 cpi->multi_arf_last_grp_enabled = 0;
2108
2109 cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
2110#if CONFIG_INTERNAL_STATS
2111 cpi->b_calculate_blockiness = 1;
2112 cpi->b_calculate_consistency = 1;
2113 cpi->total_inconsistency = 0;
2114 cpi->psnr.worst = 100.0;
2115 cpi->worst_ssim = 100.0;
2116
2117 cpi->count = 0;
2118 cpi->bytes = 0;
2119
2120 if (cpi->b_calculate_psnr) {
2121 cpi->total_sq_error = 0;
2122 cpi->total_samples = 0;
2123 cpi->tot_recode_hits = 0;
2124 cpi->summed_quality = 0;
2125 cpi->summed_weights = 0;
2126 }
2127
2128 cpi->fastssim.worst = 100.0;
2129 cpi->psnrhvs.worst = 100.0;
2130
2131 if (cpi->b_calculate_blockiness) {
2132 cpi->total_blockiness = 0;
2133 cpi->worst_blockiness = 0.0;
2134 }
2135
2136 if (cpi->b_calculate_consistency) {
2137 CHECK_MEM_ERROR(cm, cpi->ssim_vars,
Yaowu Xuf883b422016-08-30 14:01:10 -07002138 aom_malloc(sizeof(*cpi->ssim_vars) * 4 *
Yaowu Xuc27fc142016-08-22 16:08:15 -07002139 cpi->common.mi_rows * cpi->common.mi_cols));
2140 cpi->worst_consistency = 100.0;
2141 }
2142#endif
2143
2144 cpi->first_time_stamp_ever = INT64_MAX;
2145
2146#if CONFIG_REF_MV
2147 for (i = 0; i < NMV_CONTEXTS; ++i) {
2148 cpi->td.mb.nmvcost[i][0] = &cpi->nmv_costs[i][0][MV_MAX];
2149 cpi->td.mb.nmvcost[i][1] = &cpi->nmv_costs[i][1][MV_MAX];
2150 cpi->td.mb.nmvcost_hp[i][0] = &cpi->nmv_costs_hp[i][0][MV_MAX];
2151 cpi->td.mb.nmvcost_hp[i][1] = &cpi->nmv_costs_hp[i][1][MV_MAX];
2152 }
2153#else
2154 cal_nmvjointsadcost(cpi->td.mb.nmvjointsadcost);
2155 cpi->td.mb.nmvcost[0] = &cpi->nmvcosts[0][MV_MAX];
2156 cpi->td.mb.nmvcost[1] = &cpi->nmvcosts[1][MV_MAX];
2157 cpi->td.mb.nmvcost_hp[0] = &cpi->nmvcosts_hp[0][MV_MAX];
2158 cpi->td.mb.nmvcost_hp[1] = &cpi->nmvcosts_hp[1][MV_MAX];
2159#endif
2160 cpi->td.mb.nmvsadcost[0] = &cpi->nmvsadcosts[0][MV_MAX];
2161 cpi->td.mb.nmvsadcost[1] = &cpi->nmvsadcosts[1][MV_MAX];
2162 cal_nmvsadcosts(cpi->td.mb.nmvsadcost);
2163
2164 cpi->td.mb.nmvsadcost_hp[0] = &cpi->nmvsadcosts_hp[0][MV_MAX];
2165 cpi->td.mb.nmvsadcost_hp[1] = &cpi->nmvsadcosts_hp[1][MV_MAX];
2166 cal_nmvsadcosts_hp(cpi->td.mb.nmvsadcost_hp);
2167
2168#ifdef OUTPUT_YUV_SKINMAP
2169 yuv_skinmap_file = fopen("skinmap.yuv", "ab");
2170#endif
2171#ifdef OUTPUT_YUV_REC
2172 yuv_rec_file = fopen("rec.yuv", "wb");
2173#endif
2174
2175#if 0
2176 framepsnr = fopen("framepsnr.stt", "a");
2177 kf_list = fopen("kf_list.stt", "w");
2178#endif
2179
Yaowu Xuc27fc142016-08-22 16:08:15 -07002180 if (oxcf->pass == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002181 av1_init_first_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002182 } else if (oxcf->pass == 2) {
2183 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
2184 const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz);
2185
2186#if CONFIG_FP_MB_STATS
2187 if (cpi->use_fp_mb_stats) {
2188 const size_t psz = cpi->common.MBs * sizeof(uint8_t);
2189 const int ps = (int)(oxcf->firstpass_mb_stats_in.sz / psz);
2190
2191 cpi->twopass.firstpass_mb_stats.mb_stats_start =
2192 oxcf->firstpass_mb_stats_in.buf;
2193 cpi->twopass.firstpass_mb_stats.mb_stats_end =
2194 cpi->twopass.firstpass_mb_stats.mb_stats_start +
2195 (ps - 1) * cpi->common.MBs * sizeof(uint8_t);
2196 }
2197#endif
2198
2199 cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
2200 cpi->twopass.stats_in = cpi->twopass.stats_in_start;
2201 cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];
2202
Yaowu Xuf883b422016-08-30 14:01:10 -07002203 av1_init_second_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002204 }
2205
2206 init_upsampled_ref_frame_bufs(cpi);
2207
Yaowu Xuf883b422016-08-30 14:01:10 -07002208 av1_set_speed_features_framesize_independent(cpi);
2209 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002210
2211 // Allocate memory to store variances for a frame.
Urvang Joshi454280d2016-10-14 16:51:44 -07002212 CHECK_MEM_ERROR(cm, cpi->source_diff_var,
2213 aom_calloc(cm->MBs, sizeof(*cpi->source_diff_var)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002214 cpi->source_var_thresh = 0;
2215 cpi->frames_till_next_var_check = 0;
2216
2217#define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
2218 cpi->fn_ptr[BT].sdf = SDF; \
2219 cpi->fn_ptr[BT].sdaf = SDAF; \
2220 cpi->fn_ptr[BT].vf = VF; \
2221 cpi->fn_ptr[BT].svf = SVF; \
2222 cpi->fn_ptr[BT].svaf = SVAF; \
2223 cpi->fn_ptr[BT].sdx3f = SDX3F; \
2224 cpi->fn_ptr[BT].sdx8f = SDX8F; \
2225 cpi->fn_ptr[BT].sdx4df = SDX4DF;
2226
2227#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002228 BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
2229 aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
2230 aom_sad128x128x3, aom_sad128x128x8, aom_sad128x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002231
Yaowu Xuf883b422016-08-30 14:01:10 -07002232 BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
2233 aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64, NULL,
2234 NULL, aom_sad128x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002235
Yaowu Xuf883b422016-08-30 14:01:10 -07002236 BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
2237 aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128, NULL,
2238 NULL, aom_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002239#endif // CONFIG_EXT_PARTITION
2240
Yaowu Xuf883b422016-08-30 14:01:10 -07002241 BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
2242 aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16, NULL, NULL,
2243 aom_sad32x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002244
Yaowu Xuf883b422016-08-30 14:01:10 -07002245 BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
2246 aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32, NULL, NULL,
2247 aom_sad16x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002248
Yaowu Xuf883b422016-08-30 14:01:10 -07002249 BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
2250 aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32, NULL, NULL,
2251 aom_sad64x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002252
Yaowu Xuf883b422016-08-30 14:01:10 -07002253 BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
2254 aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64, NULL, NULL,
2255 aom_sad32x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002256
Yaowu Xuf883b422016-08-30 14:01:10 -07002257 BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
2258 aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
2259 aom_sad32x32x3, aom_sad32x32x8, aom_sad32x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002260
Yaowu Xuf883b422016-08-30 14:01:10 -07002261 BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
2262 aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
2263 aom_sad64x64x3, aom_sad64x64x8, aom_sad64x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002264
Yaowu Xuf883b422016-08-30 14:01:10 -07002265 BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
2266 aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
2267 aom_sad16x16x3, aom_sad16x16x8, aom_sad16x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002268
Yaowu Xuf883b422016-08-30 14:01:10 -07002269 BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
2270 aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8, aom_sad16x8x3,
2271 aom_sad16x8x8, aom_sad16x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002272
Yaowu Xuf883b422016-08-30 14:01:10 -07002273 BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
2274 aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16, aom_sad8x16x3,
2275 aom_sad8x16x8, aom_sad8x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002276
Yaowu Xuf883b422016-08-30 14:01:10 -07002277 BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
2278 aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x3,
2279 aom_sad8x8x8, aom_sad8x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002280
Yaowu Xuf883b422016-08-30 14:01:10 -07002281 BFP(BLOCK_8X4, aom_sad8x4, aom_sad8x4_avg, aom_variance8x4,
2282 aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, NULL,
2283 aom_sad8x4x8, aom_sad8x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002284
Yaowu Xuf883b422016-08-30 14:01:10 -07002285 BFP(BLOCK_4X8, aom_sad4x8, aom_sad4x8_avg, aom_variance4x8,
2286 aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, NULL,
2287 aom_sad4x8x8, aom_sad4x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288
Yaowu Xuf883b422016-08-30 14:01:10 -07002289 BFP(BLOCK_4X4, aom_sad4x4, aom_sad4x4_avg, aom_variance4x4,
2290 aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x3,
2291 aom_sad4x4x8, aom_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002292
Yue Chencb60b182016-10-13 15:18:22 -07002293#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002294#define OBFP(BT, OSDF, OVF, OSVF) \
2295 cpi->fn_ptr[BT].osdf = OSDF; \
2296 cpi->fn_ptr[BT].ovf = OVF; \
2297 cpi->fn_ptr[BT].osvf = OSVF;
2298
2299#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002300 OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
2301 aom_obmc_sub_pixel_variance128x128)
2302 OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
2303 aom_obmc_sub_pixel_variance128x64)
2304 OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
2305 aom_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002306#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002307 OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
2308 aom_obmc_sub_pixel_variance64x64)
2309 OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
2310 aom_obmc_sub_pixel_variance64x32)
2311 OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
2312 aom_obmc_sub_pixel_variance32x64)
2313 OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
2314 aom_obmc_sub_pixel_variance32x32)
2315 OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
2316 aom_obmc_sub_pixel_variance32x16)
2317 OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
2318 aom_obmc_sub_pixel_variance16x32)
2319 OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
2320 aom_obmc_sub_pixel_variance16x16)
2321 OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
2322 aom_obmc_sub_pixel_variance16x8)
2323 OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
2324 aom_obmc_sub_pixel_variance8x16)
2325 OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
2326 aom_obmc_sub_pixel_variance8x8)
2327 OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
2328 aom_obmc_sub_pixel_variance4x8)
2329 OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
2330 aom_obmc_sub_pixel_variance8x4)
2331 OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
2332 aom_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07002333#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002334
2335#if CONFIG_EXT_INTER
2336#define MBFP(BT, MSDF, MVF, MSVF) \
2337 cpi->fn_ptr[BT].msdf = MSDF; \
2338 cpi->fn_ptr[BT].mvf = MVF; \
2339 cpi->fn_ptr[BT].msvf = MSVF;
2340
2341#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002342 MBFP(BLOCK_128X128, aom_masked_sad128x128, aom_masked_variance128x128,
2343 aom_masked_sub_pixel_variance128x128)
2344 MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_variance128x64,
2345 aom_masked_sub_pixel_variance128x64)
2346 MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_variance64x128,
2347 aom_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002348#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002349 MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_variance64x64,
2350 aom_masked_sub_pixel_variance64x64)
2351 MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_variance64x32,
2352 aom_masked_sub_pixel_variance64x32)
2353 MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_variance32x64,
2354 aom_masked_sub_pixel_variance32x64)
2355 MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_variance32x32,
2356 aom_masked_sub_pixel_variance32x32)
2357 MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_variance32x16,
2358 aom_masked_sub_pixel_variance32x16)
2359 MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_variance16x32,
2360 aom_masked_sub_pixel_variance16x32)
2361 MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_variance16x16,
2362 aom_masked_sub_pixel_variance16x16)
2363 MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_variance16x8,
2364 aom_masked_sub_pixel_variance16x8)
2365 MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_variance8x16,
2366 aom_masked_sub_pixel_variance8x16)
2367 MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_variance8x8,
2368 aom_masked_sub_pixel_variance8x8)
2369 MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_variance4x8,
2370 aom_masked_sub_pixel_variance4x8)
2371 MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_variance8x4,
2372 aom_masked_sub_pixel_variance8x4)
2373 MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_variance4x4,
2374 aom_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002375#endif // CONFIG_EXT_INTER
2376
Yaowu Xuf883b422016-08-30 14:01:10 -07002377#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002378 highbd_set_var_fns(cpi);
2379#endif
2380
Yaowu Xuf883b422016-08-30 14:01:10 -07002381 /* av1_init_quantizer() is first called here. Add check in
2382 * av1_frame_init_quantizer() so that av1_init_quantizer is only
Yaowu Xuc27fc142016-08-22 16:08:15 -07002383 * called later when needed. This will avoid unnecessary calls of
Yaowu Xuf883b422016-08-30 14:01:10 -07002384 * av1_init_quantizer() for every frame.
Yaowu Xuc27fc142016-08-22 16:08:15 -07002385 */
Yaowu Xuf883b422016-08-30 14:01:10 -07002386 av1_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002387#if CONFIG_AOM_QM
2388 aom_qm_init(cm);
2389#endif
2390
Yaowu Xuf883b422016-08-30 14:01:10 -07002391 av1_loop_filter_init(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002392#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07002393 av1_loop_restoration_precal();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002394#endif // CONFIG_LOOP_RESTORATION
2395
2396 cm->error.setjmp = 0;
2397
2398 return cpi;
2399}
2400
2401#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
2402
2403#define SNPRINT2(H, T, V) \
2404 snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
2405
Yaowu Xuf883b422016-08-30 14:01:10 -07002406void av1_remove_compressor(AV1_COMP *cpi) {
2407 AV1_COMMON *cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002408 unsigned int i;
2409 int t;
2410
2411 if (!cpi) return;
2412
2413 cm = &cpi->common;
2414 if (cm->current_video_frame > 0) {
2415#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07002416 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002417
2418 if (cpi->oxcf.pass != 1) {
2419 char headings[512] = { 0 };
2420 char results[512] = { 0 };
2421 FILE *f = fopen("opsnr.stt", "a");
2422 double time_encoded =
2423 (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
2424 10000000.000;
2425 double total_encode_time =
2426 (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
2427 const double dr =
2428 (double)cpi->bytes * (double)8 / (double)1000 / time_encoded;
2429 const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
2430 const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
2431 const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
2432
2433 if (cpi->b_calculate_psnr) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002434 const double total_psnr = aom_sse_to_psnr(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002435 (double)cpi->total_samples, peak, (double)cpi->total_sq_error);
2436 const double total_ssim =
2437 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
2438 snprintf(headings, sizeof(headings),
2439 "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
Yaowu Xuf883b422016-08-30 14:01:10 -07002440 "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
Yaowu Xuc27fc142016-08-22 16:08:15 -07002441 "WstPsnr\tWstSsim\tWstFast\tWstHVS");
2442 snprintf(results, sizeof(results),
2443 "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2444 "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2445 "%7.3f\t%7.3f\t%7.3f\t%7.3f",
2446 dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr,
2447 cpi->psnr.stat[ALL] / cpi->count, total_psnr, total_ssim,
2448 total_ssim, cpi->fastssim.stat[ALL] / cpi->count,
2449 cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst,
2450 cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst);
2451
2452 if (cpi->b_calculate_blockiness) {
2453 SNPRINT(headings, "\t Block\tWstBlck");
2454 SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count);
2455 SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness);
2456 }
2457
2458 if (cpi->b_calculate_consistency) {
2459 double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07002460 aom_sse_to_psnr((double)cpi->total_samples, peak,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002461 (double)cpi->total_inconsistency);
2462
2463 SNPRINT(headings, "\tConsist\tWstCons");
2464 SNPRINT2(results, "\t%7.3f", consistency);
2465 SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
2466 }
Sarah Parkerf97b7862016-08-25 17:42:57 -07002467 fprintf(f, "%s\t Time\tRcErr\tAbsErr\n", headings);
2468 fprintf(f, "%s\t%8.0f\t%7.2f\t%7.2f\n", results, total_encode_time,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002469 rate_err, fabs(rate_err));
2470 }
2471
2472 fclose(f);
2473 }
2474
2475#endif
2476
2477#if 0
2478 {
2479 printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000);
2480 printf("\n_frames recive_data encod_mb_row compress_frame Total\n");
2481 printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame,
2482 cpi->time_receive_data / 1000, cpi->time_encode_sb_row / 1000,
2483 cpi->time_compress_data / 1000,
2484 (cpi->time_receive_data + cpi->time_compress_data) / 1000);
2485 }
2486#endif
2487 }
2488
2489 for (t = 0; t < cpi->num_workers; ++t) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002490 AVxWorker *const worker = &cpi->workers[t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491 EncWorkerData *const thread_data = &cpi->tile_thr_data[t];
2492
2493 // Deallocate allocated threads.
Yaowu Xuf883b422016-08-30 14:01:10 -07002494 aom_get_worker_interface()->end(worker);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002495
2496 // Deallocate allocated thread data.
2497 if (t < cpi->num_workers - 1) {
Urvang Joshib100db72016-10-12 16:28:56 -07002498#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002499 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -07002500 aom_free(thread_data->td->mb.palette_buffer);
Urvang Joshib100db72016-10-12 16:28:56 -07002501#endif // CONFIG_PALETTE
Yaowu Xuf883b422016-08-30 14:01:10 -07002502 aom_free(thread_data->td->counts);
2503 av1_free_pc_tree(thread_data->td);
2504 av1_free_var_tree(thread_data->td);
2505 aom_free(thread_data->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002506 }
2507 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002508 aom_free(cpi->tile_thr_data);
2509 aom_free(cpi->workers);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002510
Yaowu Xuf883b422016-08-30 14:01:10 -07002511 if (cpi->num_workers > 1) av1_loop_filter_dealloc(&cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002512
2513 dealloc_compressor_data(cpi);
2514
2515 for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
2516 ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002517 aom_free(cpi->mbgraph_stats[i].mb_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002518 }
2519
2520#if CONFIG_FP_MB_STATS
2521 if (cpi->use_fp_mb_stats) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002522 aom_free(cpi->twopass.frame_mb_stats_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002523 cpi->twopass.frame_mb_stats_buf = NULL;
2524 }
2525#endif
2526
Yaowu Xuf883b422016-08-30 14:01:10 -07002527 av1_remove_common(cm);
2528 av1_free_ref_frame_buffers(cm->buffer_pool);
2529 aom_free(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002530
2531#ifdef OUTPUT_YUV_SKINMAP
2532 fclose(yuv_skinmap_file);
2533#endif
2534#ifdef OUTPUT_YUV_REC
2535 fclose(yuv_rec_file);
2536#endif
2537
2538#if 0
2539
2540 if (keyfile)
2541 fclose(keyfile);
2542
2543 if (framepsnr)
2544 fclose(framepsnr);
2545
2546 if (kf_list)
2547 fclose(kf_list);
2548
2549#endif
2550}
2551
Yaowu Xuf883b422016-08-30 14:01:10 -07002552static void generate_psnr_packet(AV1_COMP *cpi) {
2553 struct aom_codec_cx_pkt pkt;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002554 int i;
2555 PSNR_STATS psnr;
Yaowu Xuf883b422016-08-30 14:01:10 -07002556#if CONFIG_AOM_HIGHBITDEPTH
2557 aom_calc_highbd_psnr(cpi->Source, cpi->common.frame_to_show, &psnr,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002558 cpi->td.mb.e_mbd.bd, cpi->oxcf.input_bit_depth);
2559#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002560 aom_calc_psnr(cpi->Source, cpi->common.frame_to_show, &psnr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002561#endif
2562
2563 for (i = 0; i < 4; ++i) {
2564 pkt.data.psnr.samples[i] = psnr.samples[i];
2565 pkt.data.psnr.sse[i] = psnr.sse[i];
2566 pkt.data.psnr.psnr[i] = psnr.psnr[i];
2567 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002568 pkt.kind = AOM_CODEC_PSNR_PKT;
2569 aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002570}
2571
Yaowu Xuf883b422016-08-30 14:01:10 -07002572int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002573 if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
2574
2575 cpi->ref_frame_flags = ref_frame_flags;
2576 return 0;
2577}
2578
Yaowu Xuf883b422016-08-30 14:01:10 -07002579void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags) {
2580 cpi->ext_refresh_golden_frame = (ref_frame_flags & AOM_GOLD_FLAG) != 0;
2581 cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & AOM_ALT_FLAG) != 0;
2582 cpi->ext_refresh_last_frame = (ref_frame_flags & AOM_LAST_FLAG) != 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002583 cpi->ext_refresh_frame_flags_pending = 1;
2584}
2585
Yaowu Xuf883b422016-08-30 14:01:10 -07002586static YV12_BUFFER_CONFIG *get_av1_ref_frame_buffer(
2587 AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002588 MV_REFERENCE_FRAME ref_frame = NONE;
Yaowu Xuf883b422016-08-30 14:01:10 -07002589 if (ref_frame_flag == AOM_LAST_FLAG) ref_frame = LAST_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002590#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002591 else if (ref_frame_flag == AOM_LAST2_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002592 ref_frame = LAST2_FRAME;
Yaowu Xuf883b422016-08-30 14:01:10 -07002593 else if (ref_frame_flag == AOM_LAST3_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002594 ref_frame = LAST3_FRAME;
2595#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002596 else if (ref_frame_flag == AOM_GOLD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002597 ref_frame = GOLDEN_FRAME;
2598#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002599 else if (ref_frame_flag == AOM_BWD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002600 ref_frame = BWDREF_FRAME;
2601#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002602 else if (ref_frame_flag == AOM_ALT_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002603 ref_frame = ALTREF_FRAME;
2604
2605 return ref_frame == NONE ? NULL : get_ref_frame_buffer(cpi, ref_frame);
2606}
2607
Yaowu Xuf883b422016-08-30 14:01:10 -07002608int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002609 YV12_BUFFER_CONFIG *sd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002610 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002611 if (cfg) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002612 aom_yv12_copy_frame(cfg, sd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002613 return 0;
2614 } else {
2615 return -1;
2616 }
2617}
2618
Yaowu Xuf883b422016-08-30 14:01:10 -07002619int av1_set_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
2620 YV12_BUFFER_CONFIG *sd) {
2621 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
2622 if (cfg) {
2623 aom_yv12_copy_frame(sd, cfg);
2624 return 0;
2625 } else {
2626 return -1;
2627 }
2628}
2629
2630int av1_update_entropy(AV1_COMP *cpi, int update) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002631 cpi->ext_refresh_frame_context = update;
2632 cpi->ext_refresh_frame_context_pending = 1;
2633 return 0;
2634}
2635
2636#if defined(OUTPUT_YUV_DENOISED) || defined(OUTPUT_YUV_SKINMAP)
2637// The denoiser buffer is allocated as a YUV 440 buffer. This function writes it
2638// as YUV 420. We simply use the top-left pixels of the UV buffers, since we do
2639// not denoise the UV channels at this time. If ever we implement UV channel
2640// denoising we will have to modify this.
Yaowu Xuf883b422016-08-30 14:01:10 -07002641void aom_write_yuv_frame_420(YV12_BUFFER_CONFIG *s, FILE *f) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002642 uint8_t *src = s->y_buffer;
2643 int h = s->y_height;
2644
2645 do {
2646 fwrite(src, s->y_width, 1, f);
2647 src += s->y_stride;
2648 } while (--h);
2649
2650 src = s->u_buffer;
2651 h = s->uv_height;
2652
2653 do {
2654 fwrite(src, s->uv_width, 1, f);
2655 src += s->uv_stride;
2656 } while (--h);
2657
2658 src = s->v_buffer;
2659 h = s->uv_height;
2660
2661 do {
2662 fwrite(src, s->uv_width, 1, f);
2663 src += s->uv_stride;
2664 } while (--h);
2665}
2666#endif
2667
2668#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002669static void check_show_existing_frame(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002670 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
Yaowu Xuf883b422016-08-30 14:01:10 -07002671 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002672 const FRAME_UPDATE_TYPE next_frame_update_type =
2673 gf_group->update_type[gf_group->index];
2674 const int which_arf = gf_group->arf_update_idx[gf_group->index];
Zoe Liu5fca7242016-10-10 17:18:57 -07002675
2676 if (cm->show_existing_frame == 1) {
2677 cm->show_existing_frame = 0;
2678 } else if (cpi->rc.is_last_bipred_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679 // NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
2680 // needed next to show the BWDREF_FRAME, which is pointed by
2681 // the last_fb_idxes[0] after reference frame buffer update
2682 cpi->rc.is_last_bipred_frame = 0;
2683 cm->show_existing_frame = 1;
2684 cpi->existing_fb_idx_to_show = cpi->lst_fb_idxes[0];
2685 } else if (cpi->is_arf_filter_off[which_arf] &&
2686 (next_frame_update_type == OVERLAY_UPDATE ||
2687 next_frame_update_type == INTNL_OVERLAY_UPDATE)) {
2688 // Other parameters related to OVERLAY_UPDATE will be taken care of
Yaowu Xuf883b422016-08-30 14:01:10 -07002689 // in av1_rc_get_second_pass_params(cpi)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002690 cm->show_existing_frame = 1;
2691 cpi->rc.is_src_frame_alt_ref = 1;
2692 cpi->existing_fb_idx_to_show = cpi->alt_fb_idx;
2693 cpi->is_arf_filter_off[which_arf] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002694 }
2695 cpi->rc.is_src_frame_ext_arf = 0;
2696}
2697#endif // CONFIG_EXT_REFS
2698
2699#ifdef OUTPUT_YUV_REC
Yaowu Xuf883b422016-08-30 14:01:10 -07002700void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002701 uint8_t *src = s->y_buffer;
2702 int h = cm->height;
2703
Yaowu Xuf883b422016-08-30 14:01:10 -07002704#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002705 if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
2706 uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
2707
2708 do {
2709 fwrite(src16, s->y_width, 2, yuv_rec_file);
2710 src16 += s->y_stride;
2711 } while (--h);
2712
2713 src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
2714 h = s->uv_height;
2715
2716 do {
2717 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2718 src16 += s->uv_stride;
2719 } while (--h);
2720
2721 src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
2722 h = s->uv_height;
2723
2724 do {
2725 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2726 src16 += s->uv_stride;
2727 } while (--h);
2728
2729 fflush(yuv_rec_file);
2730 return;
2731 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002732#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002733
2734 do {
2735 fwrite(src, s->y_width, 1, yuv_rec_file);
2736 src += s->y_stride;
2737 } while (--h);
2738
2739 src = s->u_buffer;
2740 h = s->uv_height;
2741
2742 do {
2743 fwrite(src, s->uv_width, 1, yuv_rec_file);
2744 src += s->uv_stride;
2745 } while (--h);
2746
2747 src = s->v_buffer;
2748 h = s->uv_height;
2749
2750 do {
2751 fwrite(src, s->uv_width, 1, yuv_rec_file);
2752 src += s->uv_stride;
2753 } while (--h);
2754
2755 fflush(yuv_rec_file);
2756}
2757#endif // OUTPUT_YUV_REC
2758
Yaowu Xuf883b422016-08-30 14:01:10 -07002759#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002760static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
2761 YV12_BUFFER_CONFIG *dst,
2762 int bd) {
2763#else
2764static void scale_and_extend_frame_nonnormative(const YV12_BUFFER_CONFIG *src,
2765 YV12_BUFFER_CONFIG *dst) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002766#endif // CONFIG_AOM_HIGHBITDEPTH
2767 // TODO(dkovalev): replace YV12_BUFFER_CONFIG with aom_image_t
Yaowu Xuc27fc142016-08-22 16:08:15 -07002768 int i;
2769 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2770 src->v_buffer };
2771 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2772 const int src_widths[3] = { src->y_crop_width, src->uv_crop_width,
2773 src->uv_crop_width };
2774 const int src_heights[3] = { src->y_crop_height, src->uv_crop_height,
2775 src->uv_crop_height };
2776 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2777 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2778 const int dst_widths[3] = { dst->y_crop_width, dst->uv_crop_width,
2779 dst->uv_crop_width };
2780 const int dst_heights[3] = { dst->y_crop_height, dst->uv_crop_height,
2781 dst->uv_crop_height };
2782
2783 for (i = 0; i < MAX_MB_PLANE; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002784#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002785 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002786 av1_highbd_resize_plane(srcs[i], src_heights[i], src_widths[i],
2787 src_strides[i], dsts[i], dst_heights[i],
2788 dst_widths[i], dst_strides[i], bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002789 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002790 av1_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
2791 dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002792 }
2793#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002794 av1_resize_plane(srcs[i], src_heights[i], src_widths[i], src_strides[i],
2795 dsts[i], dst_heights[i], dst_widths[i], dst_strides[i]);
2796#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002797 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002798 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002799}
2800
Yaowu Xuf883b422016-08-30 14:01:10 -07002801#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002802static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2803 YV12_BUFFER_CONFIG *dst, int planes,
2804 int bd) {
2805#else
2806static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2807 YV12_BUFFER_CONFIG *dst, int planes) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002808#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002809 const int src_w = src->y_crop_width;
2810 const int src_h = src->y_crop_height;
2811 const int dst_w = dst->y_crop_width;
2812 const int dst_h = dst->y_crop_height;
2813 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2814 src->v_buffer };
2815 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2816 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2817 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2818 const InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -07002819 av1_get_interp_filter_params(EIGHTTAP_REGULAR);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002820 const int16_t *kernel = interp_filter_params.filter_ptr;
2821 const int taps = interp_filter_params.taps;
2822 int x, y, i;
2823
Yaowu Xu637590c2016-11-16 15:15:46 -08002824 assert(planes <= 3);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002825 for (y = 0; y < dst_h; y += 16) {
2826 for (x = 0; x < dst_w; x += 16) {
2827 for (i = 0; i < planes; ++i) {
2828 const int factor = (i == 0 || i == 3 ? 1 : 2);
2829 const int x_q4 = x * (16 / factor) * src_w / dst_w;
2830 const int y_q4 = y * (16 / factor) * src_h / dst_h;
2831 const int src_stride = src_strides[i];
2832 const int dst_stride = dst_strides[i];
2833 const uint8_t *src_ptr = srcs[i] +
2834 (y / factor) * src_h / dst_h * src_stride +
2835 (x / factor) * src_w / dst_w;
2836 uint8_t *dst_ptr = dsts[i] + (y / factor) * dst_stride + (x / factor);
2837
Yaowu Xuf883b422016-08-30 14:01:10 -07002838#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002839 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002840 aom_highbd_convolve8(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002841 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2842 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2843 16 / factor, 16 / factor, bd);
2844 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002845 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2847 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2848 16 / factor, 16 / factor);
2849 }
2850#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002851 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002852 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2853 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
2854 16 / factor, 16 / factor);
Yaowu Xuf883b422016-08-30 14:01:10 -07002855#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002856 }
2857 }
2858 }
2859
2860 if (planes == 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07002861 aom_extend_frame_borders_y(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002862 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002863 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002864}
2865
Yaowu Xuf883b422016-08-30 14:01:10 -07002866static int scale_down(AV1_COMP *cpi, int q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002867 RATE_CONTROL *const rc = &cpi->rc;
2868 GF_GROUP *const gf_group = &cpi->twopass.gf_group;
2869 int scale = 0;
2870 assert(frame_is_kf_gf_arf(cpi));
2871
2872 if (rc->frame_size_selector == UNSCALED &&
2873 q >= rc->rf_level_maxq[gf_group->rf_level[gf_group->index]]) {
2874 const int max_size_thresh =
2875 (int)(rate_thresh_mult[SCALE_STEP1] *
Yaowu Xuf883b422016-08-30 14:01:10 -07002876 AOMMAX(rc->this_frame_target, rc->avg_frame_bandwidth));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002877 scale = rc->projected_frame_size > max_size_thresh ? 1 : 0;
2878 }
2879 return scale;
2880}
2881
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002882#if CONFIG_GLOBAL_MOTION
2883#define MIN_GLOBAL_MOTION_BLKS 4
2884static int recode_loop_test_global_motion(AV1_COMP *cpi) {
2885 int i;
2886 int recode = 0;
2887 AV1_COMMON *const cm = &cpi->common;
2888 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
2889 if (cm->global_motion[i].wmtype != IDENTITY &&
2890 cpi->global_motion_used[i] < MIN_GLOBAL_MOTION_BLKS) {
2891 set_default_gmparams(&cm->global_motion[i]);
David Barker43479c62016-11-30 10:34:20 +00002892#if CONFIG_REF_MV
2893 recode = 1;
2894#else
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002895 recode |= (cpi->global_motion_used[i] > 0);
David Barker43479c62016-11-30 10:34:20 +00002896#endif
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002897 }
2898 }
2899 return recode;
2900}
2901#endif // CONFIG_GLOBAL_MOTION
2902
Yaowu Xuc27fc142016-08-22 16:08:15 -07002903// Function to test for conditions that indicate we should loop
2904// back and recode a frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002905static int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit, int q,
2906 int maxq, int minq) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002907 const RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07002908 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002909 const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
2910 int force_recode = 0;
2911
2912 if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
2913 (cpi->sf.recode_loop == ALLOW_RECODE) ||
2914 (frame_is_kfgfarf && (cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
2915 if (frame_is_kfgfarf && (oxcf->resize_mode == RESIZE_DYNAMIC) &&
2916 scale_down(cpi, q)) {
2917 // Code this group at a lower resolution.
2918 cpi->resize_pending = 1;
2919 return 1;
2920 }
2921
2922 // TODO(agrange) high_limit could be greater than the scale-down threshold.
2923 if ((rc->projected_frame_size > high_limit && q < maxq) ||
2924 (rc->projected_frame_size < low_limit && q > minq)) {
2925 force_recode = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002926 } else if (cpi->oxcf.rc_mode == AOM_CQ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002927 // Deal with frame undershoot and whether or not we are
2928 // below the automatically set cq level.
2929 if (q > oxcf->cq_level &&
2930 rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
2931 force_recode = 1;
2932 }
2933 }
2934 }
2935 return force_recode;
2936}
2937
2938static INLINE int get_free_upsampled_ref_buf(EncRefCntBuffer *ubufs) {
2939 int i;
2940
2941 for (i = 0; i < (REF_FRAMES + 1); i++) {
2942 if (!ubufs[i].ref_count) {
2943 return i;
2944 }
2945 }
2946 return INVALID_IDX;
2947}
2948
2949// Up-sample 1 reference frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002950static INLINE int upsample_ref_frame(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002951 const YV12_BUFFER_CONFIG *const ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002952 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002953 EncRefCntBuffer *ubufs = cpi->upsampled_ref_bufs;
2954 int new_uidx = get_free_upsampled_ref_buf(ubufs);
2955
2956 if (new_uidx == INVALID_IDX) {
2957 return INVALID_IDX;
2958 } else {
2959 YV12_BUFFER_CONFIG *upsampled_ref = &ubufs[new_uidx].buf;
2960
2961 // Can allocate buffer for Y plane only.
2962 if (upsampled_ref->buffer_alloc_sz < (ref->buffer_alloc_sz << 6))
Yaowu Xuf883b422016-08-30 14:01:10 -07002963 if (aom_realloc_frame_buffer(upsampled_ref, (cm->width << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07002964 (cm->height << 3), cm->subsampling_x,
2965 cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07002966#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002967 cm->use_highbitdepth,
2968#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07002969 (AOM_BORDER_IN_PIXELS << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07002970 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07002971 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002972 "Failed to allocate up-sampled frame buffer");
2973
2974// Currently, only Y plane is up-sampled, U, V are not used.
Yaowu Xuf883b422016-08-30 14:01:10 -07002975#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002976 scale_and_extend_frame(ref, upsampled_ref, 1, (int)cm->bit_depth);
2977#else
2978 scale_and_extend_frame(ref, upsampled_ref, 1);
2979#endif
2980 return new_uidx;
2981 }
2982}
2983
2984#define DUMP_REF_FRAME_IMAGES 0
2985
2986#if DUMP_REF_FRAME_IMAGES == 1
Yaowu Xuf883b422016-08-30 14:01:10 -07002987static int dump_one_image(AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002988 const YV12_BUFFER_CONFIG *const ref_buf,
2989 char *file_name) {
2990 int h;
2991 FILE *f_ref = NULL;
2992
2993 if (ref_buf == NULL) {
2994 printf("Frame data buffer is NULL.\n");
Yaowu Xuf883b422016-08-30 14:01:10 -07002995 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002996 }
2997
2998 if ((f_ref = fopen(file_name, "wb")) == NULL) {
2999 printf("Unable to open file %s to write.\n", file_name);
Yaowu Xuf883b422016-08-30 14:01:10 -07003000 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003001 }
3002
3003 // --- Y ---
3004 for (h = 0; h < cm->height; ++h) {
3005 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
3006 }
3007 // --- U ---
3008 for (h = 0; h < (cm->height >> 1); ++h) {
3009 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
3010 f_ref);
3011 }
3012 // --- V ---
3013 for (h = 0; h < (cm->height >> 1); ++h) {
3014 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
3015 f_ref);
3016 }
3017
3018 fclose(f_ref);
3019
Yaowu Xuf883b422016-08-30 14:01:10 -07003020 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003021}
3022
Yaowu Xuf883b422016-08-30 14:01:10 -07003023static void dump_ref_frame_images(AV1_COMP *cpi) {
3024 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003025 MV_REFERENCE_FRAME ref_frame;
3026
3027 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3028 char file_name[256] = "";
3029 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
3030 cm->current_video_frame, ref_frame);
3031 dump_one_image(cm, get_ref_frame_buffer(cpi, ref_frame), file_name);
3032 }
3033}
3034#endif // DUMP_REF_FRAME_IMAGES == 1
3035
3036#if CONFIG_EXT_REFS
3037// This function is used to shift the virtual indices of last reference frames
3038// as follows:
3039// LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3040// when the LAST_FRAME is updated.
Yaowu Xuf883b422016-08-30 14:01:10 -07003041static INLINE void shift_last_ref_frames(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003042 int ref_frame;
3043 for (ref_frame = LAST_REF_FRAMES - 1; ref_frame > 0; --ref_frame) {
3044 cpi->lst_fb_idxes[ref_frame] = cpi->lst_fb_idxes[ref_frame - 1];
3045
3046 // [0] is allocated to the current coded frame. The statistics for the
Zoe Liuf0e46692016-10-12 12:31:43 -07003047 // reference frames start at [LAST_FRAME], i.e. [1].
Yaowu Xuc27fc142016-08-22 16:08:15 -07003048 if (!cpi->rc.is_src_frame_alt_ref) {
Zoe Liuf0e46692016-10-12 12:31:43 -07003049 memcpy(cpi->interp_filter_selected[ref_frame + LAST_FRAME],
3050 cpi->interp_filter_selected[ref_frame - 1 + LAST_FRAME],
3051 sizeof(cpi->interp_filter_selected[ref_frame - 1 + LAST_FRAME]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003052 }
3053 }
3054}
Zoe Liuf0e46692016-10-12 12:31:43 -07003055#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003056
Yaowu Xuf883b422016-08-30 14:01:10 -07003057void av1_update_reference_frames(AV1_COMP *cpi) {
3058 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003059 BufferPool *const pool = cm->buffer_pool;
3060 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3061 int new_uidx = 0;
3062
3063 // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3064 // for the purpose to verify no mismatch between encoder and decoder.
3065 if (cm->show_frame) cpi->last_show_frame_buf_idx = cm->new_fb_idx;
3066
3067 if (use_upsampled_ref) {
3068#if CONFIG_EXT_REFS
3069 if (cm->show_existing_frame) {
3070 new_uidx = cpi->upsampled_ref_idx[cpi->existing_fb_idx_to_show];
3071 // TODO(zoeliu): Once following is confirmed, remove it.
3072 assert(cpi->upsampled_ref_bufs[new_uidx].ref_count > 0);
3073 } else {
3074#endif // CONFIG_EXT_REFS
3075 // Up-sample the current encoded frame.
3076 RefCntBuffer *bufs = pool->frame_bufs;
3077 const YV12_BUFFER_CONFIG *const ref = &bufs[cm->new_fb_idx].buf;
3078
3079 new_uidx = upsample_ref_frame(cpi, ref);
3080#if CONFIG_EXT_REFS
3081 assert(new_uidx != INVALID_IDX);
3082 }
3083#endif // CONFIG_EXT_REFS
3084 }
3085 // At this point the new frame has been encoded.
3086 // If any buffer copy / swapping is signaled it should be done here.
3087 if (cm->frame_type == KEY_FRAME) {
3088 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3089 cm->new_fb_idx);
3090#if CONFIG_EXT_REFS
3091 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3092 cm->new_fb_idx);
3093#endif // CONFIG_EXT_REFS
3094 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3095 cm->new_fb_idx);
3096
3097 if (use_upsampled_ref) {
3098 uref_cnt_fb(cpi->upsampled_ref_bufs,
3099 &cpi->upsampled_ref_idx[cpi->gld_fb_idx], new_uidx);
3100#if CONFIG_EXT_REFS
3101 uref_cnt_fb(cpi->upsampled_ref_bufs,
3102 &cpi->upsampled_ref_idx[cpi->bwd_fb_idx], new_uidx);
3103#endif // CONFIG_EXT_REFS
3104 uref_cnt_fb(cpi->upsampled_ref_bufs,
3105 &cpi->upsampled_ref_idx[cpi->alt_fb_idx], new_uidx);
3106 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003107 } else if (av1_preserve_existing_gf(cpi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003108 // We have decided to preserve the previously existing golden frame as our
3109 // new ARF frame. However, in the short term in function
Yaowu Xuf883b422016-08-30 14:01:10 -07003110 // av1_bitstream.c::get_refresh_mask() we left it in the GF slot and, if
Yaowu Xuc27fc142016-08-22 16:08:15 -07003111 // we're updating the GF with the current decoded frame, we save it to the
3112 // ARF slot instead.
3113 // We now have to update the ARF with the current frame and swap gld_fb_idx
3114 // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF
3115 // slot and, if we're updating the GF, the current frame becomes the new GF.
3116 int tmp;
3117
3118 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3119 cm->new_fb_idx);
3120 if (use_upsampled_ref)
3121 uref_cnt_fb(cpi->upsampled_ref_bufs,
3122 &cpi->upsampled_ref_idx[cpi->alt_fb_idx], new_uidx);
3123
3124 tmp = cpi->alt_fb_idx;
3125 cpi->alt_fb_idx = cpi->gld_fb_idx;
3126 cpi->gld_fb_idx = tmp;
3127
3128#if CONFIG_EXT_REFS
3129 // We need to modify the mapping accordingly
3130 cpi->arf_map[0] = cpi->alt_fb_idx;
3131#endif
3132// TODO(zoeliu): Do we need to copy cpi->interp_filter_selected[0] over to
3133// cpi->interp_filter_selected[GOLDEN_FRAME]?
3134#if CONFIG_EXT_REFS
3135 } else if (cpi->rc.is_last_bipred_frame) {
3136 // Refresh the LAST_FRAME with the BWDREF_FRAME and retire the LAST3_FRAME
3137 // by updating the virtual indices. Note that the frame BWDREF_FRAME points
3138 // to now should be retired, and it should not be used before refreshed.
3139 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3140
3141 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003142 cpi->lst_fb_idxes[0] = cpi->bwd_fb_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143 cpi->bwd_fb_idx = tmp;
Zoe Liuf0e46692016-10-12 12:31:43 -07003144
3145 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3146 cpi->interp_filter_selected[BWDREF_FRAME],
3147 sizeof(cpi->interp_filter_selected[BWDREF_FRAME]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003148 } else if (cpi->rc.is_src_frame_ext_arf && cm->show_existing_frame) {
3149 // Deal with the special case for showing existing internal ALTREF_FRAME
3150 // Refresh the LAST_FRAME with the ALTREF_FRAME and retire the LAST3_FRAME
3151 // by updating the virtual indices.
3152 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3153 int which_arf = gf_group->arf_ref_idx[gf_group->index];
3154 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3155
3156 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003157 cpi->lst_fb_idxes[0] = cpi->alt_fb_idx;
Zoe Liuf0e46692016-10-12 12:31:43 -07003158 cpi->alt_fb_idx = tmp;
3159
3160 // We need to modify the mapping accordingly
3161 cpi->arf_map[which_arf] = cpi->alt_fb_idx;
3162
Yaowu Xuc27fc142016-08-22 16:08:15 -07003163 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3164 cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3165 sizeof(cpi->interp_filter_selected[ALTREF_FRAME + which_arf]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003166#endif // CONFIG_EXT_REFS
3167 } else { /* For non key/golden frames */
3168 if (cpi->refresh_alt_ref_frame) {
3169 int arf_idx = cpi->alt_fb_idx;
3170 int which_arf = 0;
3171#if CONFIG_EXT_REFS
3172 if (cpi->oxcf.pass == 2) {
3173 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3174 which_arf = gf_group->arf_update_idx[gf_group->index];
3175 arf_idx = cpi->arf_map[which_arf];
3176 }
3177#else
3178 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
3179 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3180 arf_idx = gf_group->arf_update_idx[gf_group->index];
3181 }
3182#endif // CONFIG_EXT_REFS
3183 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
3184 if (use_upsampled_ref)
3185 uref_cnt_fb(cpi->upsampled_ref_bufs, &cpi->upsampled_ref_idx[arf_idx],
3186 new_uidx);
3187
3188 memcpy(cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3189 cpi->interp_filter_selected[0],
3190 sizeof(cpi->interp_filter_selected[0]));
3191 }
3192
3193 if (cpi->refresh_golden_frame) {
3194 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3195 cm->new_fb_idx);
3196 if (use_upsampled_ref)
3197 uref_cnt_fb(cpi->upsampled_ref_bufs,
3198 &cpi->upsampled_ref_idx[cpi->gld_fb_idx], new_uidx);
3199
Zoe Liuf0e46692016-10-12 12:31:43 -07003200#if !CONFIG_EXT_REFS
3201 if (!cpi->rc.is_src_frame_alt_ref)
3202#endif // !CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003203 memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3204 cpi->interp_filter_selected[0],
3205 sizeof(cpi->interp_filter_selected[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003206 }
3207
3208#if CONFIG_EXT_REFS
3209 if (cpi->refresh_bwd_ref_frame) {
3210 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3211 // We have swapped the virtual indices to allow bwd_ref_frame to use
3212 // ALT0 as reference frame. We need to swap them back.
3213 // NOTE: The ALT_REFs' are indexed reversely, and ALT0 refers to the
3214 // farthest ALT_REF from the first frame in the gf group.
3215 int tmp = cpi->arf_map[0];
3216 cpi->arf_map[0] = cpi->alt_fb_idx;
3217 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3218 cpi->bwd_fb_idx = tmp;
3219 }
Zoe Liuf0e46692016-10-12 12:31:43 -07003220
Yaowu Xuc27fc142016-08-22 16:08:15 -07003221 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3222 cm->new_fb_idx);
3223 if (use_upsampled_ref)
3224 uref_cnt_fb(cpi->upsampled_ref_bufs,
3225 &cpi->upsampled_ref_idx[cpi->bwd_fb_idx], new_uidx);
3226
3227 memcpy(cpi->interp_filter_selected[BWDREF_FRAME],
3228 cpi->interp_filter_selected[0],
3229 sizeof(cpi->interp_filter_selected[0]));
3230 }
3231#endif // CONFIG_EXT_REFS
3232 }
3233
3234 if (cpi->refresh_last_frame) {
3235#if CONFIG_EXT_REFS
3236 // NOTE(zoeliu): We have two layers of mapping (1) from the per-frame
3237 // reference to the reference frame buffer virtual index; and then (2) from
3238 // the virtual index to the reference frame buffer physical index:
3239 //
3240 // LAST_FRAME, ..., LAST3_FRAME, ..., ALTREF_FRAME
3241 // | | |
3242 // v v v
3243 // lst_fb_idxes[0], ..., lst_fb_idxes[2], ..., alt_fb_idx
3244 // | | |
3245 // v v v
3246 // ref_frame_map[], ..., ref_frame_map[], ..., ref_frame_map[]
3247 //
3248 // When refresh_last_frame is set, it is intended to retire LAST3_FRAME,
3249 // have the other 2 LAST reference frames shifted as follows:
3250 // LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3251 // , and then have LAST_FRAME refreshed by the newly coded frame.
3252 //
3253 // To fulfill it, the decoder will be notified to execute following 2 steps:
3254 //
3255 // (a) To change ref_frame_map[] and have the virtual index of LAST3_FRAME
3256 // to point to the newly coded frame, i.e.
3257 // ref_frame_map[lst_fb_idexes[2]] => new_fb_idx;
3258 //
3259 // (b) To change the 1st layer mapping to have LAST_FRAME mapped to the
3260 // original virtual index of LAST3_FRAME and have the other mappings
3261 // shifted as follows:
3262 // LAST_FRAME, LAST2_FRAME, LAST3_FRAME
3263 // | | |
3264 // v v v
3265 // lst_fb_idxes[2], lst_fb_idxes[0], lst_fb_idxes[1]
3266 int ref_frame;
Zoe Liu5fca7242016-10-10 17:18:57 -07003267
Yaowu Xuc27fc142016-08-22 16:08:15 -07003268 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3269 // We have swapped the virtual indices to use ALT0 as BWD_REF
3270 // and we need to swap them back.
3271 int tmp = cpi->arf_map[0];
3272 cpi->arf_map[0] = cpi->alt_fb_idx;
3273 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3274 cpi->bwd_fb_idx = tmp;
3275 }
Zoe Liu5fca7242016-10-10 17:18:57 -07003276
Yaowu Xuc27fc142016-08-22 16:08:15 -07003277 if (cm->frame_type == KEY_FRAME) {
3278 for (ref_frame = 0; ref_frame < LAST_REF_FRAMES; ++ref_frame) {
3279 ref_cnt_fb(pool->frame_bufs,
3280 &cm->ref_frame_map[cpi->lst_fb_idxes[ref_frame]],
3281 cm->new_fb_idx);
3282
3283 if (use_upsampled_ref)
3284 uref_cnt_fb(cpi->upsampled_ref_bufs,
3285 &cpi->upsampled_ref_idx[cpi->lst_fb_idxes[ref_frame]],
3286 new_uidx);
3287 }
3288 } else {
3289 int tmp;
3290
3291 ref_cnt_fb(pool->frame_bufs,
3292 &cm->ref_frame_map[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3293 cm->new_fb_idx);
3294
3295 if (use_upsampled_ref)
3296 uref_cnt_fb(
3297 cpi->upsampled_ref_bufs,
3298 &cpi->upsampled_ref_idx[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3299 new_uidx);
3300
3301 tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3302
3303 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003304 cpi->lst_fb_idxes[0] = tmp;
3305
Zoe Liuf0e46692016-10-12 12:31:43 -07003306 assert(cm->show_existing_frame == 0);
3307 // NOTE: Currently only LF_UPDATE and INTNL_OVERLAY_UPDATE frames are to
3308 // refresh the LAST_FRAME.
3309 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3310 cpi->interp_filter_selected[0],
3311 sizeof(cpi->interp_filter_selected[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003312 }
3313#else
3314 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
3315 cm->new_fb_idx);
3316 if (use_upsampled_ref)
3317 uref_cnt_fb(cpi->upsampled_ref_bufs,
3318 &cpi->upsampled_ref_idx[cpi->lst_fb_idx], new_uidx);
3319 if (!cpi->rc.is_src_frame_alt_ref) {
3320 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3321 cpi->interp_filter_selected[0],
3322 sizeof(cpi->interp_filter_selected[0]));
3323 }
3324#endif // CONFIG_EXT_REFS
3325 }
3326
3327#if DUMP_REF_FRAME_IMAGES == 1
3328 // Dump out all reference frame images.
3329 dump_ref_frame_images(cpi);
3330#endif // DUMP_REF_FRAME_IMAGES
3331}
3332
Yaowu Xuf883b422016-08-30 14:01:10 -07003333static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003334 MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
3335 struct loopfilter *lf = &cm->lf;
3336 if (is_lossless_requested(&cpi->oxcf)) {
3337 lf->filter_level = 0;
3338 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07003339 struct aom_usec_timer timer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003340
Yaowu Xuf883b422016-08-30 14:01:10 -07003341 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003342
Yaowu Xuf883b422016-08-30 14:01:10 -07003343 aom_usec_timer_start(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003344
3345#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07003346 av1_pick_filter_restoration(cpi->Source, cpi, cpi->sf.lpf_pick);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003347#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003348 av1_pick_filter_level(cpi->Source, cpi, cpi->sf.lpf_pick);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003349#endif // CONFIG_LOOP_RESTORATION
3350
Yaowu Xuf883b422016-08-30 14:01:10 -07003351 aom_usec_timer_mark(&timer);
3352 cpi->time_pick_lpf += aom_usec_timer_elapsed(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003353 }
3354
3355 if (lf->filter_level > 0) {
3356#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07003357 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003358#else
3359 if (cpi->num_workers > 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07003360 av1_loop_filter_frame_mt(cm->frame_to_show, cm, xd->plane,
3361 lf->filter_level, 0, 0, cpi->workers,
3362 cpi->num_workers, &cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003363 else
Yaowu Xuf883b422016-08-30 14:01:10 -07003364 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003365#endif
3366 }
Steinar Midtskogen5d56f4d2016-09-25 09:23:16 +02003367#if CONFIG_DERING
3368 if (is_lossless_requested(&cpi->oxcf)) {
3369 cm->dering_level = 0;
3370 } else {
3371 cm->dering_level =
3372 av1_dering_search(cm->frame_to_show, cpi->Source, cm, xd);
3373 av1_dering_frame(cm->frame_to_show, cm, xd, cm->dering_level);
3374 }
3375#endif // CONFIG_DERING
3376
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003377#if CONFIG_CLPF
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003378 cm->clpf_strength_y = cm->clpf_strength_u = cm->clpf_strength_v = 0;
Yaowu Xud71be782016-10-14 08:47:03 -07003379 cm->clpf_size = CLPF_64X64;
3380
3381 // Allocate buffer to hold the status of all filter blocks:
3382 // 1 = On, 0 = off, -1 = implicitly off
3383 {
3384 int size;
3385 cm->clpf_stride = ((cm->frame_to_show->y_crop_width + MIN_FB_SIZE - 1) &
3386 ~(MIN_FB_SIZE - 1)) >>
3387 MIN_FB_SIZE_LOG2;
3388 size = cm->clpf_stride *
3389 ((cm->frame_to_show->y_crop_height + MIN_FB_SIZE - 1) &
3390 ~(MIN_FB_SIZE - 1)) >>
3391 MIN_FB_SIZE_LOG2;
3392 CHECK_MEM_ERROR(cm, cm->clpf_blocks, aom_malloc(size));
3393 memset(cm->clpf_blocks, CLPF_NOFLAG, size);
3394 }
3395
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003396 if (!is_lossless_requested(&cpi->oxcf)) {
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003397 const YV12_BUFFER_CONFIG *const frame = cm->frame_to_show;
3398
Steinar Midtskogen499deb92016-09-02 10:56:54 +02003399 // Find the best strength and block size for the entire frame
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003400 int fb_size_log2, strength_y, strength_u, strength_v;
3401 av1_clpf_test_frame(frame, cpi->Source, cm, &strength_y, &fb_size_log2,
3402 AOM_PLANE_Y);
Steinar Midtskogen2e40cc42016-09-21 12:39:13 +02003403 av1_clpf_test_frame(frame, cpi->Source, cm, &strength_u, 0, AOM_PLANE_U);
3404 av1_clpf_test_frame(frame, cpi->Source, cm, &strength_v, 0, AOM_PLANE_V);
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003405
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003406 if (strength_y) {
Steinar Midtskogen499deb92016-09-02 10:56:54 +02003407 // Apply the filter using the chosen strength
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003408 cm->clpf_strength_y = strength_y - (strength_y == 4);
Steinar Midtskogen499deb92016-09-02 10:56:54 +02003409 cm->clpf_size =
Yaowu Xud71be782016-10-14 08:47:03 -07003410 fb_size_log2 ? fb_size_log2 - MAX_FB_SIZE_LOG2 + 3 : CLPF_NOSIZE;
3411 av1_clpf_frame(frame, cpi->Source, cm, cm->clpf_size != CLPF_NOSIZE,
3412 strength_y, 4 + cm->clpf_size, AOM_PLANE_Y,
3413 av1_clpf_decision);
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003414 }
3415 if (strength_u) {
3416 cm->clpf_strength_u = strength_u - (strength_u == 4);
Yaowu Xud71be782016-10-14 08:47:03 -07003417 av1_clpf_frame(frame, NULL, cm, 0, strength_u, 4, AOM_PLANE_U, NULL);
Steinar Midtskogenecf9a0c2016-09-13 16:37:13 +02003418 }
3419 if (strength_v) {
3420 cm->clpf_strength_v = strength_v - (strength_v == 4);
Yaowu Xud71be782016-10-14 08:47:03 -07003421 av1_clpf_frame(frame, NULL, cm, 0, strength_v, 4, AOM_PLANE_V, NULL);
Steinar Midtskogend06588a2016-05-06 13:48:20 +02003422 }
3423 }
3424#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003425#if CONFIG_LOOP_RESTORATION
3426 if (cm->rst_info.restoration_type != RESTORE_NONE) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003427 av1_loop_restoration_init(&cm->rst_internal, &cm->rst_info,
3428 cm->frame_type == KEY_FRAME, cm->width,
3429 cm->height);
3430 av1_loop_restoration_rows(cm->frame_to_show, cm, 0, cm->mi_rows, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003431 }
3432#endif // CONFIG_LOOP_RESTORATION
3433
Yaowu Xuf883b422016-08-30 14:01:10 -07003434 aom_extend_frame_inner_borders(cm->frame_to_show);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003435}
3436
Yaowu Xuf883b422016-08-30 14:01:10 -07003437static INLINE void alloc_frame_mvs(AV1_COMMON *const cm, int buffer_idx) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003438 RefCntBuffer *const new_fb_ptr = &cm->buffer_pool->frame_bufs[buffer_idx];
3439 if (new_fb_ptr->mvs == NULL || new_fb_ptr->mi_rows < cm->mi_rows ||
3440 new_fb_ptr->mi_cols < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003441 aom_free(new_fb_ptr->mvs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003442 CHECK_MEM_ERROR(cm, new_fb_ptr->mvs,
Yaowu Xuf883b422016-08-30 14:01:10 -07003443 (MV_REF *)aom_calloc(cm->mi_rows * cm->mi_cols,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003444 sizeof(*new_fb_ptr->mvs)));
3445 new_fb_ptr->mi_rows = cm->mi_rows;
3446 new_fb_ptr->mi_cols = cm->mi_cols;
3447 }
3448}
3449
Yaowu Xuf883b422016-08-30 14:01:10 -07003450void av1_scale_references(AV1_COMP *cpi) {
3451 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003452 MV_REFERENCE_FRAME ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003453 const AOM_REFFRAME ref_mask[INTER_REFS_PER_FRAME] = {
3454 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003455#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003456 AOM_LAST2_FLAG,
3457 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003458#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003459 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003460#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003461 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003462#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003463 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003464 };
3465
3466 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003467 // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
Yaowu Xuc27fc142016-08-22 16:08:15 -07003468 if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
3469 BufferPool *const pool = cm->buffer_pool;
3470 const YV12_BUFFER_CONFIG *const ref =
3471 get_ref_frame_buffer(cpi, ref_frame);
3472
3473 if (ref == NULL) {
3474 cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3475 continue;
3476 }
3477
Yaowu Xuf883b422016-08-30 14:01:10 -07003478#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003479 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3480 RefCntBuffer *new_fb_ptr = NULL;
3481 int force_scaling = 0;
3482 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3483 if (new_fb == INVALID_IDX) {
3484 new_fb = get_free_fb(cm);
3485 force_scaling = 1;
3486 }
3487 if (new_fb == INVALID_IDX) return;
3488 new_fb_ptr = &pool->frame_bufs[new_fb];
3489 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3490 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003491 if (aom_realloc_frame_buffer(
3492 &new_fb_ptr->buf, cm->width, cm->height, cm->subsampling_x,
3493 cm->subsampling_y, cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
3494 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003495 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003496 "Failed to allocate frame buffer");
3497 scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE,
3498 (int)cm->bit_depth);
3499 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3500 alloc_frame_mvs(cm, new_fb);
3501 }
3502#else
3503 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3504 RefCntBuffer *new_fb_ptr = NULL;
3505 int force_scaling = 0;
3506 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3507 if (new_fb == INVALID_IDX) {
3508 new_fb = get_free_fb(cm);
3509 force_scaling = 1;
3510 }
3511 if (new_fb == INVALID_IDX) return;
3512 new_fb_ptr = &pool->frame_bufs[new_fb];
3513 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3514 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003515 if (aom_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003516 cm->subsampling_x, cm->subsampling_y,
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003517 AOM_BORDER_IN_PIXELS, cm->byte_alignment,
3518 NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003519 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003520 "Failed to allocate frame buffer");
3521 scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE);
3522 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3523 alloc_frame_mvs(cm, new_fb);
3524 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003525#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003526
3527 if (cpi->sf.use_upsampled_references &&
3528 (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3529 new_fb_ptr->buf.y_crop_height != cm->height)) {
3530 const int map_idx = get_ref_frame_map_idx(cpi, ref_frame);
3531 EncRefCntBuffer *ubuf =
3532 &cpi->upsampled_ref_bufs[cpi->upsampled_ref_idx[map_idx]];
3533
Yaowu Xuf883b422016-08-30 14:01:10 -07003534 if (aom_realloc_frame_buffer(&ubuf->buf, (cm->width << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003535 (cm->height << 3), cm->subsampling_x,
3536 cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003537#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003538 cm->use_highbitdepth,
3539#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003540 (AOM_BORDER_IN_PIXELS << 3),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003541 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003542 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003543 "Failed to allocate up-sampled frame buffer");
Yaowu Xuf883b422016-08-30 14:01:10 -07003544#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003545 scale_and_extend_frame(&new_fb_ptr->buf, &ubuf->buf, 1,
3546 (int)cm->bit_depth);
3547#else
3548 scale_and_extend_frame(&new_fb_ptr->buf, &ubuf->buf, 1);
3549#endif
3550 }
3551 } else {
3552 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3553 RefCntBuffer *const buf = &pool->frame_bufs[buf_idx];
3554 buf->buf.y_crop_width = ref->y_crop_width;
3555 buf->buf.y_crop_height = ref->y_crop_height;
3556 cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
3557 ++buf->ref_count;
3558 }
3559 } else {
3560 if (cpi->oxcf.pass != 0) cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3561 }
3562 }
3563}
3564
Yaowu Xuf883b422016-08-30 14:01:10 -07003565static void release_scaled_references(AV1_COMP *cpi) {
3566 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003567 int i;
3568 if (cpi->oxcf.pass == 0) {
3569 // Only release scaled references under certain conditions:
3570 // if reference will be updated, or if scaled reference has same resolution.
3571 int refresh[INTER_REFS_PER_FRAME];
3572 refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
3573#if CONFIG_EXT_REFS
3574 refresh[1] = refresh[2] = 0;
3575 refresh[3] = (cpi->refresh_golden_frame) ? 1 : 0;
3576 refresh[4] = (cpi->refresh_bwd_ref_frame) ? 1 : 0;
3577 refresh[5] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3578#else
3579 refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
3580 refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3581#endif // CONFIG_EXT_REFS
3582 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3583 const int idx = cpi->scaled_ref_idx[i - 1];
3584 RefCntBuffer *const buf =
3585 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3586 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i);
3587 if (buf != NULL &&
3588 (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width &&
3589 buf->buf.y_crop_height == ref->y_crop_height))) {
3590 --buf->ref_count;
3591 cpi->scaled_ref_idx[i - 1] = INVALID_IDX;
3592 }
3593 }
3594 } else {
3595 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) {
3596 const int idx = cpi->scaled_ref_idx[i];
3597 RefCntBuffer *const buf =
3598 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3599 if (buf != NULL) {
3600 --buf->ref_count;
3601 cpi->scaled_ref_idx[i] = INVALID_IDX;
3602 }
3603 }
3604 }
3605}
3606
3607static void full_to_model_count(unsigned int *model_count,
3608 unsigned int *full_count) {
3609 int n;
3610 model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN];
3611 model_count[ONE_TOKEN] = full_count[ONE_TOKEN];
3612 model_count[TWO_TOKEN] = full_count[TWO_TOKEN];
3613 for (n = THREE_TOKEN; n < EOB_TOKEN; ++n)
3614 model_count[TWO_TOKEN] += full_count[n];
3615 model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN];
3616}
3617
Yaowu Xuf883b422016-08-30 14:01:10 -07003618void av1_full_to_model_counts(av1_coeff_count_model *model_count,
3619 av1_coeff_count *full_count) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003620 int i, j, k, l;
3621
3622 for (i = 0; i < PLANE_TYPES; ++i)
3623 for (j = 0; j < REF_TYPES; ++j)
3624 for (k = 0; k < COEF_BANDS; ++k)
3625 for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
3626 full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]);
3627}
3628
3629#if 0 && CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07003630static void output_frame_level_debug_stats(AV1_COMP *cpi) {
3631 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003632 FILE *const f = fopen("tmp.stt", cm->current_video_frame ? "a" : "w");
3633 int64_t recon_err;
3634
Yaowu Xuf883b422016-08-30 14:01:10 -07003635 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003636
Yaowu Xuf883b422016-08-30 14:01:10 -07003637 recon_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003638
3639 if (cpi->twopass.total_left_stats.coded_error != 0.0)
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07003640 fprintf(f, "%10u %dx%d %d %d %10d %10d %10d %10d"
Yaowu Xuc27fc142016-08-22 16:08:15 -07003641 "%10"PRId64" %10"PRId64" %5d %5d %10"PRId64" "
3642 "%10"PRId64" %10"PRId64" %10d "
3643 "%7.2lf %7.2lf %7.2lf %7.2lf %7.2lf"
3644 "%6d %6d %5d %5d %5d "
3645 "%10"PRId64" %10.3lf"
3646 "%10lf %8u %10"PRId64" %10d %10d %10d\n",
3647 cpi->common.current_video_frame,
3648 cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003649 cpi->rc.source_alt_ref_pending,
3650 cpi->rc.source_alt_ref_active,
3651 cpi->rc.this_frame_target,
3652 cpi->rc.projected_frame_size,
3653 cpi->rc.projected_frame_size / cpi->common.MBs,
3654 (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
3655 cpi->rc.vbr_bits_off_target,
3656 cpi->rc.vbr_bits_off_target_fast,
3657 cpi->twopass.extend_minq,
3658 cpi->twopass.extend_minq_fast,
3659 cpi->rc.total_target_vs_actual,
3660 (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target),
3661 cpi->rc.total_actual_bits, cm->base_qindex,
Yaowu Xuf883b422016-08-30 14:01:10 -07003662 av1_convert_qindex_to_q(cm->base_qindex, cm->bit_depth),
3663 (double)av1_dc_quant(cm->base_qindex, 0, cm->bit_depth) / 4.0,
3664 av1_convert_qindex_to_q(cpi->twopass.active_worst_quality,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003665 cm->bit_depth),
3666 cpi->rc.avg_q,
Yaowu Xuf883b422016-08-30 14:01:10 -07003667 av1_convert_qindex_to_q(cpi->oxcf.cq_level, cm->bit_depth),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003668 cpi->refresh_last_frame, cpi->refresh_golden_frame,
3669 cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost,
3670 cpi->twopass.bits_left,
3671 cpi->twopass.total_left_stats.coded_error,
3672 cpi->twopass.bits_left /
3673 (1 + cpi->twopass.total_left_stats.coded_error),
3674 cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost,
3675 cpi->twopass.kf_zeromotion_pct,
3676 cpi->twopass.fr_content_type);
3677
3678 fclose(f);
3679
3680 if (0) {
3681 FILE *const fmodes = fopen("Modes.stt", "a");
3682 int i;
3683
3684 fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame,
3685 cm->frame_type, cpi->refresh_golden_frame,
3686 cpi->refresh_alt_ref_frame);
3687
3688 for (i = 0; i < MAX_MODES; ++i)
3689 fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]);
3690
3691 fprintf(fmodes, "\n");
3692
3693 fclose(fmodes);
3694 }
3695}
3696#endif
3697
Yaowu Xuf883b422016-08-30 14:01:10 -07003698static void set_mv_search_params(AV1_COMP *cpi) {
3699 const AV1_COMMON *const cm = &cpi->common;
3700 const unsigned int max_mv_def = AOMMIN(cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003701
3702 // Default based on max resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003703 cpi->mv_step_param = av1_init_search_range(max_mv_def);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003704
3705 if (cpi->sf.mv.auto_mv_step_size) {
3706 if (frame_is_intra_only(cm)) {
3707 // Initialize max_mv_magnitude for use in the first INTER frame
3708 // after a key/intra-only frame.
3709 cpi->max_mv_magnitude = max_mv_def;
3710 } else {
3711 if (cm->show_frame) {
3712 // Allow mv_steps to correspond to twice the max mv magnitude found
3713 // in the previous frame, capped by the default max_mv_magnitude based
3714 // on resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003715 cpi->mv_step_param = av1_init_search_range(
3716 AOMMIN(max_mv_def, 2 * cpi->max_mv_magnitude));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003717 }
3718 cpi->max_mv_magnitude = 0;
3719 }
3720 }
3721}
3722
Yaowu Xuf883b422016-08-30 14:01:10 -07003723static void set_size_independent_vars(AV1_COMP *cpi) {
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003724#if CONFIG_GLOBAL_MOTION
3725 int i;
3726 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3727 set_default_gmparams(&cpi->common.global_motion[i]);
3728 }
3729 cpi->global_motion_search_done = 0;
3730#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07003731 av1_set_speed_features_framesize_independent(cpi);
3732 av1_set_rd_speed_thresholds(cpi);
3733 av1_set_rd_speed_thresholds_sub8x8(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003734 cpi->common.interp_filter = cpi->sf.default_interp_filter;
3735}
3736
Yaowu Xuf883b422016-08-30 14:01:10 -07003737static void set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003738 int *top_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003739 AV1_COMMON *const cm = &cpi->common;
3740 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003741
3742 // Setup variables that depend on the dimensions of the frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07003743 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003744
3745 // Decide q and q bounds.
Yaowu Xuf883b422016-08-30 14:01:10 -07003746 *q = av1_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003747
3748 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003749 av1_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003750 }
3751
3752 // Configure experimental use of segmentation for enhanced coding of
3753 // static regions if indicated.
3754 // Only allowed in the second pass of a two pass encode, as it requires
3755 // lagged coding, and if the relevant speed feature flag is set.
3756 if (oxcf->pass == 2 && cpi->sf.static_segmentation)
3757 configure_static_seg_features(cpi);
3758}
3759
Yaowu Xuf883b422016-08-30 14:01:10 -07003760static void init_motion_estimation(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003761 int y_stride = cpi->scaled_source.y_stride;
3762
3763 if (cpi->sf.mv.search_method == NSTEP) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003764 av1_init3smotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003765 } else if (cpi->sf.mv.search_method == DIAMOND) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003766 av1_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003767 }
3768}
3769
Yaowu Xuf883b422016-08-30 14:01:10 -07003770static void set_frame_size(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003771 int ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003772 AV1_COMMON *const cm = &cpi->common;
3773 AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003774 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
3775
Yaowu Xuf883b422016-08-30 14:01:10 -07003776 if (oxcf->pass == 2 && oxcf->rc_mode == AOM_VBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003777 ((oxcf->resize_mode == RESIZE_FIXED && cm->current_video_frame == 0) ||
3778 (oxcf->resize_mode == RESIZE_DYNAMIC && cpi->resize_pending))) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003779 av1_calculate_coded_size(cpi, &oxcf->scaled_frame_width,
3780 &oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003781
3782 // There has been a change in frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003783 av1_set_size_literal(cpi, oxcf->scaled_frame_width,
3784 oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003785 }
3786
Yaowu Xuf883b422016-08-30 14:01:10 -07003787 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003788 oxcf->resize_mode == RESIZE_DYNAMIC) {
3789 if (cpi->resize_pending == 1) {
3790 oxcf->scaled_frame_width =
3791 (cm->width * cpi->resize_scale_num) / cpi->resize_scale_den;
3792 oxcf->scaled_frame_height =
3793 (cm->height * cpi->resize_scale_num) / cpi->resize_scale_den;
3794 } else if (cpi->resize_pending == -1) {
3795 // Go back up to original size.
3796 oxcf->scaled_frame_width = oxcf->width;
3797 oxcf->scaled_frame_height = oxcf->height;
3798 }
3799 if (cpi->resize_pending != 0) {
3800 // There has been a change in frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003801 av1_set_size_literal(cpi, oxcf->scaled_frame_width,
3802 oxcf->scaled_frame_height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003803
3804 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
3805 set_mv_search_params(cpi);
3806 }
3807 }
3808
3809 if (oxcf->pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003810 av1_set_target_rate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003811 }
3812
3813 alloc_frame_mvs(cm, cm->new_fb_idx);
3814
3815 // Reset the frame pointers to the current frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003816 if (aom_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003817 cm->subsampling_x, cm->subsampling_y,
Yaowu Xuf883b422016-08-30 14:01:10 -07003818#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003819 cm->use_highbitdepth,
3820#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003821 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
3822 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003823 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003824 "Failed to allocate frame buffer");
3825
3826 alloc_util_frame_buffers(cpi);
3827 init_motion_estimation(cpi);
3828
3829 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3830 RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - LAST_FRAME];
3831 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3832
3833 ref_buf->idx = buf_idx;
3834
3835 if (buf_idx != INVALID_IDX) {
3836 YV12_BUFFER_CONFIG *const buf = &cm->buffer_pool->frame_bufs[buf_idx].buf;
3837 ref_buf->buf = buf;
Yaowu Xuf883b422016-08-30 14:01:10 -07003838#if CONFIG_AOM_HIGHBITDEPTH
3839 av1_setup_scale_factors_for_frame(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003840 &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width,
3841 cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0);
3842#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003843 av1_setup_scale_factors_for_frame(&ref_buf->sf, buf->y_crop_width,
3844 buf->y_crop_height, cm->width,
3845 cm->height);
3846#endif // CONFIG_AOM_HIGHBITDEPTH
3847 if (av1_is_scaled(&ref_buf->sf)) aom_extend_frame_borders(buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003848 } else {
3849 ref_buf->buf = NULL;
3850 }
3851 }
3852
3853 set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
3854}
3855
Yaowu Xuf883b422016-08-30 14:01:10 -07003856static void reset_use_upsampled_references(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857 MV_REFERENCE_FRAME ref_frame;
3858
3859 // reset up-sampled reference buffer structure.
3860 init_upsampled_ref_frame_bufs(cpi);
3861
3862 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3863 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, ref_frame);
3864 int new_uidx = upsample_ref_frame(cpi, ref);
3865
3866 // Update the up-sampled reference index.
3867 cpi->upsampled_ref_idx[get_ref_frame_map_idx(cpi, ref_frame)] = new_uidx;
3868 cpi->upsampled_ref_bufs[new_uidx].ref_count++;
3869 }
3870}
3871
Yaowu Xuf883b422016-08-30 14:01:10 -07003872static void encode_without_recode_loop(AV1_COMP *cpi) {
3873 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003874 int q = 0, bottom_index = 0, top_index = 0; // Dummy variables.
3875 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3876
Yaowu Xuf883b422016-08-30 14:01:10 -07003877 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003878
3879 set_frame_size(cpi);
3880
3881 // For 1 pass CBR under dynamic resize mode: use faster scaling for source.
3882 // Only for 2x2 scaling for now.
Yaowu Xuf883b422016-08-30 14:01:10 -07003883 if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07003884 cpi->oxcf.resize_mode == RESIZE_DYNAMIC &&
3885 cpi->un_scaled_source->y_width == (cm->width << 1) &&
3886 cpi->un_scaled_source->y_height == (cm->height << 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003887 cpi->Source = av1_scale_if_required_fast(cm, cpi->un_scaled_source,
3888 &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003889 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07003890 cpi->Last_Source = av1_scale_if_required_fast(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003891 cm, cpi->unscaled_last_source, &cpi->scaled_last_source);
3892 } else {
3893 cpi->Source =
Yaowu Xuf883b422016-08-30 14:01:10 -07003894 av1_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003895 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07003896 cpi->Last_Source = av1_scale_if_required(cm, cpi->unscaled_last_source,
3897 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003898 }
3899
3900 if (frame_is_intra_only(cm) == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003901 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003902 }
3903
3904 set_size_independent_vars(cpi);
3905 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3906
3907 // cpi->sf.use_upsampled_references can be different from frame to frame.
3908 // Every time when cpi->sf.use_upsampled_references is changed from 0 to 1.
3909 // The reference frames for this frame have to be up-sampled before encoding.
3910 if (!use_upsampled_ref && cpi->sf.use_upsampled_references)
3911 reset_use_upsampled_references(cpi);
3912
Yaowu Xuf883b422016-08-30 14:01:10 -07003913 av1_set_quantizer(cm, q);
3914 av1_set_variance_partition_thresholds(cpi, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003915
3916 setup_frame(cpi);
3917
3918#if CONFIG_ENTROPY
3919 cm->do_subframe_update = cm->tile_cols == 1 && cm->tile_rows == 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07003920 av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
3921 av1_copy(cpi->subframe_stats.enc_starting_coef_probs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003922 cm->coef_probs_update_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07003923 av1_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003924#endif // CONFIG_ENTROPY
3925
3926 suppress_active_map(cpi);
3927 // Variance adaptive and in frame q adjustment experiments are mutually
3928 // exclusive.
3929 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003930 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003931 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003932 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003933 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003934 av1_cyclic_refresh_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003935 }
3936 apply_active_map(cpi);
3937
3938 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07003939 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003940
3941 // Update some stats from cyclic refresh, and check if we should not update
3942 // golden reference, for 1 pass CBR.
3943 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->frame_type != KEY_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -07003944 (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR))
3945 av1_cyclic_refresh_check_golden_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003946
3947 // Update the skip mb flag probabilities based on the distribution
3948 // seen in the last encoder iteration.
3949 // update_base_skip_probs(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003950 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003951}
3952
Yaowu Xuf883b422016-08-30 14:01:10 -07003953static void encode_with_recode_loop(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003954 uint8_t *dest) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003955 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003956 RATE_CONTROL *const rc = &cpi->rc;
3957 int bottom_index, top_index;
3958 int loop_count = 0;
3959 int loop_at_this_size = 0;
3960 int loop = 0;
3961 int overshoot_seen = 0;
3962 int undershoot_seen = 0;
3963 int frame_over_shoot_limit;
3964 int frame_under_shoot_limit;
3965 int q = 0, q_low = 0, q_high = 0;
3966 const int use_upsampled_ref = cpi->sf.use_upsampled_references;
3967
3968 set_size_independent_vars(cpi);
3969
Yaowu Xuc27fc142016-08-22 16:08:15 -07003970 do {
Yaowu Xuf883b422016-08-30 14:01:10 -07003971 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003972
3973 set_frame_size(cpi);
3974
3975 if (loop_count == 0 || cpi->resize_pending != 0) {
3976 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3977
Thomas Daede919bd6a2016-10-24 16:31:05 -07003978 // cpi->sf.use_upsampled_references can be different from frame to frame.
3979 // Every time when cpi->sf.use_upsampled_references is changed from 0 to
3980 // 1.
3981 // The reference frames for this frame have to be up-sampled before
3982 // encoding.
3983 if (!use_upsampled_ref && cpi->sf.use_upsampled_references)
3984 reset_use_upsampled_references(cpi);
3985
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
3987 set_mv_search_params(cpi);
3988
3989 // Reset the loop state for new frame size.
3990 overshoot_seen = 0;
3991 undershoot_seen = 0;
3992
3993 // Reconfiguration for change in frame size has concluded.
3994 cpi->resize_pending = 0;
3995
3996 q_low = bottom_index;
3997 q_high = top_index;
3998
3999 loop_at_this_size = 0;
4000 }
4001
4002 // Decide frame size bounds first time through.
4003 if (loop_count == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004004 av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
4005 &frame_under_shoot_limit,
4006 &frame_over_shoot_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004007 }
4008
4009 cpi->Source =
Yaowu Xuf883b422016-08-30 14:01:10 -07004010 av1_scale_if_required(cm, cpi->un_scaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004011
4012 if (cpi->unscaled_last_source != NULL)
Yaowu Xuf883b422016-08-30 14:01:10 -07004013 cpi->Last_Source = av1_scale_if_required(cm, cpi->unscaled_last_source,
4014 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004015
4016 if (frame_is_intra_only(cm) == 0) {
4017 if (loop_count > 0) {
4018 release_scaled_references(cpi);
4019 }
Yaowu Xuf883b422016-08-30 14:01:10 -07004020 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004021 }
4022
Yaowu Xuf883b422016-08-30 14:01:10 -07004023 av1_set_quantizer(cm, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004024
4025 if (loop_count == 0) setup_frame(cpi);
4026
4027#if CONFIG_ENTROPY
4028 // Base q-index may have changed, so we need to assign proper default coef
4029 // probs before every iteration.
4030 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
4031 int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07004032 av1_default_coef_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004033 if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
4034 cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
4035 for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
4036 } else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
4037 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
4038 }
4039 }
4040#endif // CONFIG_ENTROPY
4041
4042#if CONFIG_ENTROPY
4043 cm->do_subframe_update = cm->tile_cols == 1 && cm->tile_rows == 1;
4044 if (loop_count == 0 || frame_is_intra_only(cm) ||
4045 cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004046 av1_copy(cm->starting_coef_probs, cm->fc->coef_probs);
4047 av1_copy(cpi->subframe_stats.enc_starting_coef_probs, cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004048 } else {
4049 if (cm->do_subframe_update) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004050 av1_copy(cm->fc->coef_probs,
4051 cpi->subframe_stats.enc_starting_coef_probs);
4052 av1_copy(cm->starting_coef_probs,
4053 cpi->subframe_stats.enc_starting_coef_probs);
4054 av1_zero(cpi->subframe_stats.coef_counts_buf);
4055 av1_zero(cpi->subframe_stats.eob_counts_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004056 }
4057 }
4058 cm->coef_probs_update_idx = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07004059 av1_copy(cpi->subframe_stats.coef_probs_buf[0], cm->fc->coef_probs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004060#endif // CONFIG_ENTROPY
4061
4062 // Variance adaptive and in frame q adjustment experiments are mutually
4063 // exclusive.
4064 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004065 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004066 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004067 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004068 }
4069
4070 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07004071 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004072
4073 // Update the skip mb flag probabilities based on the distribution
4074 // seen in the last encoder iteration.
4075 // update_base_skip_probs(cpi);
4076
Yaowu Xuf883b422016-08-30 14:01:10 -07004077 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004078
4079 // Dummy pack of the bitstream using up to date stats to get an
4080 // accurate estimate of output frame size to determine if we need
4081 // to recode.
4082 if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
4083 save_coding_context(cpi);
4084
Yaowu Xuf883b422016-08-30 14:01:10 -07004085 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004086
4087 rc->projected_frame_size = (int)(*size) << 3;
4088 restore_coding_context(cpi);
4089
4090 if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
4091 }
4092
Yaowu Xuf883b422016-08-30 14:01:10 -07004093 if (cpi->oxcf.rc_mode == AOM_Q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004094 loop = 0;
4095 } else {
4096 if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced &&
4097 (rc->projected_frame_size < rc->max_frame_bandwidth)) {
4098 int last_q = q;
4099 int64_t kf_err;
4100
4101 int64_t high_err_target = cpi->ambient_err;
4102 int64_t low_err_target = cpi->ambient_err >> 1;
4103
Yaowu Xuf883b422016-08-30 14:01:10 -07004104#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105 if (cm->use_highbitdepth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004106 kf_err = aom_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004107 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004108 kf_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004109 }
4110#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004111 kf_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4112#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004113
4114 // Prevent possible divide by zero error below for perfect KF
4115 kf_err += !kf_err;
4116
4117 // The key frame is not good enough or we can afford
4118 // to make it better without undue risk of popping.
4119 if ((kf_err > high_err_target &&
4120 rc->projected_frame_size <= frame_over_shoot_limit) ||
4121 (kf_err > low_err_target &&
4122 rc->projected_frame_size <= frame_under_shoot_limit)) {
4123 // Lower q_high
4124 q_high = q > q_low ? q - 1 : q_low;
4125
4126 // Adjust Q
4127 q = (int)((q * high_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004128 q = AOMMIN(q, (q_high + q_low) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004129 } else if (kf_err < low_err_target &&
4130 rc->projected_frame_size >= frame_under_shoot_limit) {
4131 // The key frame is much better than the previous frame
4132 // Raise q_low
4133 q_low = q < q_high ? q + 1 : q_high;
4134
4135 // Adjust Q
4136 q = (int)((q * low_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004137 q = AOMMIN(q, (q_high + q_low + 1) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004138 }
4139
4140 // Clamp Q to upper and lower limits:
4141 q = clamp(q, q_low, q_high);
4142
4143 loop = q != last_q;
4144 } else if (recode_loop_test(cpi, frame_over_shoot_limit,
4145 frame_under_shoot_limit, q,
Yaowu Xuf883b422016-08-30 14:01:10 -07004146 AOMMAX(q_high, top_index), bottom_index)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004147 // Is the projected frame size out of range and are we allowed
4148 // to attempt to recode.
4149 int last_q = q;
4150 int retries = 0;
4151
4152 if (cpi->resize_pending == 1) {
4153 // Change in frame size so go back around the recode loop.
4154 cpi->rc.frame_size_selector =
4155 SCALE_STEP1 - cpi->rc.frame_size_selector;
4156 cpi->rc.next_frame_size_selector = cpi->rc.frame_size_selector;
4157
4158#if CONFIG_INTERNAL_STATS
4159 ++cpi->tot_recode_hits;
4160#endif
4161 ++loop_count;
4162 loop = 1;
4163 continue;
4164 }
4165
4166 // Frame size out of permitted range:
4167 // Update correction factor & compute new Q to try...
4168
4169 // Frame is too large
4170 if (rc->projected_frame_size > rc->this_frame_target) {
4171 // Special case if the projected size is > the max allowed.
4172 if (rc->projected_frame_size >= rc->max_frame_bandwidth)
4173 q_high = rc->worst_quality;
4174
4175 // Raise Qlow as to at least the current value
4176 q_low = q < q_high ? q + 1 : q_high;
4177
4178 if (undershoot_seen || loop_at_this_size > 1) {
4179 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004180 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004181
4182 q = (q_high + q_low + 1) / 2;
4183 } else {
4184 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004185 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004186
Yaowu Xuf883b422016-08-30 14:01:10 -07004187 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4188 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004189
4190 while (q < q_low && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004191 av1_rc_update_rate_correction_factors(cpi);
4192 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4193 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004194 retries++;
4195 }
4196 }
4197
4198 overshoot_seen = 1;
4199 } else {
4200 // Frame is too small
4201 q_high = q > q_low ? q - 1 : q_low;
4202
4203 if (overshoot_seen || loop_at_this_size > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004204 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004205 q = (q_high + q_low) / 2;
4206 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004207 av1_rc_update_rate_correction_factors(cpi);
4208 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4209 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004210 // Special case reset for qlow for constrained quality.
4211 // This should only trigger where there is very substantial
4212 // undershoot on a frame and the auto cq level is above
4213 // the user passsed in value.
Yaowu Xuf883b422016-08-30 14:01:10 -07004214 if (cpi->oxcf.rc_mode == AOM_CQ && q < q_low) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004215 q_low = q;
4216 }
4217
4218 while (q > q_high && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004219 av1_rc_update_rate_correction_factors(cpi);
4220 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4221 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004222 retries++;
4223 }
4224 }
4225
4226 undershoot_seen = 1;
4227 }
4228
4229 // Clamp Q to upper and lower limits:
4230 q = clamp(q, q_low, q_high);
4231
4232 loop = (q != last_q);
4233 } else {
4234 loop = 0;
4235 }
4236 }
4237
4238 // Special case for overlay frame.
4239 if (rc->is_src_frame_alt_ref &&
4240 rc->projected_frame_size < rc->max_frame_bandwidth)
4241 loop = 0;
4242
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004243#if CONFIG_GLOBAL_MOTION
4244 if (recode_loop_test_global_motion(cpi)) {
4245 loop = 1;
4246 }
4247#endif // CONFIG_GLOBAL_MOTION
4248
Yaowu Xuc27fc142016-08-22 16:08:15 -07004249 if (loop) {
4250 ++loop_count;
4251 ++loop_at_this_size;
4252
4253#if CONFIG_INTERNAL_STATS
4254 ++cpi->tot_recode_hits;
4255#endif
4256 }
4257 } while (loop);
4258}
4259
Yaowu Xuf883b422016-08-30 14:01:10 -07004260static int get_ref_frame_flags(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004261 const int *const map = cpi->common.ref_frame_map;
4262
4263#if CONFIG_EXT_REFS
4264 const int last2_is_last =
4265 map[cpi->lst_fb_idxes[1]] == map[cpi->lst_fb_idxes[0]];
4266 const int last3_is_last =
4267 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[0]];
4268 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[0]];
4269 const int bwd_is_last = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[0]];
4270 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[0]];
4271
4272 const int last3_is_last2 =
4273 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[1]];
4274 const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[1]];
4275 const int bwd_is_last2 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[1]];
4276
4277 const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[2]];
4278 const int bwd_is_last3 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[2]];
4279
4280 const int bwd_is_gld = map[cpi->bwd_fb_idx] == map[cpi->gld_fb_idx];
4281
4282 const int last2_is_alt = map[cpi->lst_fb_idxes[1]] == map[cpi->alt_fb_idx];
4283 const int last3_is_alt = map[cpi->lst_fb_idxes[2]] == map[cpi->alt_fb_idx];
4284 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4285 const int bwd_is_alt = map[cpi->bwd_fb_idx] == map[cpi->alt_fb_idx];
4286#else
4287 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
4288 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4289 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
4290#endif // CONFIG_EXT_REFS
4291
Yaowu Xuf883b422016-08-30 14:01:10 -07004292 int flags = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004293
4294#if CONFIG_EXT_REFS
4295 // Disable the use of BWDREF_FRAME for non-bipredictive frames.
4296 if (!(cpi->rc.is_bipred_frame || cpi->rc.is_last_bipred_frame ||
4297 (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs)))
Yaowu Xuf883b422016-08-30 14:01:10 -07004298 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004299#endif // CONFIG_EXT_REFS
4300
Yaowu Xuf883b422016-08-30 14:01:10 -07004301 if (gld_is_last || gld_is_alt) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004302
Yaowu Xuf883b422016-08-30 14:01:10 -07004303 if (cpi->rc.frames_till_gf_update_due == INT_MAX) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004304
Yaowu Xuf883b422016-08-30 14:01:10 -07004305 if (alt_is_last) flags &= ~AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004306
4307#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004308 if (last2_is_last || last2_is_alt) flags &= ~AOM_LAST2_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004309
Yaowu Xuf883b422016-08-30 14:01:10 -07004310 if (last3_is_last || last3_is_last2 || last3_is_alt) flags &= ~AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004311
Yaowu Xuf883b422016-08-30 14:01:10 -07004312 if (gld_is_last2 || gld_is_last3) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004313
4314 if ((bwd_is_last || bwd_is_last2 || bwd_is_last3 || bwd_is_gld ||
4315 bwd_is_alt) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07004316 (flags & AOM_BWD_FLAG))
4317 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004318#endif // CONFIG_EXT_REFS
4319
4320 return flags;
4321}
4322
Yaowu Xuf883b422016-08-30 14:01:10 -07004323static void set_ext_overrides(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004324 // Overrides the defaults with the externally supplied values with
Yaowu Xuf883b422016-08-30 14:01:10 -07004325 // av1_update_reference() and av1_update_entropy() calls
Yaowu Xuc27fc142016-08-22 16:08:15 -07004326 // Note: The overrides are valid only for the next frame passed
4327 // to encode_frame_to_data_rate() function
4328 if (cpi->ext_refresh_frame_context_pending) {
4329 cpi->common.refresh_frame_context = cpi->ext_refresh_frame_context;
4330 cpi->ext_refresh_frame_context_pending = 0;
4331 }
4332 if (cpi->ext_refresh_frame_flags_pending) {
4333 cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
4334 cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
4335 cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
4336 cpi->ext_refresh_frame_flags_pending = 0;
4337 }
4338}
4339
Yaowu Xuf883b422016-08-30 14:01:10 -07004340YV12_BUFFER_CONFIG *av1_scale_if_required_fast(AV1_COMMON *cm,
4341 YV12_BUFFER_CONFIG *unscaled,
4342 YV12_BUFFER_CONFIG *scaled) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004343 if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4344 cm->mi_rows * MI_SIZE != unscaled->y_height) {
4345 // For 2x2 scaling down.
Yaowu Xuf883b422016-08-30 14:01:10 -07004346 aom_scale_frame(unscaled, scaled, unscaled->y_buffer, 9, 2, 1, 2, 1, 0);
4347 aom_extend_frame_borders(scaled);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004348 return scaled;
4349 } else {
4350 return unscaled;
4351 }
4352}
4353
Yaowu Xuf883b422016-08-30 14:01:10 -07004354YV12_BUFFER_CONFIG *av1_scale_if_required(AV1_COMMON *cm,
4355 YV12_BUFFER_CONFIG *unscaled,
4356 YV12_BUFFER_CONFIG *scaled) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004357 if (cm->mi_cols * MI_SIZE != unscaled->y_width ||
4358 cm->mi_rows * MI_SIZE != unscaled->y_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004359#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004360 scale_and_extend_frame_nonnormative(unscaled, scaled, (int)cm->bit_depth);
4361#else
4362 scale_and_extend_frame_nonnormative(unscaled, scaled);
Yaowu Xuf883b422016-08-30 14:01:10 -07004363#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004364 return scaled;
4365 } else {
4366 return unscaled;
4367 }
4368}
4369
Yaowu Xuf883b422016-08-30 14:01:10 -07004370static void set_arf_sign_bias(AV1_COMP *cpi) {
4371 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004372 int arf_sign_bias;
4373#if CONFIG_EXT_REFS
4374 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4375 // The arf_sign_bias will be one for internal ARFs'
4376 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4377 (!cpi->refresh_alt_ref_frame ||
4378 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4379#else
4380 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
4381 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4382 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4383 (!cpi->refresh_alt_ref_frame ||
4384 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4385 } else {
4386 arf_sign_bias =
4387 (cpi->rc.source_alt_ref_active && !cpi->refresh_alt_ref_frame);
4388 }
Zoe Liu6cfaff92016-10-18 17:12:11 -07004389#endif // CONFIG_EXT_REFS
4390
Yaowu Xuc27fc142016-08-22 16:08:15 -07004391 cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
4392#if CONFIG_EXT_REFS
4393 cm->ref_frame_sign_bias[BWDREF_FRAME] = cm->ref_frame_sign_bias[ALTREF_FRAME];
4394#endif // CONFIG_EXT_REFS
4395}
4396
Yaowu Xuf883b422016-08-30 14:01:10 -07004397static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
James Zern7b9407a2016-05-18 23:48:05 -07004398 InterpFilter ifilter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004399 int ref_total[TOTAL_REFS_PER_FRAME] = { 0 };
4400 MV_REFERENCE_FRAME ref;
4401 int mask = 0;
4402 int arf_idx = ALTREF_FRAME;
4403
4404#if CONFIG_EXT_REFS
4405 // Get which arf used as ALTREF_FRAME
4406 if (cpi->oxcf.pass == 2)
4407 arf_idx += cpi->twopass.gf_group.arf_ref_idx[cpi->twopass.gf_group.index];
Zoe Liu6cfaff92016-10-18 17:12:11 -07004408#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004409
4410 if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
4411 return mask;
4412
4413#if CONFIG_EXT_REFS
4414 for (ref = LAST_FRAME; ref < ALTREF_FRAME; ++ref)
4415 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4416 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
4417
4418 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4419 ref_total[ref] += cpi->interp_filter_selected[arf_idx][ifilter];
4420#else
4421 for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
4422 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4423 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
Zoe Liu6cfaff92016-10-18 17:12:11 -07004424#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004425
4426 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter) {
4427 if ((ref_total[LAST_FRAME] &&
4428 cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
4429#if CONFIG_EXT_REFS
4430 (ref_total[LAST2_FRAME] == 0 ||
4431 cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 50 <
4432 ref_total[LAST2_FRAME]) &&
4433 (ref_total[LAST3_FRAME] == 0 ||
4434 cpi->interp_filter_selected[LAST3_FRAME][ifilter] * 50 <
4435 ref_total[LAST3_FRAME]) &&
4436#endif // CONFIG_EXT_REFS
4437 (ref_total[GOLDEN_FRAME] == 0 ||
4438 cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50 <
4439 ref_total[GOLDEN_FRAME]) &&
4440#if CONFIG_EXT_REFS
4441 (ref_total[BWDREF_FRAME] == 0 ||
4442 cpi->interp_filter_selected[BWDREF_FRAME][ifilter] * 50 <
4443 ref_total[BWDREF_FRAME]) &&
4444#endif // CONFIG_EXT_REFS
4445 (ref_total[ALTREF_FRAME] == 0 ||
4446 cpi->interp_filter_selected[arf_idx][ifilter] * 50 <
4447 ref_total[ALTREF_FRAME]))
4448 mask |= 1 << ifilter;
4449 }
4450 return mask;
4451}
4452
4453#define DUMP_RECON_FRAMES 0
4454
4455#if DUMP_RECON_FRAMES == 1
4456// NOTE(zoeliu): For debug - Output the filtered reconstructed video.
Yaowu Xuf883b422016-08-30 14:01:10 -07004457static void dump_filtered_recon_frames(AV1_COMP *cpi) {
4458 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004459 const YV12_BUFFER_CONFIG *recon_buf = cm->frame_to_show;
4460 int h;
4461 char file_name[256] = "/tmp/enc_filtered_recon.yuv";
4462 FILE *f_recon = NULL;
4463
4464 if (recon_buf == NULL || !cm->show_frame) {
4465 printf("Frame %d is not ready or no show to dump.\n",
4466 cm->current_video_frame);
4467 return;
4468 }
4469
4470 if (cm->current_video_frame == 0) {
4471 if ((f_recon = fopen(file_name, "wb")) == NULL) {
4472 printf("Unable to open file %s to write.\n", file_name);
4473 return;
4474 }
4475 } else {
4476 if ((f_recon = fopen(file_name, "ab")) == NULL) {
4477 printf("Unable to open file %s to append.\n", file_name);
4478 return;
4479 }
4480 }
4481 printf(
4482 "\nFrame=%5d, encode_update_type[%5d]=%1d, show_existing_frame=%d, "
4483 "y_stride=%4d, uv_stride=%4d, width=%4d, height=%4d\n",
4484 cm->current_video_frame, cpi->twopass.gf_group.index,
4485 cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
4486 cm->show_existing_frame, recon_buf->y_stride, recon_buf->uv_stride,
4487 cm->width, cm->height);
4488
4489 // --- Y ---
4490 for (h = 0; h < cm->height; ++h) {
4491 fwrite(&recon_buf->y_buffer[h * recon_buf->y_stride], 1, cm->width,
4492 f_recon);
4493 }
4494 // --- U ---
4495 for (h = 0; h < (cm->height >> 1); ++h) {
4496 fwrite(&recon_buf->u_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4497 f_recon);
4498 }
4499 // --- V ---
4500 for (h = 0; h < (cm->height >> 1); ++h) {
4501 fwrite(&recon_buf->v_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4502 f_recon);
4503 }
4504
4505 fclose(f_recon);
4506}
4507#endif // DUMP_RECON_FRAMES
4508
Yaowu Xuf883b422016-08-30 14:01:10 -07004509static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004510 uint8_t *dest,
4511 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004512 AV1_COMMON *const cm = &cpi->common;
4513 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004514 struct segmentation *const seg = &cm->seg;
4515 TX_SIZE t;
4516 set_ext_overrides(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004517 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004518
4519 // Set the arf sign bias for this frame.
4520 set_arf_sign_bias(cpi);
4521
4522#if CONFIG_EXT_REFS
4523 // NOTE:
4524 // (1) Move the setup of the ref_frame_flags upfront as it would be
4525 // determined by the current frame properties;
4526 // (2) The setup of the ref_frame_flags applies to both show_existing_frame's
4527 // and the other cases.
4528 if (cm->current_video_frame > 0)
4529 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4530
4531 if (cm->show_existing_frame) {
4532 // NOTE(zoeliu): In BIDIR_PRED, the existing frame to show is the current
4533 // BWDREF_FRAME in the reference frame buffer.
4534 cm->frame_type = INTER_FRAME;
4535 cm->show_frame = 1;
4536 cpi->frame_flags = *frame_flags;
4537
4538 // In the case of show_existing frame, we will not send fresh flag
4539 // to decoder. Any change in the reference frame buffer can be done by
4540 // switching the virtual indices.
4541
4542 cpi->refresh_last_frame = 0;
4543 cpi->refresh_golden_frame = 0;
4544 cpi->refresh_bwd_ref_frame = 0;
4545 cpi->refresh_alt_ref_frame = 0;
4546
4547 cpi->rc.is_bwd_ref_frame = 0;
4548 cpi->rc.is_last_bipred_frame = 0;
4549 cpi->rc.is_bipred_frame = 0;
4550
4551 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004552 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004553
4554 // Set up frame to show to get ready for stats collection.
4555 cm->frame_to_show = get_frame_new_buffer(cm);
4556
4557#if DUMP_RECON_FRAMES == 1
4558 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4559 dump_filtered_recon_frames(cpi);
4560#endif // DUMP_RECON_FRAMES
4561
4562 // Update the LAST_FRAME in the reference frame buffer.
Yaowu Xuf883b422016-08-30 14:01:10 -07004563 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004564
4565 // Update frame flags
4566 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4567 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4568 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4569
4570 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4571
4572 // Update the frame type
4573 cm->last_frame_type = cm->frame_type;
4574
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575 // Since we allocate a spot for the OVERLAY frame in the gf group, we need
4576 // to do post-encoding update accordingly.
4577 if (cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004578 av1_set_target_rate(cpi);
4579 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004580 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004581
4582 cm->last_width = cm->width;
4583 cm->last_height = cm->height;
4584
4585 ++cm->current_video_frame;
4586
4587 return;
4588 }
4589#endif // CONFIG_EXT_REFS
4590
4591 // Set default state for segment based loop filter update flags.
4592 cm->lf.mode_ref_delta_update = 0;
4593
4594 if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search)
4595 cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi);
4596
4597 // Set various flags etc to special state if it is a key frame.
4598 if (frame_is_intra_only(cm)) {
4599 // Reset the loop filter deltas and segmentation map.
Yaowu Xuf883b422016-08-30 14:01:10 -07004600 av1_reset_segment_features(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004601
4602 // If segmentation is enabled force a map update for key frames.
4603 if (seg->enabled) {
4604 seg->update_map = 1;
4605 seg->update_data = 1;
4606 }
4607
4608 // The alternate reference frame cannot be active for a key frame.
4609 cpi->rc.source_alt_ref_active = 0;
4610
4611 cm->error_resilient_mode = oxcf->error_resilient_mode;
4612
4613 // By default, encoder assumes decoder can use prev_mi.
4614 if (cm->error_resilient_mode) {
4615 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
4616 cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_FORWARD;
4617 } else if (cm->intra_only) {
4618 // Only reset the current context.
4619 cm->reset_frame_context = RESET_FRAME_CONTEXT_CURRENT;
4620 }
4621 }
Thomas Davies80188d12016-10-26 16:08:35 -07004622#if CONFIG_TILE_GROUPS
Thomas Daviesaf6df172016-11-09 14:04:18 +00004623 if (cpi->oxcf.mtu == 0) {
4624 cm->num_tg = cpi->oxcf.num_tile_groups;
4625 } else {
Yaowu Xu859a5272016-11-10 15:32:21 -08004626 // Use a default value for the purposes of weighting costs in probability
4627 // updates
Thomas Daviesaf6df172016-11-09 14:04:18 +00004628 cm->num_tg = DEFAULT_MAX_NUM_TG;
4629 }
Thomas Davies80188d12016-10-26 16:08:35 -07004630#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004631
4632 // For 1 pass CBR, check if we are dropping this frame.
4633 // Never drop on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004634 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004635 cm->frame_type != KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004636 if (av1_rc_drop_frame(cpi)) {
4637 av1_rc_postencode_update_drop_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004638 ++cm->current_video_frame;
4639 return;
4640 }
4641 }
4642
Yaowu Xuf883b422016-08-30 14:01:10 -07004643 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004644
4645#if CONFIG_INTERNAL_STATS
4646 memset(cpi->mode_chosen_counts, 0,
4647 MAX_MODES * sizeof(*cpi->mode_chosen_counts));
4648#endif
4649
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004650#if CONFIG_REFERENCE_BUFFER
4651 {
4652 /* Non-normative definition of current_frame_id ("frame counter" with
4653 * wraparound) */
4654 int FidLen = FRAME_ID_LENGTH_MINUS7 + 7;
4655 if (cm->current_frame_id == -1) {
Arild Fuldseth (arilfuld)bac17c12016-12-02 12:01:06 +01004656/* quasi-random initialization of current_frame_id for a key frame */
4657#if CONFIG_AOM_HIGHBITDEPTH
4658 int lsb = CONVERT_TO_SHORTPTR(cpi->Source->y_buffer)[0] & 0xff;
4659 int msb = CONVERT_TO_SHORTPTR(cpi->Source->y_buffer)[1] & 0xff;
4660#else
4661 int lsb = cpi->Source->y_buffer[0];
4662 int msb = cpi->Source->y_buffer[1];
4663#endif
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004664 cm->current_frame_id = ((msb << 8) + lsb) % (1 << FidLen);
4665 } else {
4666 cm->current_frame_id =
4667 (cm->current_frame_id + 1 + (1 << FidLen)) % (1 << FidLen);
4668 }
4669 }
4670#endif
4671
Yaowu Xuc27fc142016-08-22 16:08:15 -07004672 if (cpi->sf.recode_loop == DISALLOW_RECODE) {
4673 encode_without_recode_loop(cpi);
4674 } else {
4675 encode_with_recode_loop(cpi, size, dest);
4676 }
4677
4678#ifdef OUTPUT_YUV_SKINMAP
4679 if (cpi->common.current_video_frame > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004680 av1_compute_skin_map(cpi, yuv_skinmap_file);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004681 }
4682#endif // OUTPUT_YUV_SKINMAP
4683
4684 // Special case code to reduce pulsing when key frames are forced at a
4685 // fixed interval. Note the reconstruction error if it is the frame before
4686 // the force key frame
4687 if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004688#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004689 if (cm->use_highbitdepth) {
4690 cpi->ambient_err =
Yaowu Xuf883b422016-08-30 14:01:10 -07004691 aom_highbd_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004692 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004693 cpi->ambient_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004694 }
4695#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004696 cpi->ambient_err = aom_get_y_sse(cpi->Source, get_frame_new_buffer(cm));
4697#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698 }
4699
4700 // If the encoder forced a KEY_FRAME decision
4701 if (cm->frame_type == KEY_FRAME) {
4702 cpi->refresh_last_frame = 1;
4703 }
4704
4705 cm->frame_to_show = get_frame_new_buffer(cm);
4706 cm->frame_to_show->color_space = cm->color_space;
4707 cm->frame_to_show->color_range = cm->color_range;
4708 cm->frame_to_show->render_width = cm->render_width;
4709 cm->frame_to_show->render_height = cm->render_height;
4710
4711#if CONFIG_EXT_REFS
4712// TODO(zoeliu): For non-ref frames, loop filtering may need to be turned
4713// off.
4714#endif // CONFIG_EXT_REFS
4715
4716 // Pick the loop filter level for the frame.
4717 loopfilter_frame(cpi, cm);
4718
4719 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004720 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004721
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004722#if CONFIG_REFERENCE_BUFFER
4723 {
4724 int i;
4725 /* Update reference frame id values based on the value of refresh_mask */
4726 for (i = 0; i < REF_FRAMES; i++) {
4727 if ((cm->refresh_mask >> i) & 1) {
4728 cm->ref_frame_id[i] = cm->current_frame_id;
4729 }
4730 }
4731 }
4732#endif
4733
Yaowu Xuc27fc142016-08-22 16:08:15 -07004734#if DUMP_RECON_FRAMES == 1
4735 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4736 if (cm->show_frame) dump_filtered_recon_frames(cpi);
4737#endif // DUMP_RECON_FRAMES
4738
Steinar Midtskogend06588a2016-05-06 13:48:20 +02004739#if CONFIG_CLPF
4740 aom_free(cm->clpf_blocks);
Steinar Midtskogenf4d41e62016-08-25 12:22:24 +02004741 cm->clpf_blocks = 0;
Steinar Midtskogend06588a2016-05-06 13:48:20 +02004742#endif
4743
Yaowu Xuc27fc142016-08-22 16:08:15 -07004744 if (cm->seg.update_map) update_reference_segmentation_map(cpi);
4745
4746 if (frame_is_intra_only(cm) == 0) {
4747 release_scaled_references(cpi);
4748 }
4749
Yaowu Xuf883b422016-08-30 14:01:10 -07004750 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004751
Debargha Mukherjee153e1f82016-11-17 09:59:14 -08004752 for (t = TX_4X4; t < TX_SIZES; t++)
Yaowu Xuf883b422016-08-30 14:01:10 -07004753 av1_full_to_model_counts(cpi->td.counts->coef[t],
4754 cpi->td.rd_counts.coef_counts[t]);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004755
4756 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
4757#if CONFIG_ENTROPY
4758 cm->partial_prob_update = 0;
4759#endif // CONFIG_ENTROPY
Yaowu Xuf883b422016-08-30 14:01:10 -07004760 av1_adapt_coef_probs(cm);
4761 av1_adapt_intra_frame_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004762 }
4763
4764 if (!frame_is_intra_only(cm)) {
4765 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004766 av1_adapt_inter_frame_probs(cm);
4767 av1_adapt_mv_probs(cm, cm->allow_high_precision_mv);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004768 }
4769 }
4770
4771 if (cpi->refresh_golden_frame == 1)
4772 cpi->frame_flags |= FRAMEFLAGS_GOLDEN;
4773 else
4774 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4775
4776 if (cpi->refresh_alt_ref_frame == 1)
4777 cpi->frame_flags |= FRAMEFLAGS_ALTREF;
4778 else
4779 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4780
4781#if CONFIG_EXT_REFS
4782 if (cpi->refresh_bwd_ref_frame == 1)
4783 cpi->frame_flags |= FRAMEFLAGS_BWDREF;
4784 else
4785 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4786#endif // CONFIG_EXT_REFS
4787
4788#if !CONFIG_EXT_REFS
4789 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4790#endif // !CONFIG_EXT_REFS
4791
Yaowu Xuc27fc142016-08-22 16:08:15 -07004792 cm->last_frame_type = cm->frame_type;
4793
Yaowu Xuf883b422016-08-30 14:01:10 -07004794 av1_rc_postencode_update(cpi, *size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004795
4796#if 0
4797 output_frame_level_debug_stats(cpi);
4798#endif
4799
4800 if (cm->frame_type == KEY_FRAME) {
4801 // Tell the caller that the frame was coded as a key frame
4802 *frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY;
4803 } else {
4804 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4805 }
4806
4807 // Clear the one shot update flags for segmentation map and mode/ref loop
4808 // filter deltas.
4809 cm->seg.update_map = 0;
4810 cm->seg.update_data = 0;
4811 cm->lf.mode_ref_delta_update = 0;
4812
4813 // keep track of the last coded dimensions
4814 cm->last_width = cm->width;
4815 cm->last_height = cm->height;
4816
4817 // reset to normal state now that we are done.
4818 if (!cm->show_existing_frame) cm->last_show_frame = cm->show_frame;
4819
4820 if (cm->show_frame) {
4821#if CONFIG_EXT_REFS
4822// TODO(zoeliu): We may only swamp mi and prev_mi for those frames that are
4823// being used as reference.
4824#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004825 av1_swap_mi_and_prev_mi(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004826 // Don't increment frame counters if this was an altref buffer
4827 // update not a real frame
4828 ++cm->current_video_frame;
4829 }
4830
4831#if CONFIG_EXT_REFS
4832 // NOTE: Shall not refer to any frame not used as reference.
4833 if (cm->is_reference_frame)
4834#endif // CONFIG_EXT_REFS
4835 cm->prev_frame = cm->cur_frame;
4836}
4837
Yaowu Xuf883b422016-08-30 14:01:10 -07004838static void Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004839 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004840 if (cpi->oxcf.rc_mode == AOM_CBR) {
4841 av1_rc_get_one_pass_cbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004842 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004843 av1_rc_get_one_pass_vbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004844 }
4845 encode_frame_to_data_rate(cpi, size, dest, frame_flags);
4846}
4847
Yaowu Xuf883b422016-08-30 14:01:10 -07004848static void Pass2Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004849 unsigned int *frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004850 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) ||
Zoe Liu6cfaff92016-10-18 17:12:11 -07005054#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07005055 (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 }
Zoe Liu6cfaff92016-10-18 17:12:11 -07005422#endif // CONFIG_EXT_REFS
5423
Yaowu Xuc27fc142016-08-22 16:08:15 -07005424 // Start with a 0 size frame.
5425 *size = 0;
5426
5427 cpi->frame_flags = *frame_flags;
5428
5429 if (oxcf->pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005430 av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005431 } else if (oxcf->pass == 1) {
5432 set_frame_size(cpi);
5433 }
5434
5435 if (cpi->oxcf.pass != 0 || frame_is_intra_only(cm) == 1) {
5436 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i)
5437 cpi->scaled_ref_idx[i] = INVALID_IDX;
5438 }
5439
5440#if CONFIG_AOM_QM
5441 cm->using_qmatrix = cpi->oxcf.using_qm;
5442 cm->min_qmlevel = cpi->oxcf.qm_minlevel;
5443 cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
5444#endif
5445
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01005446#if CONFIG_REFERENCE_BUFFER
5447 if (*time_stamp == 0) {
5448 cpi->common.current_frame_id = -1;
5449 }
5450#endif
5451
Yaowu Xuc27fc142016-08-22 16:08:15 -07005452 if (oxcf->pass == 1) {
5453 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07005454 av1_first_pass(cpi, source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005455 } else if (oxcf->pass == 2) {
5456 Pass2Encode(cpi, size, dest, frame_flags);
5457 } else {
5458 // One pass encode
5459 Pass0Encode(cpi, size, dest, frame_flags);
5460 }
5461
5462 if (!cm->error_resilient_mode)
5463 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
5464
5465 // No frame encoded, or frame was dropped, release scaled references.
5466 if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
5467 release_scaled_references(cpi);
5468 }
5469
5470 if (*size > 0) {
5471 cpi->droppable = !frame_is_reference(cpi);
5472 }
5473
Yaowu Xuf883b422016-08-30 14:01:10 -07005474 aom_usec_timer_mark(&cmptimer);
5475 cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005476
5477 if (cpi->b_calculate_psnr && oxcf->pass != 1 && cm->show_frame)
5478 generate_psnr_packet(cpi);
5479
5480#if CONFIG_INTERNAL_STATS
5481 if (oxcf->pass != 1) {
5482 compute_internal_stats(cpi);
5483 cpi->bytes += (int)(*size);
5484 }
5485#endif // CONFIG_INTERNAL_STATS
5486
Yaowu Xuf883b422016-08-30 14:01:10 -07005487 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005488
5489 return 0;
5490}
5491
Yaowu Xuf883b422016-08-30 14:01:10 -07005492int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest) {
5493 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005494 if (!cm->show_frame) {
5495 return -1;
5496 } else {
5497 int ret;
5498 if (cm->frame_to_show) {
5499 *dest = *cm->frame_to_show;
5500 dest->y_width = cm->width;
5501 dest->y_height = cm->height;
5502 dest->uv_width = cm->width >> cm->subsampling_x;
5503 dest->uv_height = cm->height >> cm->subsampling_y;
5504 ret = 0;
5505 } else {
5506 ret = -1;
5507 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005508 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005509 return ret;
5510 }
5511}
5512
Yaowu Xuf883b422016-08-30 14:01:10 -07005513int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005514 if (cpi->last_show_frame_buf_idx == INVALID_IDX) return -1;
5515
5516 *frame =
5517 cpi->common.buffer_pool->frame_bufs[cpi->last_show_frame_buf_idx].buf;
5518 return 0;
5519}
5520
Yaowu Xuf883b422016-08-30 14:01:10 -07005521int av1_set_internal_size(AV1_COMP *cpi, AOM_SCALING horiz_mode,
5522 AOM_SCALING vert_mode) {
5523 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005524 int hr = 0, hs = 0, vr = 0, vs = 0;
5525
5526 if (horiz_mode > ONETWO || vert_mode > ONETWO) return -1;
5527
5528 Scale2Ratio(horiz_mode, &hr, &hs);
5529 Scale2Ratio(vert_mode, &vr, &vs);
5530
5531 // always go to the next whole number
5532 cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs;
5533 cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs;
5534 assert(cm->width <= cpi->initial_width);
5535 assert(cm->height <= cpi->initial_height);
5536
5537 update_frame_size(cpi);
5538
5539 return 0;
5540}
5541
Yaowu Xuf883b422016-08-30 14:01:10 -07005542int av1_set_size_literal(AV1_COMP *cpi, unsigned int width,
5543 unsigned int height) {
5544 AV1_COMMON *cm = &cpi->common;
5545#if CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005546 check_initial_width(cpi, cm->use_highbitdepth, 1, 1);
5547#else
5548 check_initial_width(cpi, 1, 1);
Yaowu Xuf883b422016-08-30 14:01:10 -07005549#endif // CONFIG_AOM_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005550
5551 if (width) {
5552 cm->width = width;
5553 if (cm->width > cpi->initial_width) {
5554 cm->width = cpi->initial_width;
5555 printf("Warning: Desired width too large, changed to %d\n", cm->width);
5556 }
5557 }
5558
5559 if (height) {
5560 cm->height = height;
5561 if (cm->height > cpi->initial_height) {
5562 cm->height = cpi->initial_height;
5563 printf("Warning: Desired height too large, changed to %d\n", cm->height);
5564 }
5565 }
5566 assert(cm->width <= cpi->initial_width);
5567 assert(cm->height <= cpi->initial_height);
5568
5569 update_frame_size(cpi);
5570
5571 return 0;
5572}
5573
Yaowu Xuf883b422016-08-30 14:01:10 -07005574int av1_get_quantizer(AV1_COMP *cpi) { return cpi->common.base_qindex; }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005575
Yaowu Xuf883b422016-08-30 14:01:10 -07005576void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005577 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005578 (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF)) {
5579 int ref = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005580
Yaowu Xuf883b422016-08-30 14:01:10 -07005581 if (flags & AOM_EFLAG_NO_REF_LAST) {
5582 ref ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005583#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005584 ref ^= AOM_LAST2_FLAG;
5585 ref ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005586#endif // CONFIG_EXT_REFS
5587 }
5588
Yaowu Xuf883b422016-08-30 14:01:10 -07005589 if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005590
Yaowu Xuf883b422016-08-30 14:01:10 -07005591 if (flags & AOM_EFLAG_NO_REF_ARF) ref ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005592
Yaowu Xuf883b422016-08-30 14:01:10 -07005593 av1_use_as_reference(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005594 }
5595
5596 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005597 (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
5598 AOM_EFLAG_FORCE_GF | AOM_EFLAG_FORCE_ARF)) {
5599 int upd = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005600
Yaowu Xuf883b422016-08-30 14:01:10 -07005601 if (flags & AOM_EFLAG_NO_UPD_LAST) {
5602 upd ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005603#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005604 upd ^= AOM_LAST2_FLAG;
5605 upd ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005606#endif // CONFIG_EXT_REFS
5607 }
5608
Yaowu Xuf883b422016-08-30 14:01:10 -07005609 if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005610
Yaowu Xuf883b422016-08-30 14:01:10 -07005611 if (flags & AOM_EFLAG_NO_UPD_ARF) upd ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005612
Yaowu Xuf883b422016-08-30 14:01:10 -07005613 av1_update_reference(cpi, upd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005614 }
5615
Yaowu Xuf883b422016-08-30 14:01:10 -07005616 if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
5617 av1_update_entropy(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 }
5619}