blob: 54f4102d11c738e03a96318315eeb25feac57655 [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"
Jean-Marc Valin01435132017-02-18 14:12:53 -050019#if CONFIG_CDEF
Steinar Midtskogena9d41e82017-03-17 12:48:15 +010020#include "av1/common/cdef.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070021#include "av1/common/clpf.h"
Jean-Marc Valin01435132017-02-18 14:12:53 -050022#endif // CONFIG_CDEF
Yaowu Xuc27fc142016-08-22 16:08:15 -070023#include "av1/common/filter.h"
24#include "av1/common/idct.h"
25#include "av1/common/reconinter.h"
26#include "av1/common/reconintra.h"
Fergus Simpsond0565002017-03-27 16:51:52 -070027#include "av1/common/resize.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070028#include "av1/common/tile_common.h"
29
30#include "av1/encoder/aq_complexity.h"
31#include "av1/encoder/aq_cyclicrefresh.h"
32#include "av1/encoder/aq_variance.h"
33#include "av1/encoder/bitstream.h"
Todd Nguyen302d0972017-06-16 16:16:29 -070034#if CONFIG_BGSPRITE
35#include "av1/encoder/bgsprite.h"
36#endif // CONFIG_BGSPRITE
Yaowu Xuc27fc142016-08-22 16:08:15 -070037#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"
Angie Chiangf0fbf9d2017-03-15 15:01:22 -070044#if CONFIG_LV_MAP
45#include "av1/encoder/encodetxb.h"
46#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -070047#include "av1/encoder/ethread.h"
48#include "av1/encoder/firstpass.h"
49#include "av1/encoder/mbgraph.h"
50#include "av1/encoder/picklpf.h"
51#if CONFIG_LOOP_RESTORATION
52#include "av1/encoder/pickrst.h"
53#endif // CONFIG_LOOP_RESTORATION
54#include "av1/encoder/ratectrl.h"
55#include "av1/encoder/rd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070056#include "av1/encoder/segmentation.h"
57#include "av1/encoder/speed_features.h"
58#include "av1/encoder/temporal_filter.h"
59
Yaowu Xuf883b422016-08-30 14:01:10 -070060#include "./av1_rtcd.h"
61#include "./aom_dsp_rtcd.h"
62#include "./aom_scale_rtcd.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070063#include "aom_dsp/psnr.h"
64#if CONFIG_INTERNAL_STATS
65#include "aom_dsp/ssim.h"
66#endif
Yaowu Xuf883b422016-08-30 14:01:10 -070067#include "aom_dsp/aom_dsp_common.h"
68#include "aom_dsp/aom_filter.h"
Jingning Han1aab8182016-06-03 11:09:06 -070069#include "aom_ports/aom_timer.h"
Yaowu Xuc27fc142016-08-22 16:08:15 -070070#include "aom_ports/mem.h"
71#include "aom_ports/system_state.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070072#include "aom_scale/aom_scale.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070073#if CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070074#include "aom_util/debug_util.h"
Angie Chiang6062a8b2016-09-21 16:01:04 -070075#endif // CONFIG_BITSTREAM_DEBUG
Yaowu Xuc27fc142016-08-22 16:08:15 -070076
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -080077#if CONFIG_ENTROPY_STATS
78FRAME_COUNTS aggregate_fc;
Zoe Liua56f9162017-06-21 22:49:57 -070079// Aggregate frame counts per frame context type
80FRAME_COUNTS aggregate_fc_per_type[FRAME_CONTEXTS];
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -080081#endif // CONFIG_ENTROPY_STATS
82
Yaowu Xuc27fc142016-08-22 16:08:15 -070083#define AM_SEGMENT_ID_INACTIVE 7
84#define AM_SEGMENT_ID_ACTIVE 0
85
86#define SHARP_FILTER_QTHRESH 0 /* Q threshold for 8-tap sharp filter */
87
88#define ALTREF_HIGH_PRECISION_MV 1 // Whether to use high precision mv
89 // for altref computation.
90#define HIGH_PRECISION_MV_QTHRESH 200 // Q threshold for high precision
91 // mv. Choose a very high value for
92 // now so that HIGH_PRECISION is always
93 // chosen.
94// #define OUTPUT_YUV_REC
95#ifdef OUTPUT_YUV_DENOISED
96FILE *yuv_denoised_file = NULL;
97#endif
98#ifdef OUTPUT_YUV_SKINMAP
99FILE *yuv_skinmap_file = NULL;
100#endif
101#ifdef OUTPUT_YUV_REC
102FILE *yuv_rec_file;
103#define FILE_NAME_LEN 100
104#endif
105
106#if 0
107FILE *framepsnr;
108FILE *kf_list;
109FILE *keyfile;
110#endif
111
Luc Trudeauf8164152017-04-11 16:20:51 -0400112#if CONFIG_CFL
113CFL_CTX NULL_CFL;
114#endif
115
Urvang Joshib5ed3502016-10-17 16:38:05 -0700116#if CONFIG_INTERNAL_STATS
117typedef enum { Y, U, V, ALL } STAT_TYPE;
118#endif // CONFIG_INTERNAL_STATS
119
Yaowu Xuf883b422016-08-30 14:01:10 -0700120static INLINE void Scale2Ratio(AOM_SCALING mode, int *hr, int *hs) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700121 switch (mode) {
122 case NORMAL:
123 *hr = 1;
124 *hs = 1;
125 break;
126 case FOURFIVE:
127 *hr = 4;
128 *hs = 5;
129 break;
130 case THREEFIVE:
131 *hr = 3;
132 *hs = 5;
133 break;
134 case ONETWO:
135 *hr = 1;
136 *hs = 2;
137 break;
138 default:
139 *hr = 1;
140 *hs = 1;
141 assert(0);
142 break;
143 }
144}
145
146// Mark all inactive blocks as active. Other segmentation features may be set
147// so memset cannot be used, instead only inactive blocks should be reset.
Yaowu Xuf883b422016-08-30 14:01:10 -0700148static void suppress_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700149 unsigned char *const seg_map = cpi->segmentation_map;
150 int i;
151 if (cpi->active_map.enabled || cpi->active_map.update)
152 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
153 if (seg_map[i] == AM_SEGMENT_ID_INACTIVE)
154 seg_map[i] = AM_SEGMENT_ID_ACTIVE;
155}
156
Yaowu Xuf883b422016-08-30 14:01:10 -0700157static void apply_active_map(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700158 struct segmentation *const seg = &cpi->common.seg;
159 unsigned char *const seg_map = cpi->segmentation_map;
160 const unsigned char *const active_map = cpi->active_map.map;
161 int i;
162
163 assert(AM_SEGMENT_ID_ACTIVE == CR_SEGMENT_ID_BASE);
164
165 if (frame_is_intra_only(&cpi->common)) {
166 cpi->active_map.enabled = 0;
167 cpi->active_map.update = 1;
168 }
169
170 if (cpi->active_map.update) {
171 if (cpi->active_map.enabled) {
172 for (i = 0; i < cpi->common.mi_rows * cpi->common.mi_cols; ++i)
173 if (seg_map[i] == AM_SEGMENT_ID_ACTIVE) seg_map[i] = active_map[i];
Yaowu Xuf883b422016-08-30 14:01:10 -0700174 av1_enable_segmentation(seg);
175 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
176 av1_enable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700177 // Setting the data to -MAX_LOOP_FILTER will result in the computed loop
178 // filter level being zero regardless of the value of seg->abs_delta.
Yaowu Xuf883b422016-08-30 14:01:10 -0700179 av1_set_segdata(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF,
180 -MAX_LOOP_FILTER);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700181 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -0700182 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_SKIP);
183 av1_disable_segfeature(seg, AM_SEGMENT_ID_INACTIVE, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700184 if (seg->enabled) {
185 seg->update_data = 1;
186 seg->update_map = 1;
187 }
188 }
189 cpi->active_map.update = 0;
190 }
191}
192
Yaowu Xuf883b422016-08-30 14:01:10 -0700193int av1_set_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
194 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700195 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols) {
196 unsigned char *const active_map_8x8 = cpi->active_map.map;
197 const int mi_rows = cpi->common.mi_rows;
198 const int mi_cols = cpi->common.mi_cols;
Jingning Han9d533022017-04-07 10:14:42 -0700199 const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
200 const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700201 cpi->active_map.update = 1;
202 if (new_map_16x16) {
203 int r, c;
204 for (r = 0; r < mi_rows; ++r) {
205 for (c = 0; c < mi_cols; ++c) {
206 active_map_8x8[r * mi_cols + c] =
Jingning Han9d533022017-04-07 10:14:42 -0700207 new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)]
Yaowu Xuc27fc142016-08-22 16:08:15 -0700208 ? AM_SEGMENT_ID_ACTIVE
209 : AM_SEGMENT_ID_INACTIVE;
210 }
211 }
212 cpi->active_map.enabled = 1;
213 } else {
214 cpi->active_map.enabled = 0;
215 }
216 return 0;
217 } else {
218 return -1;
219 }
220}
221
Yaowu Xuf883b422016-08-30 14:01:10 -0700222int av1_get_active_map(AV1_COMP *cpi, unsigned char *new_map_16x16, int rows,
223 int cols) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700224 if (rows == cpi->common.mb_rows && cols == cpi->common.mb_cols &&
225 new_map_16x16) {
226 unsigned char *const seg_map_8x8 = cpi->segmentation_map;
227 const int mi_rows = cpi->common.mi_rows;
228 const int mi_cols = cpi->common.mi_cols;
Jingning Han9d533022017-04-07 10:14:42 -0700229 const int row_scale = mi_size_high[BLOCK_16X16] == 2 ? 1 : 2;
230 const int col_scale = mi_size_wide[BLOCK_16X16] == 2 ? 1 : 2;
231
Yaowu Xuc27fc142016-08-22 16:08:15 -0700232 memset(new_map_16x16, !cpi->active_map.enabled, rows * cols);
233 if (cpi->active_map.enabled) {
234 int r, c;
235 for (r = 0; r < mi_rows; ++r) {
236 for (c = 0; c < mi_cols; ++c) {
237 // Cyclic refresh segments are considered active despite not having
238 // AM_SEGMENT_ID_ACTIVE
Jingning Han9d533022017-04-07 10:14:42 -0700239 new_map_16x16[(r >> row_scale) * cols + (c >> col_scale)] |=
Yaowu Xuc27fc142016-08-22 16:08:15 -0700240 seg_map_8x8[r * mi_cols + c] != AM_SEGMENT_ID_INACTIVE;
241 }
242 }
243 }
244 return 0;
245 } else {
246 return -1;
247 }
248}
249
Yaowu Xuf883b422016-08-30 14:01:10 -0700250void av1_set_high_precision_mv(AV1_COMP *cpi, int allow_high_precision_mv) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700251 MACROBLOCK *const mb = &cpi->td.mb;
252 cpi->common.allow_high_precision_mv = allow_high_precision_mv;
253
Yaowu Xuc27fc142016-08-22 16:08:15 -0700254 if (cpi->common.allow_high_precision_mv) {
255 int i;
256 for (i = 0; i < NMV_CONTEXTS; ++i) {
257 mb->mv_cost_stack[i] = mb->nmvcost_hp[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700258 }
259 } else {
260 int i;
261 for (i = 0; i < NMV_CONTEXTS; ++i) {
262 mb->mv_cost_stack[i] = mb->nmvcost[i];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700263 }
264 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700265}
266
Yaowu Xuf883b422016-08-30 14:01:10 -0700267static BLOCK_SIZE select_sb_size(const AV1_COMP *const cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700268#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700269 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_64X64)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700270 return BLOCK_64X64;
271
Yaowu Xuf883b422016-08-30 14:01:10 -0700272 if (cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_128X128)
Yaowu Xuc27fc142016-08-22 16:08:15 -0700273 return BLOCK_128X128;
274
Yaowu Xuf883b422016-08-30 14:01:10 -0700275 assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700276
277 assert(IMPLIES(cpi->common.tile_cols > 1,
278 cpi->common.tile_width % MAX_MIB_SIZE == 0));
279 assert(IMPLIES(cpi->common.tile_rows > 1,
280 cpi->common.tile_height % MAX_MIB_SIZE == 0));
281
282 // TODO(any): Possibly could improve this with a heuristic.
283 return BLOCK_128X128;
284#else
285 (void)cpi;
286 return BLOCK_64X64;
287#endif // CONFIG_EXT_PARTITION
288}
289
Yaowu Xuf883b422016-08-30 14:01:10 -0700290static void setup_frame(AV1_COMP *cpi) {
291 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700292 // Set up entropy context depending on frame type. The decoder mandates
293 // the use of the default context, index 0, for keyframes and inter
294 // frames where the error_resilient_mode or intra_only flag is set. For
295 // other inter-frames the encoder currently uses only two contexts;
296 // context 1 for ALTREF frames and context 0 for the others.
297 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700298 av1_setup_past_independence(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700299 } else {
300#if CONFIG_EXT_REFS
301 const GF_GROUP *gf_group = &cpi->twopass.gf_group;
302 if (gf_group->rf_level[gf_group->index] == GF_ARF_LOW)
303 cm->frame_context_idx = EXT_ARF_FRAME;
304 else if (cpi->refresh_alt_ref_frame)
305 cm->frame_context_idx = ARF_FRAME;
306#else
307 if (cpi->refresh_alt_ref_frame) cm->frame_context_idx = ARF_FRAME;
Zoe Liu6cfaff92016-10-18 17:12:11 -0700308#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700309 else if (cpi->rc.is_src_frame_alt_ref)
310 cm->frame_context_idx = OVERLAY_FRAME;
311 else if (cpi->refresh_golden_frame)
312 cm->frame_context_idx = GLD_FRAME;
313#if CONFIG_EXT_REFS
314 else if (cpi->refresh_bwd_ref_frame)
315 cm->frame_context_idx = BRF_FRAME;
Zoe Liu6cfaff92016-10-18 17:12:11 -0700316#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -0700317 else
318 cm->frame_context_idx = REGULAR_FRAME;
319 }
320
321 if (cm->frame_type == KEY_FRAME) {
322 cpi->refresh_golden_frame = 1;
323 cpi->refresh_alt_ref_frame = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700324 av1_zero(cpi->interp_filter_selected);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700325 } else {
326 *cm->fc = cm->frame_contexts[cm->frame_context_idx];
Yaowu Xuf883b422016-08-30 14:01:10 -0700327 av1_zero(cpi->interp_filter_selected[0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700328 }
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +0200329#if CONFIG_EXT_REFS
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +0200330#if CONFIG_ONE_SIDED_COMPOUND // No change to bitstream
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +0200331 if (cpi->sf.recode_loop == DISALLOW_RECODE) {
332 cpi->refresh_bwd_ref_frame = cpi->refresh_last_frame;
333 cpi->rc.is_bipred_frame = 1;
334 }
335#endif
336#endif
Thomas Daede10e1da92017-04-26 13:22:21 -0700337 cm->pre_fc = &cm->frame_contexts[cm->frame_context_idx];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700338
339 cpi->vaq_refresh = 0;
340
341 set_sb_size(cm, select_sb_size(cpi));
342}
343
Yaowu Xuf883b422016-08-30 14:01:10 -0700344static void av1_enc_setup_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700345 int i;
346 cm->mi = cm->mip + cm->mi_stride + 1;
347 memset(cm->mip, 0, cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mip));
348 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
349 // Clear top border row
350 memset(cm->prev_mip, 0, sizeof(*cm->prev_mip) * cm->mi_stride);
351 // Clear left border column
352 for (i = 1; i < cm->mi_rows + 1; ++i)
353 memset(&cm->prev_mip[i * cm->mi_stride], 0, sizeof(*cm->prev_mip));
354
355 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
356 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
357
358 memset(cm->mi_grid_base, 0,
359 cm->mi_stride * (cm->mi_rows + 1) * sizeof(*cm->mi_grid_base));
360}
361
Yaowu Xuf883b422016-08-30 14:01:10 -0700362static int av1_enc_alloc_mi(AV1_COMMON *cm, int mi_size) {
363 cm->mip = aom_calloc(mi_size, sizeof(*cm->mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700364 if (!cm->mip) return 1;
Yaowu Xuf883b422016-08-30 14:01:10 -0700365 cm->prev_mip = aom_calloc(mi_size, sizeof(*cm->prev_mip));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700366 if (!cm->prev_mip) return 1;
367 cm->mi_alloc_size = mi_size;
368
Yaowu Xuf883b422016-08-30 14:01:10 -0700369 cm->mi_grid_base = (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700370 if (!cm->mi_grid_base) return 1;
371 cm->prev_mi_grid_base =
Yaowu Xuf883b422016-08-30 14:01:10 -0700372 (MODE_INFO **)aom_calloc(mi_size, sizeof(MODE_INFO *));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700373 if (!cm->prev_mi_grid_base) return 1;
374
375 return 0;
376}
377
Yaowu Xuf883b422016-08-30 14:01:10 -0700378static void av1_enc_free_mi(AV1_COMMON *cm) {
379 aom_free(cm->mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700380 cm->mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700381 aom_free(cm->prev_mip);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700382 cm->prev_mip = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700383 aom_free(cm->mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700384 cm->mi_grid_base = NULL;
Yaowu Xuf883b422016-08-30 14:01:10 -0700385 aom_free(cm->prev_mi_grid_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700386 cm->prev_mi_grid_base = NULL;
387}
388
Yaowu Xuf883b422016-08-30 14:01:10 -0700389static void av1_swap_mi_and_prev_mi(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700390 // Current mip will be the prev_mip for the next frame.
391 MODE_INFO **temp_base = cm->prev_mi_grid_base;
392 MODE_INFO *temp = cm->prev_mip;
393 cm->prev_mip = cm->mip;
394 cm->mip = temp;
395
396 // Update the upper left visible macroblock ptrs.
397 cm->mi = cm->mip + cm->mi_stride + 1;
398 cm->prev_mi = cm->prev_mip + cm->mi_stride + 1;
399
400 cm->prev_mi_grid_base = cm->mi_grid_base;
401 cm->mi_grid_base = temp_base;
402 cm->mi_grid_visible = cm->mi_grid_base + cm->mi_stride + 1;
403 cm->prev_mi_grid_visible = cm->prev_mi_grid_base + cm->mi_stride + 1;
404}
405
Yaowu Xuf883b422016-08-30 14:01:10 -0700406void av1_initialize_enc(void) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700407 static volatile int init_done = 0;
408
409 if (!init_done) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700410 av1_rtcd();
411 aom_dsp_rtcd();
412 aom_scale_rtcd();
413 av1_init_intra_predictors();
414 av1_init_me_luts();
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +0000415#if !CONFIG_XIPHRC
Yaowu Xuf883b422016-08-30 14:01:10 -0700416 av1_rc_init_minq_luts();
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +0000417#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700418 av1_entropy_mv_init();
419 av1_encode_token_init();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700420#if CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -0700421 av1_init_wedge_masks();
Yaowu Xuc27fc142016-08-22 16:08:15 -0700422#endif
423 init_done = 1;
424 }
425}
426
Yaowu Xuf883b422016-08-30 14:01:10 -0700427static void dealloc_compressor_data(AV1_COMP *cpi) {
428 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700429
Yaowu Xuf883b422016-08-30 14:01:10 -0700430 aom_free(cpi->mbmi_ext_base);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700431 cpi->mbmi_ext_base = NULL;
432
Yushin Cho77bba8d2016-11-04 16:36:56 -0700433#if CONFIG_PVQ
434 if (cpi->oxcf.pass != 1) {
Yushin Cho749c0572017-04-07 10:36:47 -0700435 const int tile_cols = cm->tile_cols;
436 const int tile_rows = cm->tile_rows;
Yushin Cho77bba8d2016-11-04 16:36:56 -0700437 int tile_col, tile_row;
438
439 for (tile_row = 0; tile_row < tile_rows; ++tile_row)
440 for (tile_col = 0; tile_col < tile_cols; ++tile_col) {
441 TileDataEnc *tile_data =
442 &cpi->tile_data[tile_row * tile_cols + tile_col];
443 aom_free(tile_data->pvq_q.buf);
444 }
445 }
446#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700447 aom_free(cpi->tile_data);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700448 cpi->tile_data = NULL;
449
450 // Delete sementation map
Yaowu Xuf883b422016-08-30 14:01:10 -0700451 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700452 cpi->segmentation_map = NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700453
Yaowu Xuf883b422016-08-30 14:01:10 -0700454 av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700455 cpi->cyclic_refresh = NULL;
456
Yaowu Xuf883b422016-08-30 14:01:10 -0700457 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700458 cpi->active_map.map = NULL;
459
Jingning Hand064cf02017-06-01 10:00:39 -0700460#if CONFIG_MOTION_VAR
461 aom_free(cpi->td.mb.above_pred_buf);
462 cpi->td.mb.above_pred_buf = NULL;
463
464 aom_free(cpi->td.mb.left_pred_buf);
465 cpi->td.mb.left_pred_buf = NULL;
466
467 aom_free(cpi->td.mb.wsrc_buf);
468 cpi->td.mb.wsrc_buf = NULL;
469
470 aom_free(cpi->td.mb.mask_buf);
471 cpi->td.mb.mask_buf = NULL;
472#endif
473
Yaowu Xuf883b422016-08-30 14:01:10 -0700474 av1_free_ref_frame_buffers(cm->buffer_pool);
Angie Chiangf0fbf9d2017-03-15 15:01:22 -0700475#if CONFIG_LV_MAP
476 av1_free_txb_buf(cpi);
477#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700478 av1_free_context_buffers(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700479
Yaowu Xuf883b422016-08-30 14:01:10 -0700480 aom_free_frame_buffer(&cpi->last_frame_uf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700481#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700482 av1_free_restoration_buffers(cm);
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800483 aom_free_frame_buffer(&cpi->last_frame_db);
484 aom_free_frame_buffer(&cpi->trial_frame_rst);
485 aom_free(cpi->extra_rstbuf);
Timothy B. Terriberry5d24b6f2017-06-15 13:39:35 -0700486 {
487 int i;
488 for (i = 0; i < MAX_MB_PLANE; ++i)
489 av1_free_restoration_struct(&cpi->rst_search[i]);
490 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700491#endif // CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700492 aom_free_frame_buffer(&cpi->scaled_source);
493 aom_free_frame_buffer(&cpi->scaled_last_source);
494 aom_free_frame_buffer(&cpi->alt_ref_buffer);
495 av1_lookahead_destroy(cpi->lookahead);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700496
Yaowu Xuf883b422016-08-30 14:01:10 -0700497 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700498 cpi->tile_tok[0][0] = 0;
499
Yaowu Xuf883b422016-08-30 14:01:10 -0700500 av1_free_pc_tree(&cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700501
Urvang Joshib100db72016-10-12 16:28:56 -0700502#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700503 if (cpi->common.allow_screen_content_tools)
Yaowu Xuf883b422016-08-30 14:01:10 -0700504 aom_free(cpi->td.mb.palette_buffer);
Urvang Joshib100db72016-10-12 16:28:56 -0700505#endif // CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -0700506
Yaowu Xuc27fc142016-08-22 16:08:15 -0700507#if CONFIG_ANS
Alex Converse1ac1ae72016-09-17 15:11:16 -0700508 aom_buf_ans_free(&cpi->buf_ans);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700509#endif // CONFIG_ANS
510}
511
Yaowu Xuf883b422016-08-30 14:01:10 -0700512static void save_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 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700516
Sebastien Alaiwane140c502017-04-27 09:52:34 +0200517 // Stores a snapshot of key state variables which can subsequently be
518 // restored with a call to av1_restore_coding_context. These functions are
519 // intended for use in a re-code loop in av1_compress_frame where the
520 // quantizer value is adjusted between loop iterations.
Yaowu Xuc27fc142016-08-22 16:08:15 -0700521 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700522 av1_copy(cc->nmv_vec_cost[i], cpi->td.mb.nmv_vec_cost[i]);
Urvang Joshibffc0b52016-07-25 13:38:49 -0700523 av1_copy(cc->nmv_costs, cpi->nmv_costs);
524 av1_copy(cc->nmv_costs_hp, cpi->nmv_costs_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700525 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700526
Yaowu Xuf883b422016-08-30 14:01:10 -0700527 av1_copy(cc->last_ref_lf_deltas, cm->lf.last_ref_deltas);
528 av1_copy(cc->last_mode_lf_deltas, cm->lf.last_mode_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700529
530 cc->fc = *cm->fc;
531}
532
Yaowu Xuf883b422016-08-30 14:01:10 -0700533static void restore_coding_context(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700534 CODING_CONTEXT *const cc = &cpi->coding_context;
Yaowu Xuf883b422016-08-30 14:01:10 -0700535 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700536 int i;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700537
Sebastien Alaiwane140c502017-04-27 09:52:34 +0200538 // Restore key state variables to the snapshot state stored in the
539 // previous call to av1_save_coding_context.
Yaowu Xuc27fc142016-08-22 16:08:15 -0700540 for (i = 0; i < NMV_CONTEXTS; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700541 av1_copy(cpi->td.mb.nmv_vec_cost[i], cc->nmv_vec_cost[i]);
Urvang Joshibffc0b52016-07-25 13:38:49 -0700542 av1_copy(cpi->nmv_costs, cc->nmv_costs);
543 av1_copy(cpi->nmv_costs_hp, cc->nmv_costs_hp);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700544 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700545
Yaowu Xuf883b422016-08-30 14:01:10 -0700546 av1_copy(cm->lf.last_ref_deltas, cc->last_ref_lf_deltas);
547 av1_copy(cm->lf.last_mode_deltas, cc->last_mode_lf_deltas);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700548
549 *cm->fc = cc->fc;
550}
551
Yaowu Xuf883b422016-08-30 14:01:10 -0700552static void configure_static_seg_features(AV1_COMP *cpi) {
553 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700554 const RATE_CONTROL *const rc = &cpi->rc;
555 struct segmentation *const seg = &cm->seg;
556
557 int high_q = (int)(rc->avg_q > 48.0);
558 int qi_delta;
559
560 // Disable and clear down for KF
561 if (cm->frame_type == KEY_FRAME) {
562 // Clear down the global segmentation map
563 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
564 seg->update_map = 0;
565 seg->update_data = 0;
566 cpi->static_mb_pct = 0;
567
568 // Disable segmentation
Yaowu Xuf883b422016-08-30 14:01:10 -0700569 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700570
571 // Clear down the segment features.
Yaowu Xuf883b422016-08-30 14:01:10 -0700572 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700573 } else if (cpi->refresh_alt_ref_frame) {
574 // If this is an alt ref frame
575 // Clear down the global segmentation map
576 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
577 seg->update_map = 0;
578 seg->update_data = 0;
579 cpi->static_mb_pct = 0;
580
581 // Disable segmentation and individual segment features by default
Yaowu Xuf883b422016-08-30 14:01:10 -0700582 av1_disable_segmentation(seg);
583 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700584
585 // Scan frames from current to arf frame.
586 // This function re-enables segmentation if appropriate.
Yaowu Xuf883b422016-08-30 14:01:10 -0700587 av1_update_mbgraph_stats(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700588
589 // If segmentation was enabled set those features needed for the
590 // arf itself.
591 if (seg->enabled) {
592 seg->update_map = 1;
593 seg->update_data = 1;
594
595 qi_delta =
Yaowu Xuf883b422016-08-30 14:01:10 -0700596 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 0.875, cm->bit_depth);
597 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta - 2);
598 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700599
Yaowu Xuf883b422016-08-30 14:01:10 -0700600 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
601 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700602
603 // Where relevant assume segment data is delta data
604 seg->abs_delta = SEGMENT_DELTADATA;
605 }
606 } else if (seg->enabled) {
607 // All other frames if segmentation has been enabled
608
609 // First normal frame in a valid gf or alt ref group
610 if (rc->frames_since_golden == 0) {
611 // Set up segment features for normal frames in an arf group
612 if (rc->source_alt_ref_active) {
613 seg->update_map = 0;
614 seg->update_data = 1;
615 seg->abs_delta = SEGMENT_DELTADATA;
616
Yaowu Xuf883b422016-08-30 14:01:10 -0700617 qi_delta =
618 av1_compute_qdelta(rc, rc->avg_q, rc->avg_q * 1.125, cm->bit_depth);
619 av1_set_segdata(seg, 1, SEG_LVL_ALT_Q, qi_delta + 2);
620 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_Q);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700621
Yaowu Xuf883b422016-08-30 14:01:10 -0700622 av1_set_segdata(seg, 1, SEG_LVL_ALT_LF, -2);
623 av1_enable_segfeature(seg, 1, SEG_LVL_ALT_LF);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700624
625 // Segment coding disabled for compred testing
626 if (high_q || (cpi->static_mb_pct == 100)) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700627 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
628 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
629 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700630 }
631 } else {
632 // Disable segmentation and clear down features if alt ref
633 // is not active for this group
634
Yaowu Xuf883b422016-08-30 14:01:10 -0700635 av1_disable_segmentation(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700636
637 memset(cpi->segmentation_map, 0, cm->mi_rows * cm->mi_cols);
638
639 seg->update_map = 0;
640 seg->update_data = 0;
641
Yaowu Xuf883b422016-08-30 14:01:10 -0700642 av1_clearall_segfeatures(seg);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700643 }
644 } else if (rc->is_src_frame_alt_ref) {
645 // Special case where we are coding over the top of a previous
646 // alt ref frame.
647 // Segment coding disabled for compred testing
648
649 // Enable ref frame features for segment 0 as well
Yaowu Xuf883b422016-08-30 14:01:10 -0700650 av1_enable_segfeature(seg, 0, SEG_LVL_REF_FRAME);
651 av1_enable_segfeature(seg, 1, SEG_LVL_REF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700652
653 // All mbs should use ALTREF_FRAME
Yaowu Xuf883b422016-08-30 14:01:10 -0700654 av1_clear_segdata(seg, 0, SEG_LVL_REF_FRAME);
655 av1_set_segdata(seg, 0, SEG_LVL_REF_FRAME, ALTREF_FRAME);
656 av1_clear_segdata(seg, 1, SEG_LVL_REF_FRAME);
657 av1_set_segdata(seg, 1, SEG_LVL_REF_FRAME, ALTREF_FRAME);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700658
659 // Skip all MBs if high Q (0,0 mv and skip coeffs)
660 if (high_q) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700661 av1_enable_segfeature(seg, 0, SEG_LVL_SKIP);
662 av1_enable_segfeature(seg, 1, SEG_LVL_SKIP);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700663 }
664 // Enable data update
665 seg->update_data = 1;
666 } else {
667 // All other frames.
668
669 // No updates.. leave things as they are.
670 seg->update_map = 0;
671 seg->update_data = 0;
672 }
673 }
674}
675
Yaowu Xuf883b422016-08-30 14:01:10 -0700676static void update_reference_segmentation_map(AV1_COMP *cpi) {
677 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700678 MODE_INFO **mi_8x8_ptr = cm->mi_grid_visible;
679 uint8_t *cache_ptr = cm->last_frame_seg_map;
680 int row, col;
681
682 for (row = 0; row < cm->mi_rows; row++) {
683 MODE_INFO **mi_8x8 = mi_8x8_ptr;
684 uint8_t *cache = cache_ptr;
685 for (col = 0; col < cm->mi_cols; col++, mi_8x8++, cache++)
686 cache[0] = mi_8x8[0]->mbmi.segment_id;
687 mi_8x8_ptr += cm->mi_stride;
688 cache_ptr += cm->mi_cols;
689 }
690}
691
Yaowu Xuf883b422016-08-30 14:01:10 -0700692static void alloc_raw_frame_buffers(AV1_COMP *cpi) {
693 AV1_COMMON *cm = &cpi->common;
694 const AV1EncoderConfig *oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700695
696 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700697 cpi->lookahead = av1_lookahead_init(oxcf->width, oxcf->height,
698 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200699#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -0700700 cm->use_highbitdepth,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700701#endif
Yaowu Xuf883b422016-08-30 14:01:10 -0700702 oxcf->lag_in_frames);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700703 if (!cpi->lookahead)
Yaowu Xuf883b422016-08-30 14:01:10 -0700704 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700705 "Failed to allocate lag buffers");
706
707 // TODO(agrange) Check if ARF is enabled and skip allocation if not.
Yaowu Xuf883b422016-08-30 14:01:10 -0700708 if (aom_realloc_frame_buffer(&cpi->alt_ref_buffer, oxcf->width, oxcf->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700709 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200710#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700711 cm->use_highbitdepth,
712#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700713 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
714 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700715 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700716 "Failed to allocate altref buffer");
717}
718
Yaowu Xuf883b422016-08-30 14:01:10 -0700719static void alloc_util_frame_buffers(AV1_COMP *cpi) {
720 AV1_COMMON *const cm = &cpi->common;
721 if (aom_realloc_frame_buffer(&cpi->last_frame_uf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700722 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200723#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700724 cm->use_highbitdepth,
725#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700726 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
727 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700728 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700729 "Failed to allocate last frame buffer");
730
731#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -0700732 if (aom_realloc_frame_buffer(&cpi->last_frame_db, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700733 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200734#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700735 cm->use_highbitdepth,
736#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700737 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
738 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700739 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700740 "Failed to allocate last frame deblocked buffer");
Fergus Simpson9cd57cf2017-06-12 17:02:03 -0700741 if (aom_realloc_frame_buffer(
742 &cpi->trial_frame_rst,
743#if CONFIG_FRAME_SUPERRES
744 cm->superres_upscaled_width, cm->superres_upscaled_height,
745#else
746 cm->width, cm->height,
747#endif // CONFIG_FRAME_SUPERRES
748 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200749#if CONFIG_HIGHBITDEPTH
Fergus Simpson9cd57cf2017-06-12 17:02:03 -0700750 cm->use_highbitdepth,
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800751#endif
Fergus Simpson9cd57cf2017-06-12 17:02:03 -0700752 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL))
Debargha Mukherjee874d36d2016-12-14 16:53:17 -0800753 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Debargha Mukherjee999d2f62016-12-15 13:23:21 -0800754 "Failed to allocate trial restored frame buffer");
Alex Converse232e3842017-02-24 12:24:36 -0800755 int extra_rstbuf_sz = RESTORATION_EXTBUF_SIZE;
Debargha Mukherjeeb3c43bc2017-02-01 13:09:03 -0800756 if (extra_rstbuf_sz > 0) {
Alex Converse7f094f12017-02-23 17:29:40 -0800757 aom_free(cpi->extra_rstbuf);
Alex Converse232e3842017-02-24 12:24:36 -0800758 CHECK_MEM_ERROR(cm, cpi->extra_rstbuf,
Alex Converse7f094f12017-02-23 17:29:40 -0800759 (uint8_t *)aom_malloc(extra_rstbuf_sz));
Debargha Mukherjeeb3c43bc2017-02-01 13:09:03 -0800760 } else {
761 cpi->extra_rstbuf = NULL;
762 }
Yaowu Xuc27fc142016-08-22 16:08:15 -0700763#endif // CONFIG_LOOP_RESTORATION
764
Yaowu Xuf883b422016-08-30 14:01:10 -0700765 if (aom_realloc_frame_buffer(&cpi->scaled_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700766 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200767#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700768 cm->use_highbitdepth,
769#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700770 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
771 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700772 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700773 "Failed to allocate scaled source buffer");
774
Yaowu Xuf883b422016-08-30 14:01:10 -0700775 if (aom_realloc_frame_buffer(&cpi->scaled_last_source, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700776 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200777#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700778 cm->use_highbitdepth,
779#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -0700780 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
781 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -0700782 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -0700783 "Failed to allocate scaled last source buffer");
784}
785
Yunqing Wangf5dc71e2017-05-04 18:20:17 -0700786static void alloc_context_buffers_ext(AV1_COMP *cpi) {
Yaowu Xuf883b422016-08-30 14:01:10 -0700787 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700788 int mi_size = cm->mi_cols * cm->mi_rows;
789
Yunqing Wangf5dc71e2017-05-04 18:20:17 -0700790 CHECK_MEM_ERROR(cm, cpi->mbmi_ext_base,
791 aom_calloc(mi_size, sizeof(*cpi->mbmi_ext_base)));
Yaowu Xuc27fc142016-08-22 16:08:15 -0700792}
793
Yaowu Xuf883b422016-08-30 14:01:10 -0700794void av1_alloc_compressor_data(AV1_COMP *cpi) {
795 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700796
Yaowu Xuf883b422016-08-30 14:01:10 -0700797 av1_alloc_context_buffers(cm, cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700798
Angie Chiangf0fbf9d2017-03-15 15:01:22 -0700799#if CONFIG_LV_MAP
800 av1_alloc_txb_buf(cpi);
801#endif
802
Yaowu Xuc27fc142016-08-22 16:08:15 -0700803 alloc_context_buffers_ext(cpi);
804
Yaowu Xuf883b422016-08-30 14:01:10 -0700805 aom_free(cpi->tile_tok[0][0]);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700806
807 {
808 unsigned int tokens = get_token_alloc(cm->mb_rows, cm->mb_cols);
809 CHECK_MEM_ERROR(cm, cpi->tile_tok[0][0],
Yaowu Xuf883b422016-08-30 14:01:10 -0700810 aom_calloc(tokens, sizeof(*cpi->tile_tok[0][0])));
Alex Converseeb780e72016-12-13 12:46:41 -0800811#if CONFIG_ANS && !ANS_MAX_SYMBOLS
812 aom_buf_ans_alloc(&cpi->buf_ans, &cm->error, (int)tokens);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700813#endif // CONFIG_ANS
814 }
815
Yaowu Xuf883b422016-08-30 14:01:10 -0700816 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700817}
818
Yaowu Xuf883b422016-08-30 14:01:10 -0700819void av1_new_framerate(AV1_COMP *cpi, double framerate) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700820 cpi->framerate = framerate < 0.1 ? 30 : framerate;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +0000821#if CONFIG_XIPHRC
822 if (!cpi->od_rc.cur_frame) return;
823 cpi->od_rc.framerate = cpi->framerate;
824 od_enc_rc_resize(&cpi->od_rc);
825#else
Yaowu Xuf883b422016-08-30 14:01:10 -0700826 av1_rc_update_framerate(cpi);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +0000827#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700828}
829
Yaowu Xuf883b422016-08-30 14:01:10 -0700830static void set_tile_info(AV1_COMP *cpi) {
831 AV1_COMMON *const cm = &cpi->common;
Fangwen Fu73126c02017-02-08 22:37:47 -0800832#if CONFIG_TILE_GROUPS && CONFIG_DEPENDENT_HORZTILES
833 int tile_row, tile_col, num_tiles_in_tg;
834 int tg_row_start, tg_col_start;
835#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700836#if CONFIG_EXT_TILE
837#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -0700838 if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700839 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
840 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
841 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
842 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
843 } else {
844 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
845 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
846 cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
847 cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
848 }
849#else
850 cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
851 cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
852 cm->tile_width <<= MAX_MIB_SIZE_LOG2;
853 cm->tile_height <<= MAX_MIB_SIZE_LOG2;
854#endif // CONFIG_EXT_PARTITION
855
Yaowu Xuf883b422016-08-30 14:01:10 -0700856 cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
857 cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700858
859 assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
860 assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
861
862 // Get the number of tiles
863 cm->tile_cols = 1;
864 while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
865
866 cm->tile_rows = 1;
867 while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
868#else
869 int min_log2_tile_cols, max_log2_tile_cols;
Yaowu Xuf883b422016-08-30 14:01:10 -0700870 av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700871
872 cm->log2_tile_cols =
873 clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
874 cm->log2_tile_rows = cpi->oxcf.tile_rows;
875
876 cm->tile_cols = 1 << cm->log2_tile_cols;
877 cm->tile_rows = 1 << cm->log2_tile_rows;
878
879 cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
880 cm->tile_width >>= cm->log2_tile_cols;
881 cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
882 cm->tile_height >>= cm->log2_tile_rows;
883
884 // round to integer multiples of max superblock size
885 cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
886 cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
887#endif // CONFIG_EXT_TILE
Ryan Lei7386eda2016-12-08 21:08:31 -0800888
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800889#if CONFIG_DEPENDENT_HORZTILES
890 cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles;
Fangwen Fu70bcb892017-05-06 17:05:19 -0700891#if CONFIG_EXT_TILE
892 if (cm->tile_rows <= 1) cm->dependent_horz_tiles = 0;
893#else
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800894 if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0;
Fangwen Fu70bcb892017-05-06 17:05:19 -0700895#endif
Fangwen Fu73126c02017-02-08 22:37:47 -0800896#if CONFIG_TILE_GROUPS
897 if (cpi->oxcf.mtu == 0) {
898 cm->num_tg = cpi->oxcf.num_tile_groups;
899 } else {
900 // Use a default value for the purposes of weighting costs in probability
901 // updates
902 cm->num_tg = DEFAULT_MAX_NUM_TG;
903 }
904 num_tiles_in_tg =
905 (cm->tile_cols * cm->tile_rows + cm->num_tg - 1) / cm->num_tg;
906 tg_row_start = 0;
907 tg_col_start = 0;
908 for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
909 for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
910 if ((tile_row * cm->tile_cols + tile_col) % num_tiles_in_tg == 0) {
911 tg_row_start = tile_row;
912 tg_col_start = tile_col;
913 }
914 cm->tile_group_start_row[tile_row][tile_col] = tg_row_start;
915 cm->tile_group_start_col[tile_row][tile_col] = tg_col_start;
916 }
917 }
918#endif
Fangwen Fu7b9f2b32017-01-17 14:01:52 -0800919#endif
920
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800921#if CONFIG_LOOPFILTERING_ACROSS_TILES
Ryan Lei7386eda2016-12-08 21:08:31 -0800922 cm->loop_filter_across_tiles_enabled =
923 cpi->oxcf.loop_filter_across_tiles_enabled;
Ryan Lei9b02b0e2017-01-30 15:52:20 -0800924#endif // CONFIG_LOOPFILTERING_ACROSS_TILES
Yaowu Xuc27fc142016-08-22 16:08:15 -0700925}
926
Yaowu Xuf883b422016-08-30 14:01:10 -0700927static void update_frame_size(AV1_COMP *cpi) {
928 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700929 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
930
Yaowu Xuf883b422016-08-30 14:01:10 -0700931 av1_set_mb_mi(cm, cm->width, cm->height);
932 av1_init_context_buffers(cm);
Yushin Cho77bba8d2016-11-04 16:36:56 -0700933 av1_init_macroblockd(cm, xd,
934#if CONFIG_PVQ
935 NULL,
936#endif
Luc Trudeauf8164152017-04-11 16:20:51 -0400937#if CONFIG_CFL
938 &NULL_CFL,
939#endif
Yushin Cho77bba8d2016-11-04 16:36:56 -0700940 NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700941 memset(cpi->mbmi_ext_base, 0,
942 cm->mi_rows * cm->mi_cols * sizeof(*cpi->mbmi_ext_base));
943
944 set_tile_info(cpi);
945}
946
Yaowu Xuf883b422016-08-30 14:01:10 -0700947static void init_buffer_indices(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700948#if CONFIG_EXT_REFS
949 int fb_idx;
950 for (fb_idx = 0; fb_idx < LAST_REF_FRAMES; ++fb_idx)
951 cpi->lst_fb_idxes[fb_idx] = fb_idx;
952 cpi->gld_fb_idx = LAST_REF_FRAMES;
953 cpi->bwd_fb_idx = LAST_REF_FRAMES + 1;
954 cpi->alt_fb_idx = LAST_REF_FRAMES + 2;
955 for (fb_idx = 0; fb_idx < MAX_EXT_ARFS + 1; ++fb_idx)
956 cpi->arf_map[fb_idx] = LAST_REF_FRAMES + 2 + fb_idx;
957#else
958 cpi->lst_fb_idx = 0;
959 cpi->gld_fb_idx = 1;
960 cpi->alt_fb_idx = 2;
961#endif // CONFIG_EXT_REFS
962}
963
Yaowu Xuf883b422016-08-30 14:01:10 -0700964static void init_config(struct AV1_COMP *cpi, AV1EncoderConfig *oxcf) {
965 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -0700966
967 cpi->oxcf = *oxcf;
968 cpi->framerate = oxcf->init_framerate;
969
970 cm->profile = oxcf->profile;
971 cm->bit_depth = oxcf->bit_depth;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +0200972#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -0700973 cm->use_highbitdepth = oxcf->use_highbitdepth;
974#endif
975 cm->color_space = oxcf->color_space;
anorkin76fb1262017-03-22 15:12:12 -0700976#if CONFIG_COLORSPACE_HEADERS
977 cm->transfer_function = oxcf->transfer_function;
978 cm->chroma_sample_position = oxcf->chroma_sample_position;
979#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -0700980 cm->color_range = oxcf->color_range;
981
982 cm->width = oxcf->width;
983 cm->height = oxcf->height;
Yaowu Xuf883b422016-08-30 14:01:10 -0700984 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700985
986 // Single thread case: use counts in common.
987 cpi->td.counts = &cm->counts;
988
989 // change includes all joint functionality
Yaowu Xuf883b422016-08-30 14:01:10 -0700990 av1_change_config(cpi, oxcf);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700991
992 cpi->static_mb_pct = 0;
993 cpi->ref_frame_flags = 0;
994
995 init_buffer_indices(cpi);
996}
997
998static void set_rc_buffer_sizes(RATE_CONTROL *rc,
Yaowu Xuf883b422016-08-30 14:01:10 -0700999 const AV1EncoderConfig *oxcf) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001000 const int64_t bandwidth = oxcf->target_bandwidth;
1001 const int64_t starting = oxcf->starting_buffer_level_ms;
1002 const int64_t optimal = oxcf->optimal_buffer_level_ms;
1003 const int64_t maximum = oxcf->maximum_buffer_size_ms;
1004
1005 rc->starting_buffer_level = starting * bandwidth / 1000;
1006 rc->optimal_buffer_level =
1007 (optimal == 0) ? bandwidth / 8 : optimal * bandwidth / 1000;
1008 rc->maximum_buffer_size =
1009 (maximum == 0) ? bandwidth / 8 : maximum * bandwidth / 1000;
1010}
1011
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001012#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001013#define HIGHBD_BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
1014 cpi->fn_ptr[BT].sdf = SDF; \
1015 cpi->fn_ptr[BT].sdaf = SDAF; \
1016 cpi->fn_ptr[BT].vf = VF; \
1017 cpi->fn_ptr[BT].svf = SVF; \
1018 cpi->fn_ptr[BT].svaf = SVAF; \
1019 cpi->fn_ptr[BT].sdx3f = SDX3F; \
1020 cpi->fn_ptr[BT].sdx8f = SDX8F; \
1021 cpi->fn_ptr[BT].sdx4df = SDX4DF;
1022
1023#define MAKE_BFP_SAD_WRAPPER(fnname) \
1024 static unsigned int fnname##_bits8(const uint8_t *src_ptr, \
1025 int source_stride, \
1026 const uint8_t *ref_ptr, int ref_stride) { \
1027 return fnname(src_ptr, source_stride, ref_ptr, ref_stride); \
1028 } \
1029 static unsigned int fnname##_bits10( \
1030 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1031 int ref_stride) { \
1032 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 2; \
1033 } \
1034 static unsigned int fnname##_bits12( \
1035 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1036 int ref_stride) { \
1037 return fnname(src_ptr, source_stride, ref_ptr, ref_stride) >> 4; \
1038 }
1039
1040#define MAKE_BFP_SADAVG_WRAPPER(fnname) \
1041 static unsigned int fnname##_bits8( \
1042 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1043 int ref_stride, const uint8_t *second_pred) { \
1044 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred); \
1045 } \
1046 static unsigned int fnname##_bits10( \
1047 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1048 int ref_stride, const uint8_t *second_pred) { \
1049 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
1050 2; \
1051 } \
1052 static unsigned int fnname##_bits12( \
1053 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1054 int ref_stride, const uint8_t *second_pred) { \
1055 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, second_pred) >> \
1056 4; \
1057 }
1058
1059#define MAKE_BFP_SAD3_WRAPPER(fnname) \
1060 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1061 const uint8_t *ref_ptr, int ref_stride, \
1062 unsigned int *sad_array) { \
1063 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1064 } \
1065 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1066 const uint8_t *ref_ptr, int ref_stride, \
1067 unsigned int *sad_array) { \
1068 int i; \
1069 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1070 for (i = 0; i < 3; i++) sad_array[i] >>= 2; \
1071 } \
1072 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1073 const uint8_t *ref_ptr, int ref_stride, \
1074 unsigned int *sad_array) { \
1075 int i; \
1076 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1077 for (i = 0; i < 3; i++) sad_array[i] >>= 4; \
1078 }
1079
1080#define MAKE_BFP_SAD8_WRAPPER(fnname) \
1081 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1082 const uint8_t *ref_ptr, int ref_stride, \
1083 unsigned int *sad_array) { \
1084 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1085 } \
1086 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1087 const uint8_t *ref_ptr, int ref_stride, \
1088 unsigned int *sad_array) { \
1089 int i; \
1090 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1091 for (i = 0; i < 8; i++) sad_array[i] >>= 2; \
1092 } \
1093 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1094 const uint8_t *ref_ptr, int ref_stride, \
1095 unsigned int *sad_array) { \
1096 int i; \
1097 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1098 for (i = 0; i < 8; i++) sad_array[i] >>= 4; \
1099 }
1100#define MAKE_BFP_SAD4D_WRAPPER(fnname) \
1101 static void fnname##_bits8(const uint8_t *src_ptr, int source_stride, \
1102 const uint8_t *const ref_ptr[], int ref_stride, \
1103 unsigned int *sad_array) { \
1104 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1105 } \
1106 static void fnname##_bits10(const uint8_t *src_ptr, int source_stride, \
1107 const uint8_t *const ref_ptr[], int ref_stride, \
1108 unsigned int *sad_array) { \
1109 int i; \
1110 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1111 for (i = 0; i < 4; i++) sad_array[i] >>= 2; \
1112 } \
1113 static void fnname##_bits12(const uint8_t *src_ptr, int source_stride, \
1114 const uint8_t *const ref_ptr[], int ref_stride, \
1115 unsigned int *sad_array) { \
1116 int i; \
1117 fnname(src_ptr, source_stride, ref_ptr, ref_stride, sad_array); \
1118 for (i = 0; i < 4; i++) sad_array[i] >>= 4; \
1119 }
1120
1121#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001122MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x128)
1123MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x128_avg)
1124MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad128x128x3)
1125MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad128x128x8)
1126MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x128x4d)
1127MAKE_BFP_SAD_WRAPPER(aom_highbd_sad128x64)
1128MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad128x64_avg)
1129MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad128x64x4d)
1130MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x128)
1131MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x128_avg)
1132MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001133#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001134MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x16)
1135MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x16_avg)
1136MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x16x4d)
1137MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x32)
1138MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x32_avg)
1139MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x32x4d)
1140MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x32)
1141MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x32_avg)
1142MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x32x4d)
1143MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x64)
1144MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x64_avg)
1145MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x64x4d)
1146MAKE_BFP_SAD_WRAPPER(aom_highbd_sad32x32)
1147MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad32x32_avg)
1148MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad32x32x3)
1149MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad32x32x8)
1150MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad32x32x4d)
1151MAKE_BFP_SAD_WRAPPER(aom_highbd_sad64x64)
1152MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad64x64_avg)
1153MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad64x64x3)
1154MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad64x64x8)
1155MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad64x64x4d)
1156MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x16)
1157MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x16_avg)
1158MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x16x3)
1159MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x16x8)
1160MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x16x4d)
1161MAKE_BFP_SAD_WRAPPER(aom_highbd_sad16x8)
1162MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad16x8_avg)
1163MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad16x8x3)
1164MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad16x8x8)
1165MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad16x8x4d)
1166MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x16)
1167MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x16_avg)
1168MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x16x3)
1169MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x16x8)
1170MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x16x4d)
1171MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x8)
1172MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x8_avg)
1173MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad8x8x3)
1174MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x8x8)
1175MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x8x4d)
1176MAKE_BFP_SAD_WRAPPER(aom_highbd_sad8x4)
1177MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad8x4_avg)
1178MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad8x4x8)
1179MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad8x4x4d)
1180MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x8)
1181MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x8_avg)
1182MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x8x8)
1183MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x8x4d)
1184MAKE_BFP_SAD_WRAPPER(aom_highbd_sad4x4)
1185MAKE_BFP_SADAVG_WRAPPER(aom_highbd_sad4x4_avg)
1186MAKE_BFP_SAD3_WRAPPER(aom_highbd_sad4x4x3)
1187MAKE_BFP_SAD8_WRAPPER(aom_highbd_sad4x4x8)
1188MAKE_BFP_SAD4D_WRAPPER(aom_highbd_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001189
1190#if CONFIG_EXT_INTER
David Barker0f3c94e2017-05-16 15:21:50 +01001191#define HIGHBD_MBFP(BT, MCSDF, MCSVF) \
David Barkerf19f35f2017-05-22 16:33:22 +01001192 cpi->fn_ptr[BT].msdf = MCSDF; \
1193 cpi->fn_ptr[BT].msvf = MCSVF;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001194
David Barkerc155e012017-05-11 13:54:54 +01001195#define MAKE_MBFP_COMPOUND_SAD_WRAPPER(fnname) \
1196 static unsigned int fnname##_bits8( \
1197 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1198 int ref_stride, const uint8_t *second_pred_ptr, const uint8_t *m, \
1199 int m_stride, int invert_mask) { \
1200 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, \
1201 second_pred_ptr, m, m_stride, invert_mask); \
1202 } \
1203 static unsigned int fnname##_bits10( \
1204 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1205 int ref_stride, const uint8_t *second_pred_ptr, const uint8_t *m, \
1206 int m_stride, int invert_mask) { \
1207 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, \
1208 second_pred_ptr, m, m_stride, invert_mask) >> \
1209 2; \
1210 } \
1211 static unsigned int fnname##_bits12( \
1212 const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, \
1213 int ref_stride, const uint8_t *second_pred_ptr, const uint8_t *m, \
1214 int m_stride, int invert_mask) { \
1215 return fnname(src_ptr, source_stride, ref_ptr, ref_stride, \
1216 second_pred_ptr, m, m_stride, invert_mask) >> \
1217 4; \
1218 }
1219
Yaowu Xuc27fc142016-08-22 16:08:15 -07001220#if CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001221MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad128x128)
1222MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad128x64)
1223MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001224#endif // CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001225MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad64x64)
1226MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad64x32)
1227MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad32x64)
1228MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad32x32)
1229MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad32x16)
1230MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad16x32)
1231MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad16x16)
1232MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad16x8)
1233MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad8x16)
1234MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad8x8)
1235MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad8x4)
1236MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad4x8)
1237MAKE_MBFP_COMPOUND_SAD_WRAPPER(aom_highbd_masked_sad4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001238#endif // CONFIG_EXT_INTER
1239
Yue Chencb60b182016-10-13 15:18:22 -07001240#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001241#define HIGHBD_OBFP(BT, OSDF, OVF, OSVF) \
1242 cpi->fn_ptr[BT].osdf = OSDF; \
1243 cpi->fn_ptr[BT].ovf = OVF; \
1244 cpi->fn_ptr[BT].osvf = OSVF;
1245
1246#define MAKE_OBFP_SAD_WRAPPER(fnname) \
1247 static unsigned int fnname##_bits8(const uint8_t *ref, int ref_stride, \
1248 const int32_t *wsrc, \
1249 const int32_t *msk) { \
1250 return fnname(ref, ref_stride, wsrc, msk); \
1251 } \
1252 static unsigned int fnname##_bits10(const uint8_t *ref, int ref_stride, \
1253 const int32_t *wsrc, \
1254 const int32_t *msk) { \
1255 return fnname(ref, ref_stride, wsrc, msk) >> 2; \
1256 } \
1257 static unsigned int fnname##_bits12(const uint8_t *ref, int ref_stride, \
1258 const int32_t *wsrc, \
1259 const int32_t *msk) { \
1260 return fnname(ref, ref_stride, wsrc, msk) >> 4; \
1261 }
1262
1263#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001264MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x128)
1265MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad128x64)
1266MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001267#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001268MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x64)
1269MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad64x32)
1270MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x64)
1271MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x32)
1272MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad32x16)
1273MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x32)
1274MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x16)
1275MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad16x8)
1276MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x16)
1277MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x8)
1278MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad8x4)
1279MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x8)
1280MAKE_OBFP_SAD_WRAPPER(aom_highbd_obmc_sad4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001281#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001282
Yaowu Xuf883b422016-08-30 14:01:10 -07001283static void highbd_set_var_fns(AV1_COMP *const cpi) {
1284 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001285 if (cm->use_highbitdepth) {
1286 switch (cm->bit_depth) {
Yaowu Xuf883b422016-08-30 14:01:10 -07001287 case AOM_BITS_8:
1288 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits8,
1289 aom_highbd_sad32x16_avg_bits8, aom_highbd_8_variance32x16,
1290 aom_highbd_8_sub_pixel_variance32x16,
1291 aom_highbd_8_sub_pixel_avg_variance32x16, NULL, NULL,
1292 aom_highbd_sad32x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001293
Yaowu Xuf883b422016-08-30 14:01:10 -07001294 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits8,
1295 aom_highbd_sad16x32_avg_bits8, aom_highbd_8_variance16x32,
1296 aom_highbd_8_sub_pixel_variance16x32,
1297 aom_highbd_8_sub_pixel_avg_variance16x32, NULL, NULL,
1298 aom_highbd_sad16x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001299
Yaowu Xuf883b422016-08-30 14:01:10 -07001300 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits8,
1301 aom_highbd_sad64x32_avg_bits8, aom_highbd_8_variance64x32,
1302 aom_highbd_8_sub_pixel_variance64x32,
1303 aom_highbd_8_sub_pixel_avg_variance64x32, NULL, NULL,
1304 aom_highbd_sad64x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001305
Yaowu Xuf883b422016-08-30 14:01:10 -07001306 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits8,
1307 aom_highbd_sad32x64_avg_bits8, aom_highbd_8_variance32x64,
1308 aom_highbd_8_sub_pixel_variance32x64,
1309 aom_highbd_8_sub_pixel_avg_variance32x64, NULL, NULL,
1310 aom_highbd_sad32x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001311
Yaowu Xuf883b422016-08-30 14:01:10 -07001312 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits8,
1313 aom_highbd_sad32x32_avg_bits8, aom_highbd_8_variance32x32,
1314 aom_highbd_8_sub_pixel_variance32x32,
1315 aom_highbd_8_sub_pixel_avg_variance32x32,
1316 aom_highbd_sad32x32x3_bits8, aom_highbd_sad32x32x8_bits8,
1317 aom_highbd_sad32x32x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001318
Yaowu Xuf883b422016-08-30 14:01:10 -07001319 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits8,
1320 aom_highbd_sad64x64_avg_bits8, aom_highbd_8_variance64x64,
1321 aom_highbd_8_sub_pixel_variance64x64,
1322 aom_highbd_8_sub_pixel_avg_variance64x64,
1323 aom_highbd_sad64x64x3_bits8, aom_highbd_sad64x64x8_bits8,
1324 aom_highbd_sad64x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001325
Yaowu Xuf883b422016-08-30 14:01:10 -07001326 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits8,
1327 aom_highbd_sad16x16_avg_bits8, aom_highbd_8_variance16x16,
1328 aom_highbd_8_sub_pixel_variance16x16,
1329 aom_highbd_8_sub_pixel_avg_variance16x16,
1330 aom_highbd_sad16x16x3_bits8, aom_highbd_sad16x16x8_bits8,
1331 aom_highbd_sad16x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001332
1333 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001334 BLOCK_16X8, aom_highbd_sad16x8_bits8, aom_highbd_sad16x8_avg_bits8,
1335 aom_highbd_8_variance16x8, aom_highbd_8_sub_pixel_variance16x8,
1336 aom_highbd_8_sub_pixel_avg_variance16x8, aom_highbd_sad16x8x3_bits8,
1337 aom_highbd_sad16x8x8_bits8, aom_highbd_sad16x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001338
1339 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001340 BLOCK_8X16, aom_highbd_sad8x16_bits8, aom_highbd_sad8x16_avg_bits8,
1341 aom_highbd_8_variance8x16, aom_highbd_8_sub_pixel_variance8x16,
1342 aom_highbd_8_sub_pixel_avg_variance8x16, aom_highbd_sad8x16x3_bits8,
1343 aom_highbd_sad8x16x8_bits8, aom_highbd_sad8x16x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001344
1345 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001346 BLOCK_8X8, aom_highbd_sad8x8_bits8, aom_highbd_sad8x8_avg_bits8,
1347 aom_highbd_8_variance8x8, aom_highbd_8_sub_pixel_variance8x8,
1348 aom_highbd_8_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits8,
1349 aom_highbd_sad8x8x8_bits8, aom_highbd_sad8x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001350
Yaowu Xuf883b422016-08-30 14:01:10 -07001351 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits8,
1352 aom_highbd_sad8x4_avg_bits8, aom_highbd_8_variance8x4,
1353 aom_highbd_8_sub_pixel_variance8x4,
1354 aom_highbd_8_sub_pixel_avg_variance8x4, NULL,
1355 aom_highbd_sad8x4x8_bits8, aom_highbd_sad8x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001356
Yaowu Xuf883b422016-08-30 14:01:10 -07001357 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits8,
1358 aom_highbd_sad4x8_avg_bits8, aom_highbd_8_variance4x8,
1359 aom_highbd_8_sub_pixel_variance4x8,
1360 aom_highbd_8_sub_pixel_avg_variance4x8, NULL,
1361 aom_highbd_sad4x8x8_bits8, aom_highbd_sad4x8x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001362
1363 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001364 BLOCK_4X4, aom_highbd_sad4x4_bits8, aom_highbd_sad4x4_avg_bits8,
1365 aom_highbd_8_variance4x4, aom_highbd_8_sub_pixel_variance4x4,
1366 aom_highbd_8_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits8,
1367 aom_highbd_sad4x4x8_bits8, aom_highbd_sad4x4x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001368
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001369#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
Jingning Hancc5bdf42016-12-19 11:14:30 -08001370 HIGHBD_BFP(BLOCK_2X2, NULL, NULL, aom_highbd_8_variance2x2, NULL, NULL,
1371 NULL, NULL, NULL)
1372 HIGHBD_BFP(BLOCK_4X2, NULL, NULL, aom_highbd_8_variance4x2, NULL, NULL,
1373 NULL, NULL, NULL)
1374 HIGHBD_BFP(BLOCK_2X4, NULL, NULL, aom_highbd_8_variance2x4, NULL, NULL,
1375 NULL, NULL, NULL)
1376#endif
1377
Yaowu Xuc27fc142016-08-22 16:08:15 -07001378#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001379 HIGHBD_BFP(BLOCK_128X128, aom_highbd_sad128x128_bits8,
1380 aom_highbd_sad128x128_avg_bits8,
1381 aom_highbd_8_variance128x128,
1382 aom_highbd_8_sub_pixel_variance128x128,
1383 aom_highbd_8_sub_pixel_avg_variance128x128,
1384 aom_highbd_sad128x128x3_bits8, aom_highbd_sad128x128x8_bits8,
1385 aom_highbd_sad128x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001386
Yaowu Xuf883b422016-08-30 14:01:10 -07001387 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits8,
1388 aom_highbd_sad128x64_avg_bits8, aom_highbd_8_variance128x64,
1389 aom_highbd_8_sub_pixel_variance128x64,
1390 aom_highbd_8_sub_pixel_avg_variance128x64, NULL, NULL,
1391 aom_highbd_sad128x64x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001392
Yaowu Xuf883b422016-08-30 14:01:10 -07001393 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits8,
1394 aom_highbd_sad64x128_avg_bits8, aom_highbd_8_variance64x128,
1395 aom_highbd_8_sub_pixel_variance64x128,
1396 aom_highbd_8_sub_pixel_avg_variance64x128, NULL, NULL,
1397 aom_highbd_sad64x128x4d_bits8)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001398#endif // CONFIG_EXT_PARTITION
1399
1400#if CONFIG_EXT_INTER
1401#if CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001402 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits8,
1403 aom_highbd_8_masked_sub_pixel_variance128x128)
1404 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits8,
1405 aom_highbd_8_masked_sub_pixel_variance128x64)
1406 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits8,
1407 aom_highbd_8_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001408#endif // CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001409 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits8,
1410 aom_highbd_8_masked_sub_pixel_variance64x64)
1411 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits8,
1412 aom_highbd_8_masked_sub_pixel_variance64x32)
1413 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits8,
1414 aom_highbd_8_masked_sub_pixel_variance32x64)
1415 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits8,
1416 aom_highbd_8_masked_sub_pixel_variance32x32)
1417 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits8,
1418 aom_highbd_8_masked_sub_pixel_variance32x16)
1419 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits8,
1420 aom_highbd_8_masked_sub_pixel_variance16x32)
1421 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits8,
1422 aom_highbd_8_masked_sub_pixel_variance16x16)
1423 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits8,
1424 aom_highbd_8_masked_sub_pixel_variance8x16)
1425 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits8,
1426 aom_highbd_8_masked_sub_pixel_variance16x8)
1427 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits8,
1428 aom_highbd_8_masked_sub_pixel_variance8x8)
1429 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits8,
1430 aom_highbd_8_masked_sub_pixel_variance4x8)
1431 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits8,
1432 aom_highbd_8_masked_sub_pixel_variance8x4)
1433 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits8,
1434 aom_highbd_8_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001435#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001436#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001437#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001438 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits8,
1439 aom_highbd_obmc_variance128x128,
1440 aom_highbd_obmc_sub_pixel_variance128x128)
1441 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits8,
1442 aom_highbd_obmc_variance128x64,
1443 aom_highbd_obmc_sub_pixel_variance128x64)
1444 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits8,
1445 aom_highbd_obmc_variance64x128,
1446 aom_highbd_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001447#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001448 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits8,
1449 aom_highbd_obmc_variance64x64,
1450 aom_highbd_obmc_sub_pixel_variance64x64)
1451 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits8,
1452 aom_highbd_obmc_variance64x32,
1453 aom_highbd_obmc_sub_pixel_variance64x32)
1454 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits8,
1455 aom_highbd_obmc_variance32x64,
1456 aom_highbd_obmc_sub_pixel_variance32x64)
1457 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits8,
1458 aom_highbd_obmc_variance32x32,
1459 aom_highbd_obmc_sub_pixel_variance32x32)
1460 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits8,
1461 aom_highbd_obmc_variance32x16,
1462 aom_highbd_obmc_sub_pixel_variance32x16)
1463 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits8,
1464 aom_highbd_obmc_variance16x32,
1465 aom_highbd_obmc_sub_pixel_variance16x32)
1466 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits8,
1467 aom_highbd_obmc_variance16x16,
1468 aom_highbd_obmc_sub_pixel_variance16x16)
1469 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits8,
1470 aom_highbd_obmc_variance8x16,
1471 aom_highbd_obmc_sub_pixel_variance8x16)
1472 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits8,
1473 aom_highbd_obmc_variance16x8,
1474 aom_highbd_obmc_sub_pixel_variance16x8)
1475 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits8,
1476 aom_highbd_obmc_variance8x8,
1477 aom_highbd_obmc_sub_pixel_variance8x8)
1478 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits8,
1479 aom_highbd_obmc_variance4x8,
1480 aom_highbd_obmc_sub_pixel_variance4x8)
1481 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits8,
1482 aom_highbd_obmc_variance8x4,
1483 aom_highbd_obmc_sub_pixel_variance8x4)
1484 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits8,
1485 aom_highbd_obmc_variance4x4,
1486 aom_highbd_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001487#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001488 break;
1489
Yaowu Xuf883b422016-08-30 14:01:10 -07001490 case AOM_BITS_10:
1491 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits10,
1492 aom_highbd_sad32x16_avg_bits10, aom_highbd_10_variance32x16,
1493 aom_highbd_10_sub_pixel_variance32x16,
1494 aom_highbd_10_sub_pixel_avg_variance32x16, NULL, NULL,
1495 aom_highbd_sad32x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001496
Yaowu Xuf883b422016-08-30 14:01:10 -07001497 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits10,
1498 aom_highbd_sad16x32_avg_bits10, aom_highbd_10_variance16x32,
1499 aom_highbd_10_sub_pixel_variance16x32,
1500 aom_highbd_10_sub_pixel_avg_variance16x32, NULL, NULL,
1501 aom_highbd_sad16x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001502
Yaowu Xuf883b422016-08-30 14:01:10 -07001503 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits10,
1504 aom_highbd_sad64x32_avg_bits10, aom_highbd_10_variance64x32,
1505 aom_highbd_10_sub_pixel_variance64x32,
1506 aom_highbd_10_sub_pixel_avg_variance64x32, NULL, NULL,
1507 aom_highbd_sad64x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001508
Yaowu Xuf883b422016-08-30 14:01:10 -07001509 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits10,
1510 aom_highbd_sad32x64_avg_bits10, aom_highbd_10_variance32x64,
1511 aom_highbd_10_sub_pixel_variance32x64,
1512 aom_highbd_10_sub_pixel_avg_variance32x64, NULL, NULL,
1513 aom_highbd_sad32x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001514
Yaowu Xuf883b422016-08-30 14:01:10 -07001515 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits10,
1516 aom_highbd_sad32x32_avg_bits10, aom_highbd_10_variance32x32,
1517 aom_highbd_10_sub_pixel_variance32x32,
1518 aom_highbd_10_sub_pixel_avg_variance32x32,
1519 aom_highbd_sad32x32x3_bits10, aom_highbd_sad32x32x8_bits10,
1520 aom_highbd_sad32x32x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001521
Yaowu Xuf883b422016-08-30 14:01:10 -07001522 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits10,
1523 aom_highbd_sad64x64_avg_bits10, aom_highbd_10_variance64x64,
1524 aom_highbd_10_sub_pixel_variance64x64,
1525 aom_highbd_10_sub_pixel_avg_variance64x64,
1526 aom_highbd_sad64x64x3_bits10, aom_highbd_sad64x64x8_bits10,
1527 aom_highbd_sad64x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001528
Yaowu Xuf883b422016-08-30 14:01:10 -07001529 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits10,
1530 aom_highbd_sad16x16_avg_bits10, aom_highbd_10_variance16x16,
1531 aom_highbd_10_sub_pixel_variance16x16,
1532 aom_highbd_10_sub_pixel_avg_variance16x16,
1533 aom_highbd_sad16x16x3_bits10, aom_highbd_sad16x16x8_bits10,
1534 aom_highbd_sad16x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001535
Yaowu Xuf883b422016-08-30 14:01:10 -07001536 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits10,
1537 aom_highbd_sad16x8_avg_bits10, aom_highbd_10_variance16x8,
1538 aom_highbd_10_sub_pixel_variance16x8,
1539 aom_highbd_10_sub_pixel_avg_variance16x8,
1540 aom_highbd_sad16x8x3_bits10, aom_highbd_sad16x8x8_bits10,
1541 aom_highbd_sad16x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001542
Yaowu Xuf883b422016-08-30 14:01:10 -07001543 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits10,
1544 aom_highbd_sad8x16_avg_bits10, aom_highbd_10_variance8x16,
1545 aom_highbd_10_sub_pixel_variance8x16,
1546 aom_highbd_10_sub_pixel_avg_variance8x16,
1547 aom_highbd_sad8x16x3_bits10, aom_highbd_sad8x16x8_bits10,
1548 aom_highbd_sad8x16x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001549
1550 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001551 BLOCK_8X8, aom_highbd_sad8x8_bits10, aom_highbd_sad8x8_avg_bits10,
1552 aom_highbd_10_variance8x8, aom_highbd_10_sub_pixel_variance8x8,
1553 aom_highbd_10_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits10,
1554 aom_highbd_sad8x8x8_bits10, aom_highbd_sad8x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001555
Yaowu Xuf883b422016-08-30 14:01:10 -07001556 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits10,
1557 aom_highbd_sad8x4_avg_bits10, aom_highbd_10_variance8x4,
1558 aom_highbd_10_sub_pixel_variance8x4,
1559 aom_highbd_10_sub_pixel_avg_variance8x4, NULL,
1560 aom_highbd_sad8x4x8_bits10, aom_highbd_sad8x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001561
Yaowu Xuf883b422016-08-30 14:01:10 -07001562 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits10,
1563 aom_highbd_sad4x8_avg_bits10, aom_highbd_10_variance4x8,
1564 aom_highbd_10_sub_pixel_variance4x8,
1565 aom_highbd_10_sub_pixel_avg_variance4x8, NULL,
1566 aom_highbd_sad4x8x8_bits10, aom_highbd_sad4x8x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001567
1568 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001569 BLOCK_4X4, aom_highbd_sad4x4_bits10, aom_highbd_sad4x4_avg_bits10,
1570 aom_highbd_10_variance4x4, aom_highbd_10_sub_pixel_variance4x4,
1571 aom_highbd_10_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits10,
1572 aom_highbd_sad4x4x8_bits10, aom_highbd_sad4x4x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001573
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001574#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
Jingning Hancc5bdf42016-12-19 11:14:30 -08001575 HIGHBD_BFP(BLOCK_2X2, NULL, NULL, aom_highbd_10_variance2x2, NULL, NULL,
1576 NULL, NULL, NULL)
1577 HIGHBD_BFP(BLOCK_4X2, NULL, NULL, aom_highbd_10_variance4x2, NULL, NULL,
1578 NULL, NULL, NULL)
1579 HIGHBD_BFP(BLOCK_2X4, NULL, NULL, aom_highbd_10_variance2x4, NULL, NULL,
1580 NULL, NULL, NULL)
1581#endif
1582
Yaowu Xuc27fc142016-08-22 16:08:15 -07001583#if CONFIG_EXT_PARTITION
1584 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001585 BLOCK_128X128, aom_highbd_sad128x128_bits10,
1586 aom_highbd_sad128x128_avg_bits10, aom_highbd_10_variance128x128,
1587 aom_highbd_10_sub_pixel_variance128x128,
1588 aom_highbd_10_sub_pixel_avg_variance128x128,
1589 aom_highbd_sad128x128x3_bits10, aom_highbd_sad128x128x8_bits10,
1590 aom_highbd_sad128x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001591
Yaowu Xuf883b422016-08-30 14:01:10 -07001592 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits10,
1593 aom_highbd_sad128x64_avg_bits10,
1594 aom_highbd_10_variance128x64,
1595 aom_highbd_10_sub_pixel_variance128x64,
1596 aom_highbd_10_sub_pixel_avg_variance128x64, NULL, NULL,
1597 aom_highbd_sad128x64x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001598
Yaowu Xuf883b422016-08-30 14:01:10 -07001599 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits10,
1600 aom_highbd_sad64x128_avg_bits10,
1601 aom_highbd_10_variance64x128,
1602 aom_highbd_10_sub_pixel_variance64x128,
1603 aom_highbd_10_sub_pixel_avg_variance64x128, NULL, NULL,
1604 aom_highbd_sad64x128x4d_bits10)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001605#endif // CONFIG_EXT_PARTITION
1606
1607#if CONFIG_EXT_INTER
1608#if CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001609 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits10,
1610 aom_highbd_10_masked_sub_pixel_variance128x128)
1611 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits10,
1612 aom_highbd_10_masked_sub_pixel_variance128x64)
1613 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits10,
1614 aom_highbd_10_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001615#endif // CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001616 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits10,
1617 aom_highbd_10_masked_sub_pixel_variance64x64)
1618 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits10,
1619 aom_highbd_10_masked_sub_pixel_variance64x32)
1620 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits10,
1621 aom_highbd_10_masked_sub_pixel_variance32x64)
1622 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits10,
1623 aom_highbd_10_masked_sub_pixel_variance32x32)
1624 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits10,
1625 aom_highbd_10_masked_sub_pixel_variance32x16)
1626 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits10,
1627 aom_highbd_10_masked_sub_pixel_variance16x32)
1628 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits10,
1629 aom_highbd_10_masked_sub_pixel_variance16x16)
1630 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits10,
1631 aom_highbd_10_masked_sub_pixel_variance8x16)
1632 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits10,
1633 aom_highbd_10_masked_sub_pixel_variance16x8)
1634 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits10,
1635 aom_highbd_10_masked_sub_pixel_variance8x8)
1636 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits10,
1637 aom_highbd_10_masked_sub_pixel_variance4x8)
1638 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits10,
1639 aom_highbd_10_masked_sub_pixel_variance8x4)
1640 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits10,
1641 aom_highbd_10_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001642#endif // CONFIG_EXT_INTER
Yue Chencb60b182016-10-13 15:18:22 -07001643#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001644#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001645 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits10,
1646 aom_highbd_10_obmc_variance128x128,
1647 aom_highbd_10_obmc_sub_pixel_variance128x128)
1648 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits10,
1649 aom_highbd_10_obmc_variance128x64,
1650 aom_highbd_10_obmc_sub_pixel_variance128x64)
1651 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits10,
1652 aom_highbd_10_obmc_variance64x128,
1653 aom_highbd_10_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001654#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001655 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits10,
1656 aom_highbd_10_obmc_variance64x64,
1657 aom_highbd_10_obmc_sub_pixel_variance64x64)
1658 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits10,
1659 aom_highbd_10_obmc_variance64x32,
1660 aom_highbd_10_obmc_sub_pixel_variance64x32)
1661 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits10,
1662 aom_highbd_10_obmc_variance32x64,
1663 aom_highbd_10_obmc_sub_pixel_variance32x64)
1664 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits10,
1665 aom_highbd_10_obmc_variance32x32,
1666 aom_highbd_10_obmc_sub_pixel_variance32x32)
1667 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits10,
1668 aom_highbd_10_obmc_variance32x16,
1669 aom_highbd_10_obmc_sub_pixel_variance32x16)
1670 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits10,
1671 aom_highbd_10_obmc_variance16x32,
1672 aom_highbd_10_obmc_sub_pixel_variance16x32)
1673 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits10,
1674 aom_highbd_10_obmc_variance16x16,
1675 aom_highbd_10_obmc_sub_pixel_variance16x16)
1676 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits10,
1677 aom_highbd_10_obmc_variance8x16,
1678 aom_highbd_10_obmc_sub_pixel_variance8x16)
1679 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits10,
1680 aom_highbd_10_obmc_variance16x8,
1681 aom_highbd_10_obmc_sub_pixel_variance16x8)
1682 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits10,
1683 aom_highbd_10_obmc_variance8x8,
1684 aom_highbd_10_obmc_sub_pixel_variance8x8)
1685 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits10,
1686 aom_highbd_10_obmc_variance4x8,
1687 aom_highbd_10_obmc_sub_pixel_variance4x8)
1688 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits10,
1689 aom_highbd_10_obmc_variance8x4,
1690 aom_highbd_10_obmc_sub_pixel_variance8x4)
1691 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits10,
1692 aom_highbd_10_obmc_variance4x4,
1693 aom_highbd_10_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001694#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001695 break;
1696
Yaowu Xuf883b422016-08-30 14:01:10 -07001697 case AOM_BITS_12:
1698 HIGHBD_BFP(BLOCK_32X16, aom_highbd_sad32x16_bits12,
1699 aom_highbd_sad32x16_avg_bits12, aom_highbd_12_variance32x16,
1700 aom_highbd_12_sub_pixel_variance32x16,
1701 aom_highbd_12_sub_pixel_avg_variance32x16, NULL, NULL,
1702 aom_highbd_sad32x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001703
Yaowu Xuf883b422016-08-30 14:01:10 -07001704 HIGHBD_BFP(BLOCK_16X32, aom_highbd_sad16x32_bits12,
1705 aom_highbd_sad16x32_avg_bits12, aom_highbd_12_variance16x32,
1706 aom_highbd_12_sub_pixel_variance16x32,
1707 aom_highbd_12_sub_pixel_avg_variance16x32, NULL, NULL,
1708 aom_highbd_sad16x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001709
Yaowu Xuf883b422016-08-30 14:01:10 -07001710 HIGHBD_BFP(BLOCK_64X32, aom_highbd_sad64x32_bits12,
1711 aom_highbd_sad64x32_avg_bits12, aom_highbd_12_variance64x32,
1712 aom_highbd_12_sub_pixel_variance64x32,
1713 aom_highbd_12_sub_pixel_avg_variance64x32, NULL, NULL,
1714 aom_highbd_sad64x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001715
Yaowu Xuf883b422016-08-30 14:01:10 -07001716 HIGHBD_BFP(BLOCK_32X64, aom_highbd_sad32x64_bits12,
1717 aom_highbd_sad32x64_avg_bits12, aom_highbd_12_variance32x64,
1718 aom_highbd_12_sub_pixel_variance32x64,
1719 aom_highbd_12_sub_pixel_avg_variance32x64, NULL, NULL,
1720 aom_highbd_sad32x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001721
Yaowu Xuf883b422016-08-30 14:01:10 -07001722 HIGHBD_BFP(BLOCK_32X32, aom_highbd_sad32x32_bits12,
1723 aom_highbd_sad32x32_avg_bits12, aom_highbd_12_variance32x32,
1724 aom_highbd_12_sub_pixel_variance32x32,
1725 aom_highbd_12_sub_pixel_avg_variance32x32,
1726 aom_highbd_sad32x32x3_bits12, aom_highbd_sad32x32x8_bits12,
1727 aom_highbd_sad32x32x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001728
Yaowu Xuf883b422016-08-30 14:01:10 -07001729 HIGHBD_BFP(BLOCK_64X64, aom_highbd_sad64x64_bits12,
1730 aom_highbd_sad64x64_avg_bits12, aom_highbd_12_variance64x64,
1731 aom_highbd_12_sub_pixel_variance64x64,
1732 aom_highbd_12_sub_pixel_avg_variance64x64,
1733 aom_highbd_sad64x64x3_bits12, aom_highbd_sad64x64x8_bits12,
1734 aom_highbd_sad64x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001735
Yaowu Xuf883b422016-08-30 14:01:10 -07001736 HIGHBD_BFP(BLOCK_16X16, aom_highbd_sad16x16_bits12,
1737 aom_highbd_sad16x16_avg_bits12, aom_highbd_12_variance16x16,
1738 aom_highbd_12_sub_pixel_variance16x16,
1739 aom_highbd_12_sub_pixel_avg_variance16x16,
1740 aom_highbd_sad16x16x3_bits12, aom_highbd_sad16x16x8_bits12,
1741 aom_highbd_sad16x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001742
Yaowu Xuf883b422016-08-30 14:01:10 -07001743 HIGHBD_BFP(BLOCK_16X8, aom_highbd_sad16x8_bits12,
1744 aom_highbd_sad16x8_avg_bits12, aom_highbd_12_variance16x8,
1745 aom_highbd_12_sub_pixel_variance16x8,
1746 aom_highbd_12_sub_pixel_avg_variance16x8,
1747 aom_highbd_sad16x8x3_bits12, aom_highbd_sad16x8x8_bits12,
1748 aom_highbd_sad16x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001749
Yaowu Xuf883b422016-08-30 14:01:10 -07001750 HIGHBD_BFP(BLOCK_8X16, aom_highbd_sad8x16_bits12,
1751 aom_highbd_sad8x16_avg_bits12, aom_highbd_12_variance8x16,
1752 aom_highbd_12_sub_pixel_variance8x16,
1753 aom_highbd_12_sub_pixel_avg_variance8x16,
1754 aom_highbd_sad8x16x3_bits12, aom_highbd_sad8x16x8_bits12,
1755 aom_highbd_sad8x16x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001756
1757 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001758 BLOCK_8X8, aom_highbd_sad8x8_bits12, aom_highbd_sad8x8_avg_bits12,
1759 aom_highbd_12_variance8x8, aom_highbd_12_sub_pixel_variance8x8,
1760 aom_highbd_12_sub_pixel_avg_variance8x8, aom_highbd_sad8x8x3_bits12,
1761 aom_highbd_sad8x8x8_bits12, aom_highbd_sad8x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001762
Yaowu Xuf883b422016-08-30 14:01:10 -07001763 HIGHBD_BFP(BLOCK_8X4, aom_highbd_sad8x4_bits12,
1764 aom_highbd_sad8x4_avg_bits12, aom_highbd_12_variance8x4,
1765 aom_highbd_12_sub_pixel_variance8x4,
1766 aom_highbd_12_sub_pixel_avg_variance8x4, NULL,
1767 aom_highbd_sad8x4x8_bits12, aom_highbd_sad8x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001768
Yaowu Xuf883b422016-08-30 14:01:10 -07001769 HIGHBD_BFP(BLOCK_4X8, aom_highbd_sad4x8_bits12,
1770 aom_highbd_sad4x8_avg_bits12, aom_highbd_12_variance4x8,
1771 aom_highbd_12_sub_pixel_variance4x8,
1772 aom_highbd_12_sub_pixel_avg_variance4x8, NULL,
1773 aom_highbd_sad4x8x8_bits12, aom_highbd_sad4x8x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001774
1775 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001776 BLOCK_4X4, aom_highbd_sad4x4_bits12, aom_highbd_sad4x4_avg_bits12,
1777 aom_highbd_12_variance4x4, aom_highbd_12_sub_pixel_variance4x4,
1778 aom_highbd_12_sub_pixel_avg_variance4x4, aom_highbd_sad4x4x3_bits12,
1779 aom_highbd_sad4x4x8_bits12, aom_highbd_sad4x4x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001780
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07001781#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
Jingning Hancc5bdf42016-12-19 11:14:30 -08001782 HIGHBD_BFP(BLOCK_2X2, NULL, NULL, aom_highbd_12_variance2x2, NULL, NULL,
1783 NULL, NULL, NULL)
1784 HIGHBD_BFP(BLOCK_4X2, NULL, NULL, aom_highbd_12_variance4x2, NULL, NULL,
1785 NULL, NULL, NULL)
1786 HIGHBD_BFP(BLOCK_2X4, NULL, NULL, aom_highbd_12_variance2x4, NULL, NULL,
1787 NULL, NULL, NULL)
1788#endif
1789
Yaowu Xuc27fc142016-08-22 16:08:15 -07001790#if CONFIG_EXT_PARTITION
1791 HIGHBD_BFP(
Yaowu Xuf883b422016-08-30 14:01:10 -07001792 BLOCK_128X128, aom_highbd_sad128x128_bits12,
1793 aom_highbd_sad128x128_avg_bits12, aom_highbd_12_variance128x128,
1794 aom_highbd_12_sub_pixel_variance128x128,
1795 aom_highbd_12_sub_pixel_avg_variance128x128,
1796 aom_highbd_sad128x128x3_bits12, aom_highbd_sad128x128x8_bits12,
1797 aom_highbd_sad128x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001798
Yaowu Xuf883b422016-08-30 14:01:10 -07001799 HIGHBD_BFP(BLOCK_128X64, aom_highbd_sad128x64_bits12,
1800 aom_highbd_sad128x64_avg_bits12,
1801 aom_highbd_12_variance128x64,
1802 aom_highbd_12_sub_pixel_variance128x64,
1803 aom_highbd_12_sub_pixel_avg_variance128x64, NULL, NULL,
1804 aom_highbd_sad128x64x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001805
Yaowu Xuf883b422016-08-30 14:01:10 -07001806 HIGHBD_BFP(BLOCK_64X128, aom_highbd_sad64x128_bits12,
1807 aom_highbd_sad64x128_avg_bits12,
1808 aom_highbd_12_variance64x128,
1809 aom_highbd_12_sub_pixel_variance64x128,
1810 aom_highbd_12_sub_pixel_avg_variance64x128, NULL, NULL,
1811 aom_highbd_sad64x128x4d_bits12)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001812#endif // CONFIG_EXT_PARTITION
1813
1814#if CONFIG_EXT_INTER
1815#if CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001816 HIGHBD_MBFP(BLOCK_128X128, aom_highbd_masked_sad128x128_bits12,
1817 aom_highbd_12_masked_sub_pixel_variance128x128)
1818 HIGHBD_MBFP(BLOCK_128X64, aom_highbd_masked_sad128x64_bits12,
1819 aom_highbd_12_masked_sub_pixel_variance128x64)
1820 HIGHBD_MBFP(BLOCK_64X128, aom_highbd_masked_sad64x128_bits12,
1821 aom_highbd_12_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001822#endif // CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01001823 HIGHBD_MBFP(BLOCK_64X64, aom_highbd_masked_sad64x64_bits12,
1824 aom_highbd_12_masked_sub_pixel_variance64x64)
1825 HIGHBD_MBFP(BLOCK_64X32, aom_highbd_masked_sad64x32_bits12,
1826 aom_highbd_12_masked_sub_pixel_variance64x32)
1827 HIGHBD_MBFP(BLOCK_32X64, aom_highbd_masked_sad32x64_bits12,
1828 aom_highbd_12_masked_sub_pixel_variance32x64)
1829 HIGHBD_MBFP(BLOCK_32X32, aom_highbd_masked_sad32x32_bits12,
1830 aom_highbd_12_masked_sub_pixel_variance32x32)
1831 HIGHBD_MBFP(BLOCK_32X16, aom_highbd_masked_sad32x16_bits12,
1832 aom_highbd_12_masked_sub_pixel_variance32x16)
1833 HIGHBD_MBFP(BLOCK_16X32, aom_highbd_masked_sad16x32_bits12,
1834 aom_highbd_12_masked_sub_pixel_variance16x32)
1835 HIGHBD_MBFP(BLOCK_16X16, aom_highbd_masked_sad16x16_bits12,
1836 aom_highbd_12_masked_sub_pixel_variance16x16)
1837 HIGHBD_MBFP(BLOCK_8X16, aom_highbd_masked_sad8x16_bits12,
1838 aom_highbd_12_masked_sub_pixel_variance8x16)
1839 HIGHBD_MBFP(BLOCK_16X8, aom_highbd_masked_sad16x8_bits12,
1840 aom_highbd_12_masked_sub_pixel_variance16x8)
1841 HIGHBD_MBFP(BLOCK_8X8, aom_highbd_masked_sad8x8_bits12,
1842 aom_highbd_12_masked_sub_pixel_variance8x8)
1843 HIGHBD_MBFP(BLOCK_4X8, aom_highbd_masked_sad4x8_bits12,
1844 aom_highbd_12_masked_sub_pixel_variance4x8)
1845 HIGHBD_MBFP(BLOCK_8X4, aom_highbd_masked_sad8x4_bits12,
1846 aom_highbd_12_masked_sub_pixel_variance8x4)
1847 HIGHBD_MBFP(BLOCK_4X4, aom_highbd_masked_sad4x4_bits12,
1848 aom_highbd_12_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001849#endif // CONFIG_EXT_INTER
1850
Yue Chencb60b182016-10-13 15:18:22 -07001851#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001852#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001853 HIGHBD_OBFP(BLOCK_128X128, aom_highbd_obmc_sad128x128_bits12,
1854 aom_highbd_12_obmc_variance128x128,
1855 aom_highbd_12_obmc_sub_pixel_variance128x128)
1856 HIGHBD_OBFP(BLOCK_128X64, aom_highbd_obmc_sad128x64_bits12,
1857 aom_highbd_12_obmc_variance128x64,
1858 aom_highbd_12_obmc_sub_pixel_variance128x64)
1859 HIGHBD_OBFP(BLOCK_64X128, aom_highbd_obmc_sad64x128_bits12,
1860 aom_highbd_12_obmc_variance64x128,
1861 aom_highbd_12_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07001862#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07001863 HIGHBD_OBFP(BLOCK_64X64, aom_highbd_obmc_sad64x64_bits12,
1864 aom_highbd_12_obmc_variance64x64,
1865 aom_highbd_12_obmc_sub_pixel_variance64x64)
1866 HIGHBD_OBFP(BLOCK_64X32, aom_highbd_obmc_sad64x32_bits12,
1867 aom_highbd_12_obmc_variance64x32,
1868 aom_highbd_12_obmc_sub_pixel_variance64x32)
1869 HIGHBD_OBFP(BLOCK_32X64, aom_highbd_obmc_sad32x64_bits12,
1870 aom_highbd_12_obmc_variance32x64,
1871 aom_highbd_12_obmc_sub_pixel_variance32x64)
1872 HIGHBD_OBFP(BLOCK_32X32, aom_highbd_obmc_sad32x32_bits12,
1873 aom_highbd_12_obmc_variance32x32,
1874 aom_highbd_12_obmc_sub_pixel_variance32x32)
1875 HIGHBD_OBFP(BLOCK_32X16, aom_highbd_obmc_sad32x16_bits12,
1876 aom_highbd_12_obmc_variance32x16,
1877 aom_highbd_12_obmc_sub_pixel_variance32x16)
1878 HIGHBD_OBFP(BLOCK_16X32, aom_highbd_obmc_sad16x32_bits12,
1879 aom_highbd_12_obmc_variance16x32,
1880 aom_highbd_12_obmc_sub_pixel_variance16x32)
1881 HIGHBD_OBFP(BLOCK_16X16, aom_highbd_obmc_sad16x16_bits12,
1882 aom_highbd_12_obmc_variance16x16,
1883 aom_highbd_12_obmc_sub_pixel_variance16x16)
1884 HIGHBD_OBFP(BLOCK_8X16, aom_highbd_obmc_sad8x16_bits12,
1885 aom_highbd_12_obmc_variance8x16,
1886 aom_highbd_12_obmc_sub_pixel_variance8x16)
1887 HIGHBD_OBFP(BLOCK_16X8, aom_highbd_obmc_sad16x8_bits12,
1888 aom_highbd_12_obmc_variance16x8,
1889 aom_highbd_12_obmc_sub_pixel_variance16x8)
1890 HIGHBD_OBFP(BLOCK_8X8, aom_highbd_obmc_sad8x8_bits12,
1891 aom_highbd_12_obmc_variance8x8,
1892 aom_highbd_12_obmc_sub_pixel_variance8x8)
1893 HIGHBD_OBFP(BLOCK_4X8, aom_highbd_obmc_sad4x8_bits12,
1894 aom_highbd_12_obmc_variance4x8,
1895 aom_highbd_12_obmc_sub_pixel_variance4x8)
1896 HIGHBD_OBFP(BLOCK_8X4, aom_highbd_obmc_sad8x4_bits12,
1897 aom_highbd_12_obmc_variance8x4,
1898 aom_highbd_12_obmc_sub_pixel_variance8x4)
1899 HIGHBD_OBFP(BLOCK_4X4, aom_highbd_obmc_sad4x4_bits12,
1900 aom_highbd_12_obmc_variance4x4,
1901 aom_highbd_12_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07001902#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07001903 break;
1904
1905 default:
1906 assert(0 &&
Yaowu Xuf883b422016-08-30 14:01:10 -07001907 "cm->bit_depth should be AOM_BITS_8, "
1908 "AOM_BITS_10 or AOM_BITS_12");
Yaowu Xuc27fc142016-08-22 16:08:15 -07001909 }
1910 }
1911}
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02001912#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07001913
Yaowu Xuf883b422016-08-30 14:01:10 -07001914static void realloc_segmentation_maps(AV1_COMP *cpi) {
1915 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001916
1917 // Create the encoder segmentation map and set all entries to 0
Yaowu Xuf883b422016-08-30 14:01:10 -07001918 aom_free(cpi->segmentation_map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001919 CHECK_MEM_ERROR(cm, cpi->segmentation_map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001920 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001921
1922 // Create a map used for cyclic background refresh.
Yaowu Xuf883b422016-08-30 14:01:10 -07001923 if (cpi->cyclic_refresh) av1_cyclic_refresh_free(cpi->cyclic_refresh);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001924 CHECK_MEM_ERROR(cm, cpi->cyclic_refresh,
Yaowu Xuf883b422016-08-30 14:01:10 -07001925 av1_cyclic_refresh_alloc(cm->mi_rows, cm->mi_cols));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001926
1927 // Create a map used to mark inactive areas.
Yaowu Xuf883b422016-08-30 14:01:10 -07001928 aom_free(cpi->active_map.map);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001929 CHECK_MEM_ERROR(cm, cpi->active_map.map,
Yaowu Xuf883b422016-08-30 14:01:10 -07001930 aom_calloc(cm->mi_rows * cm->mi_cols, 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001931}
1932
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07001933#if CONFIG_EXT_INTER
1934void set_compound_tools(AV1_COMMON *cm) {
1935 (void)cm;
1936#if CONFIG_INTERINTRA
1937 cm->allow_interintra_compound = 1;
1938#endif // CONFIG_INTERINTRA
1939#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
1940 cm->allow_masked_compound = 1;
1941#endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
1942}
1943#endif // CONFIG_EXT_INTER
1944
Yaowu Xuf883b422016-08-30 14:01:10 -07001945void av1_change_config(struct AV1_COMP *cpi, const AV1EncoderConfig *oxcf) {
1946 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001947 RATE_CONTROL *const rc = &cpi->rc;
1948
1949 if (cm->profile != oxcf->profile) cm->profile = oxcf->profile;
1950 cm->bit_depth = oxcf->bit_depth;
1951 cm->color_space = oxcf->color_space;
anorkin76fb1262017-03-22 15:12:12 -07001952#if CONFIG_COLORSPACE_HEADERS
1953 cm->transfer_function = oxcf->transfer_function;
1954 cm->chroma_sample_position = oxcf->chroma_sample_position;
1955#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07001956 cm->color_range = oxcf->color_range;
1957
1958 if (cm->profile <= PROFILE_1)
Yaowu Xuf883b422016-08-30 14:01:10 -07001959 assert(cm->bit_depth == AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001960 else
Yaowu Xuf883b422016-08-30 14:01:10 -07001961 assert(cm->bit_depth > AOM_BITS_8);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001962
1963 cpi->oxcf = *oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001964 cpi->td.mb.e_mbd.bd = (int)cm->bit_depth;
Yaowu Xuc27fc142016-08-22 16:08:15 -07001965#if CONFIG_GLOBAL_MOTION
1966 cpi->td.mb.e_mbd.global_motion = cm->global_motion;
1967#endif // CONFIG_GLOBAL_MOTION
1968
Yaowu Xuf883b422016-08-30 14:01:10 -07001969 if ((oxcf->pass == 0) && (oxcf->rc_mode == AOM_Q)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07001970 rc->baseline_gf_interval = FIXED_GF_INTERVAL;
1971 } else {
1972 rc->baseline_gf_interval = (MIN_GF_INTERVAL + MAX_GF_INTERVAL) / 2;
1973 }
1974
1975 cpi->refresh_last_frame = 1;
1976 cpi->refresh_golden_frame = 0;
1977#if CONFIG_EXT_REFS
1978 cpi->refresh_bwd_ref_frame = 0;
1979#endif // CONFIG_EXT_REFS
1980
1981 cm->refresh_frame_context =
1982 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
1983 ? REFRESH_FRAME_CONTEXT_FORWARD
1984 : REFRESH_FRAME_CONTEXT_BACKWARD;
1985 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
1986
Urvang Joshib100db72016-10-12 16:28:56 -07001987#if CONFIG_PALETTE
Yaowu Xuf883b422016-08-30 14:01:10 -07001988 cm->allow_screen_content_tools = (cpi->oxcf.content == AOM_CONTENT_SCREEN);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001989 if (cm->allow_screen_content_tools) {
1990 MACROBLOCK *x = &cpi->td.mb;
1991 if (x->palette_buffer == 0) {
1992 CHECK_MEM_ERROR(cm, x->palette_buffer,
Yaowu Xuf883b422016-08-30 14:01:10 -07001993 aom_memalign(16, sizeof(*x->palette_buffer)));
Yaowu Xuc27fc142016-08-22 16:08:15 -07001994 }
1995 // Reallocate the pc_tree, as it's contents depends on
1996 // the state of cm->allow_screen_content_tools
Yaowu Xuf883b422016-08-30 14:01:10 -07001997 av1_free_pc_tree(&cpi->td);
1998 av1_setup_pc_tree(&cpi->common, &cpi->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07001999 }
Urvang Joshib100db72016-10-12 16:28:56 -07002000#endif // CONFIG_PALETTE
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07002001#if CONFIG_EXT_INTER
2002 set_compound_tools(cm);
2003#endif // CONFIG_EXT_INTER
Yaowu Xuf883b422016-08-30 14:01:10 -07002004 av1_reset_segment_features(cm);
2005 av1_set_high_precision_mv(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002006
Yaowu Xuc27fc142016-08-22 16:08:15 -07002007 set_rc_buffer_sizes(rc, &cpi->oxcf);
2008
2009 // Under a configuration change, where maximum_buffer_size may change,
2010 // keep buffer level clipped to the maximum allowed buffer size.
Yaowu Xuf883b422016-08-30 14:01:10 -07002011 rc->bits_off_target = AOMMIN(rc->bits_off_target, rc->maximum_buffer_size);
2012 rc->buffer_level = AOMMIN(rc->buffer_level, rc->maximum_buffer_size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002013
2014 // Set up frame rate and related parameters rate control values.
Yaowu Xuf883b422016-08-30 14:01:10 -07002015 av1_new_framerate(cpi, cpi->framerate);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002016
2017 // Set absolute upper and lower quality limits
2018 rc->worst_quality = cpi->oxcf.worst_allowed_q;
2019 rc->best_quality = cpi->oxcf.best_allowed_q;
2020
2021 cm->interp_filter = cpi->sf.default_interp_filter;
2022
2023 if (cpi->oxcf.render_width > 0 && cpi->oxcf.render_height > 0) {
2024 cm->render_width = cpi->oxcf.render_width;
2025 cm->render_height = cpi->oxcf.render_height;
2026 } else {
2027 cm->render_width = cpi->oxcf.width;
2028 cm->render_height = cpi->oxcf.height;
2029 }
2030 cm->width = cpi->oxcf.width;
2031 cm->height = cpi->oxcf.height;
2032
2033 if (cpi->initial_width) {
2034 if (cm->width > cpi->initial_width || cm->height > cpi->initial_height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002035 av1_free_context_buffers(cm);
2036 av1_alloc_compressor_data(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002037 realloc_segmentation_maps(cpi);
2038 cpi->initial_width = cpi->initial_height = 0;
2039 }
2040 }
2041 update_frame_size(cpi);
2042
2043 cpi->alt_ref_source = NULL;
2044 rc->is_src_frame_alt_ref = 0;
2045
2046#if CONFIG_EXT_REFS
2047 rc->is_bwd_ref_frame = 0;
2048 rc->is_last_bipred_frame = 0;
2049 rc->is_bipred_frame = 0;
2050#endif // CONFIG_EXT_REFS
2051
2052#if 0
2053 // Experimental RD Code
2054 cpi->frame_distortion = 0;
2055 cpi->last_frame_distortion = 0;
2056#endif
2057
2058 set_tile_info(cpi);
2059
2060 cpi->ext_refresh_frame_flags_pending = 0;
2061 cpi->ext_refresh_frame_context_pending = 0;
2062
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002063#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002064 highbd_set_var_fns(cpi);
2065#endif
Alex Converseeb780e72016-12-13 12:46:41 -08002066
2067#if CONFIG_ANS && ANS_MAX_SYMBOLS
2068 cpi->common.ans_window_size_log2 = cpi->oxcf.ans_window_size_log2;
2069 if (cpi->buf_ans.size != (1 << cpi->common.ans_window_size_log2)) {
2070 aom_buf_ans_free(&cpi->buf_ans);
2071 aom_buf_ans_alloc(&cpi->buf_ans, &cpi->common.error,
2072 1 << cpi->common.ans_window_size_log2);
2073 }
2074#endif // CONFIG_ANS && ANS_MAX_SYMBOLS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002075}
2076
Yaowu Xuf883b422016-08-30 14:01:10 -07002077AV1_COMP *av1_create_compressor(AV1EncoderConfig *oxcf,
2078 BufferPool *const pool) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002079 unsigned int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07002080 AV1_COMP *volatile const cpi = aom_memalign(32, sizeof(AV1_COMP));
2081 AV1_COMMON *volatile const cm = cpi != NULL ? &cpi->common : NULL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002082
2083 if (!cm) return NULL;
2084
Yaowu Xuf883b422016-08-30 14:01:10 -07002085 av1_zero(*cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002086
2087 if (setjmp(cm->error.jmp)) {
2088 cm->error.setjmp = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -07002089 av1_remove_compressor(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002090 return 0;
2091 }
2092
2093 cm->error.setjmp = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002094 cm->alloc_mi = av1_enc_alloc_mi;
2095 cm->free_mi = av1_enc_free_mi;
2096 cm->setup_mi = av1_enc_setup_mi;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002097
Angie Chianga5d96c42016-10-21 16:16:56 -07002098 CHECK_MEM_ERROR(cm, cm->fc,
2099 (FRAME_CONTEXT *)aom_memalign(32, sizeof(*cm->fc)));
2100 CHECK_MEM_ERROR(cm, cm->frame_contexts,
2101 (FRAME_CONTEXT *)aom_memalign(
2102 32, FRAME_CONTEXTS * sizeof(*cm->frame_contexts)));
2103 memset(cm->fc, 0, sizeof(*cm->fc));
2104 memset(cm->frame_contexts, 0, FRAME_CONTEXTS * sizeof(*cm->frame_contexts));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002105
2106 cpi->resize_state = 0;
2107 cpi->resize_avg_qp = 0;
2108 cpi->resize_buffer_underflow = 0;
Fergus Simpsonddc846e2017-04-24 18:09:13 -07002109
Yaowu Xuc27fc142016-08-22 16:08:15 -07002110 cpi->common.buffer_pool = pool;
2111
2112 init_config(cpi, oxcf);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00002113#if CONFIG_XIPHRC
2114 cpi->od_rc.framerate = cpi->framerate;
2115 cpi->od_rc.frame_width = cm->render_width;
2116 cpi->od_rc.frame_height = cm->render_height;
2117 cpi->od_rc.keyframe_rate = oxcf->key_freq;
2118 cpi->od_rc.goldenframe_rate = FIXED_GF_INTERVAL;
2119 cpi->od_rc.altref_rate = 25;
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00002120 cpi->od_rc.firstpass_quant = 1;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00002121 cpi->od_rc.bit_depth = cm->bit_depth;
2122 cpi->od_rc.minq = oxcf->best_allowed_q;
2123 cpi->od_rc.maxq = oxcf->worst_allowed_q;
2124 if (cpi->oxcf.rc_mode == AOM_CQ) cpi->od_rc.minq = cpi->od_rc.quality;
2125 cpi->od_rc.quality = cpi->oxcf.rc_mode == AOM_Q ? oxcf->cq_level : -1;
2126 cpi->od_rc.periodic_boosts = oxcf->frame_periodic_boost;
2127 od_enc_rc_init(&cpi->od_rc,
2128 cpi->oxcf.rc_mode == AOM_Q ? -1 : oxcf->target_bandwidth,
2129 oxcf->maximum_buffer_size_ms);
2130#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002131 av1_rc_init(&cpi->oxcf, oxcf->pass, &cpi->rc);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00002132#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002133
2134 cm->current_video_frame = 0;
2135 cpi->partition_search_skippable_frame = 0;
2136 cpi->tile_data = NULL;
2137 cpi->last_show_frame_buf_idx = INVALID_IDX;
2138
2139 realloc_segmentation_maps(cpi);
2140
Yaowu Xuc27fc142016-08-22 16:08:15 -07002141 for (i = 0; i < NMV_CONTEXTS; ++i) {
Urvang Joshibffc0b52016-07-25 13:38:49 -07002142 memset(cpi->nmv_costs, 0, sizeof(cpi->nmv_costs));
2143 memset(cpi->nmv_costs_hp, 0, sizeof(cpi->nmv_costs_hp));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002144 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002145
Yaowu Xuc27fc142016-08-22 16:08:15 -07002146 for (i = 0; i < (sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]));
2147 i++) {
2148 CHECK_MEM_ERROR(
2149 cm, cpi->mbgraph_stats[i].mb_stats,
Yaowu Xuf883b422016-08-30 14:01:10 -07002150 aom_calloc(cm->MBs * sizeof(*cpi->mbgraph_stats[i].mb_stats), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002151 }
2152
2153#if CONFIG_FP_MB_STATS
2154 cpi->use_fp_mb_stats = 0;
2155 if (cpi->use_fp_mb_stats) {
2156 // a place holder used to store the first pass mb stats in the first pass
2157 CHECK_MEM_ERROR(cm, cpi->twopass.frame_mb_stats_buf,
Yaowu Xuf883b422016-08-30 14:01:10 -07002158 aom_calloc(cm->MBs * sizeof(uint8_t), 1));
Yaowu Xuc27fc142016-08-22 16:08:15 -07002159 } else {
2160 cpi->twopass.frame_mb_stats_buf = NULL;
2161 }
2162#endif
2163
2164 cpi->refresh_alt_ref_frame = 0;
2165 cpi->multi_arf_last_grp_enabled = 0;
2166
2167 cpi->b_calculate_psnr = CONFIG_INTERNAL_STATS;
2168#if CONFIG_INTERNAL_STATS
2169 cpi->b_calculate_blockiness = 1;
2170 cpi->b_calculate_consistency = 1;
2171 cpi->total_inconsistency = 0;
2172 cpi->psnr.worst = 100.0;
2173 cpi->worst_ssim = 100.0;
2174
2175 cpi->count = 0;
2176 cpi->bytes = 0;
2177
2178 if (cpi->b_calculate_psnr) {
2179 cpi->total_sq_error = 0;
2180 cpi->total_samples = 0;
2181 cpi->tot_recode_hits = 0;
2182 cpi->summed_quality = 0;
2183 cpi->summed_weights = 0;
2184 }
2185
2186 cpi->fastssim.worst = 100.0;
2187 cpi->psnrhvs.worst = 100.0;
2188
2189 if (cpi->b_calculate_blockiness) {
2190 cpi->total_blockiness = 0;
2191 cpi->worst_blockiness = 0.0;
2192 }
2193
2194 if (cpi->b_calculate_consistency) {
2195 CHECK_MEM_ERROR(cm, cpi->ssim_vars,
Yaowu Xuf883b422016-08-30 14:01:10 -07002196 aom_malloc(sizeof(*cpi->ssim_vars) * 4 *
Yaowu Xuc27fc142016-08-22 16:08:15 -07002197 cpi->common.mi_rows * cpi->common.mi_cols));
2198 cpi->worst_consistency = 100.0;
2199 }
2200#endif
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08002201#if CONFIG_ENTROPY_STATS
2202 av1_zero(aggregate_fc);
Zoe Liua56f9162017-06-21 22:49:57 -07002203 av1_zero_array(aggregate_fc_per_type, FRAME_CONTEXTS);
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08002204#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002205
2206 cpi->first_time_stamp_ever = INT64_MAX;
2207
Yaowu Xuc27fc142016-08-22 16:08:15 -07002208 for (i = 0; i < NMV_CONTEXTS; ++i) {
2209 cpi->td.mb.nmvcost[i][0] = &cpi->nmv_costs[i][0][MV_MAX];
2210 cpi->td.mb.nmvcost[i][1] = &cpi->nmv_costs[i][1][MV_MAX];
2211 cpi->td.mb.nmvcost_hp[i][0] = &cpi->nmv_costs_hp[i][0][MV_MAX];
2212 cpi->td.mb.nmvcost_hp[i][1] = &cpi->nmv_costs_hp[i][1][MV_MAX];
2213 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07002214
2215#ifdef OUTPUT_YUV_SKINMAP
2216 yuv_skinmap_file = fopen("skinmap.yuv", "ab");
2217#endif
2218#ifdef OUTPUT_YUV_REC
2219 yuv_rec_file = fopen("rec.yuv", "wb");
2220#endif
2221
2222#if 0
2223 framepsnr = fopen("framepsnr.stt", "a");
2224 kf_list = fopen("kf_list.stt", "w");
2225#endif
2226
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00002227#if CONFIG_XIPHRC
2228 if (oxcf->pass == 2) {
2229 cpi->od_rc.twopass_allframes_buf = oxcf->two_pass_stats_in.buf;
2230 cpi->od_rc.twopass_allframes_buf_size = oxcf->two_pass_stats_in.sz;
2231 }
2232#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07002233 if (oxcf->pass == 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002234 av1_init_first_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002235 } else if (oxcf->pass == 2) {
2236 const size_t packet_sz = sizeof(FIRSTPASS_STATS);
2237 const int packets = (int)(oxcf->two_pass_stats_in.sz / packet_sz);
2238
2239#if CONFIG_FP_MB_STATS
2240 if (cpi->use_fp_mb_stats) {
2241 const size_t psz = cpi->common.MBs * sizeof(uint8_t);
2242 const int ps = (int)(oxcf->firstpass_mb_stats_in.sz / psz);
2243
2244 cpi->twopass.firstpass_mb_stats.mb_stats_start =
2245 oxcf->firstpass_mb_stats_in.buf;
2246 cpi->twopass.firstpass_mb_stats.mb_stats_end =
2247 cpi->twopass.firstpass_mb_stats.mb_stats_start +
2248 (ps - 1) * cpi->common.MBs * sizeof(uint8_t);
2249 }
2250#endif
2251
2252 cpi->twopass.stats_in_start = oxcf->two_pass_stats_in.buf;
2253 cpi->twopass.stats_in = cpi->twopass.stats_in_start;
2254 cpi->twopass.stats_in_end = &cpi->twopass.stats_in[packets - 1];
2255
Yaowu Xuf883b422016-08-30 14:01:10 -07002256 av1_init_second_pass(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002257 }
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00002258#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07002259
Jingning Hand064cf02017-06-01 10:00:39 -07002260#if CONFIG_MOTION_VAR
2261#if CONFIG_HIGHBITDEPTH
2262 int buf_scaler = 2;
2263#else
2264 int buf_scaler = 1;
2265#endif
2266 CHECK_MEM_ERROR(
2267 cm, cpi->td.mb.above_pred_buf,
2268 (uint8_t *)aom_memalign(16, buf_scaler * MAX_MB_PLANE * MAX_SB_SQUARE *
2269 sizeof(*cpi->td.mb.above_pred_buf)));
2270 CHECK_MEM_ERROR(
2271 cm, cpi->td.mb.left_pred_buf,
2272 (uint8_t *)aom_memalign(16, buf_scaler * MAX_MB_PLANE * MAX_SB_SQUARE *
2273 sizeof(*cpi->td.mb.left_pred_buf)));
2274
2275 CHECK_MEM_ERROR(cm, cpi->td.mb.wsrc_buf,
2276 (int32_t *)aom_memalign(
2277 16, MAX_SB_SQUARE * sizeof(*cpi->td.mb.wsrc_buf)));
2278
2279 CHECK_MEM_ERROR(cm, cpi->td.mb.mask_buf,
2280 (int32_t *)aom_memalign(
2281 16, MAX_SB_SQUARE * sizeof(*cpi->td.mb.mask_buf)));
2282
2283#endif
2284
Yaowu Xuf883b422016-08-30 14:01:10 -07002285 av1_set_speed_features_framesize_independent(cpi);
2286 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002287
Yaowu Xuc27fc142016-08-22 16:08:15 -07002288#define BFP(BT, SDF, SDAF, VF, SVF, SVAF, SDX3F, SDX8F, SDX4DF) \
2289 cpi->fn_ptr[BT].sdf = SDF; \
2290 cpi->fn_ptr[BT].sdaf = SDAF; \
2291 cpi->fn_ptr[BT].vf = VF; \
2292 cpi->fn_ptr[BT].svf = SVF; \
2293 cpi->fn_ptr[BT].svaf = SVAF; \
2294 cpi->fn_ptr[BT].sdx3f = SDX3F; \
2295 cpi->fn_ptr[BT].sdx8f = SDX8F; \
2296 cpi->fn_ptr[BT].sdx4df = SDX4DF;
2297
2298#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002299 BFP(BLOCK_128X128, aom_sad128x128, aom_sad128x128_avg, aom_variance128x128,
2300 aom_sub_pixel_variance128x128, aom_sub_pixel_avg_variance128x128,
2301 aom_sad128x128x3, aom_sad128x128x8, aom_sad128x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002302
Yaowu Xuf883b422016-08-30 14:01:10 -07002303 BFP(BLOCK_128X64, aom_sad128x64, aom_sad128x64_avg, aom_variance128x64,
2304 aom_sub_pixel_variance128x64, aom_sub_pixel_avg_variance128x64, NULL,
2305 NULL, aom_sad128x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002306
Yaowu Xuf883b422016-08-30 14:01:10 -07002307 BFP(BLOCK_64X128, aom_sad64x128, aom_sad64x128_avg, aom_variance64x128,
2308 aom_sub_pixel_variance64x128, aom_sub_pixel_avg_variance64x128, NULL,
2309 NULL, aom_sad64x128x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002310#endif // CONFIG_EXT_PARTITION
2311
Yaowu Xuf883b422016-08-30 14:01:10 -07002312 BFP(BLOCK_32X16, aom_sad32x16, aom_sad32x16_avg, aom_variance32x16,
2313 aom_sub_pixel_variance32x16, aom_sub_pixel_avg_variance32x16, NULL, NULL,
2314 aom_sad32x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002315
Yaowu Xuf883b422016-08-30 14:01:10 -07002316 BFP(BLOCK_16X32, aom_sad16x32, aom_sad16x32_avg, aom_variance16x32,
2317 aom_sub_pixel_variance16x32, aom_sub_pixel_avg_variance16x32, NULL, NULL,
2318 aom_sad16x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002319
Yaowu Xuf883b422016-08-30 14:01:10 -07002320 BFP(BLOCK_64X32, aom_sad64x32, aom_sad64x32_avg, aom_variance64x32,
2321 aom_sub_pixel_variance64x32, aom_sub_pixel_avg_variance64x32, NULL, NULL,
2322 aom_sad64x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002323
Yaowu Xuf883b422016-08-30 14:01:10 -07002324 BFP(BLOCK_32X64, aom_sad32x64, aom_sad32x64_avg, aom_variance32x64,
2325 aom_sub_pixel_variance32x64, aom_sub_pixel_avg_variance32x64, NULL, NULL,
2326 aom_sad32x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002327
Yaowu Xuf883b422016-08-30 14:01:10 -07002328 BFP(BLOCK_32X32, aom_sad32x32, aom_sad32x32_avg, aom_variance32x32,
2329 aom_sub_pixel_variance32x32, aom_sub_pixel_avg_variance32x32,
2330 aom_sad32x32x3, aom_sad32x32x8, aom_sad32x32x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002331
Yaowu Xuf883b422016-08-30 14:01:10 -07002332 BFP(BLOCK_64X64, aom_sad64x64, aom_sad64x64_avg, aom_variance64x64,
2333 aom_sub_pixel_variance64x64, aom_sub_pixel_avg_variance64x64,
2334 aom_sad64x64x3, aom_sad64x64x8, aom_sad64x64x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002335
Yaowu Xuf883b422016-08-30 14:01:10 -07002336 BFP(BLOCK_16X16, aom_sad16x16, aom_sad16x16_avg, aom_variance16x16,
2337 aom_sub_pixel_variance16x16, aom_sub_pixel_avg_variance16x16,
2338 aom_sad16x16x3, aom_sad16x16x8, aom_sad16x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002339
Yaowu Xuf883b422016-08-30 14:01:10 -07002340 BFP(BLOCK_16X8, aom_sad16x8, aom_sad16x8_avg, aom_variance16x8,
2341 aom_sub_pixel_variance16x8, aom_sub_pixel_avg_variance16x8, aom_sad16x8x3,
2342 aom_sad16x8x8, aom_sad16x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002343
Yaowu Xuf883b422016-08-30 14:01:10 -07002344 BFP(BLOCK_8X16, aom_sad8x16, aom_sad8x16_avg, aom_variance8x16,
2345 aom_sub_pixel_variance8x16, aom_sub_pixel_avg_variance8x16, aom_sad8x16x3,
2346 aom_sad8x16x8, aom_sad8x16x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002347
Yaowu Xuf883b422016-08-30 14:01:10 -07002348 BFP(BLOCK_8X8, aom_sad8x8, aom_sad8x8_avg, aom_variance8x8,
2349 aom_sub_pixel_variance8x8, aom_sub_pixel_avg_variance8x8, aom_sad8x8x3,
2350 aom_sad8x8x8, aom_sad8x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002351
Yaowu Xuf883b422016-08-30 14:01:10 -07002352 BFP(BLOCK_8X4, aom_sad8x4, aom_sad8x4_avg, aom_variance8x4,
2353 aom_sub_pixel_variance8x4, aom_sub_pixel_avg_variance8x4, NULL,
2354 aom_sad8x4x8, aom_sad8x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002355
Yaowu Xuf883b422016-08-30 14:01:10 -07002356 BFP(BLOCK_4X8, aom_sad4x8, aom_sad4x8_avg, aom_variance4x8,
2357 aom_sub_pixel_variance4x8, aom_sub_pixel_avg_variance4x8, NULL,
2358 aom_sad4x8x8, aom_sad4x8x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002359
Yaowu Xuf883b422016-08-30 14:01:10 -07002360 BFP(BLOCK_4X4, aom_sad4x4, aom_sad4x4_avg, aom_variance4x4,
2361 aom_sub_pixel_variance4x4, aom_sub_pixel_avg_variance4x4, aom_sad4x4x3,
2362 aom_sad4x4x8, aom_sad4x4x4d)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002363
Timothy B. Terriberry81ec2612017-04-26 16:53:47 -07002364#if CONFIG_CHROMA_2X2 || CONFIG_CHROMA_SUB8X8
Jingning Han9e7c49f2016-12-06 11:20:10 -08002365 BFP(BLOCK_2X2, NULL, NULL, aom_variance2x2, NULL, NULL, NULL, NULL, NULL)
Jingning Hane2ffaf82016-12-14 15:26:30 -08002366 BFP(BLOCK_2X4, NULL, NULL, aom_variance2x4, NULL, NULL, NULL, NULL, NULL)
2367 BFP(BLOCK_4X2, NULL, NULL, aom_variance4x2, NULL, NULL, NULL, NULL, NULL)
Jingning Han9e7c49f2016-12-06 11:20:10 -08002368#endif
2369
Yue Chencb60b182016-10-13 15:18:22 -07002370#if CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002371#define OBFP(BT, OSDF, OVF, OSVF) \
2372 cpi->fn_ptr[BT].osdf = OSDF; \
2373 cpi->fn_ptr[BT].ovf = OVF; \
2374 cpi->fn_ptr[BT].osvf = OSVF;
2375
2376#if CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002377 OBFP(BLOCK_128X128, aom_obmc_sad128x128, aom_obmc_variance128x128,
2378 aom_obmc_sub_pixel_variance128x128)
2379 OBFP(BLOCK_128X64, aom_obmc_sad128x64, aom_obmc_variance128x64,
2380 aom_obmc_sub_pixel_variance128x64)
2381 OBFP(BLOCK_64X128, aom_obmc_sad64x128, aom_obmc_variance64x128,
2382 aom_obmc_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002383#endif // CONFIG_EXT_PARTITION
Yaowu Xuf883b422016-08-30 14:01:10 -07002384 OBFP(BLOCK_64X64, aom_obmc_sad64x64, aom_obmc_variance64x64,
2385 aom_obmc_sub_pixel_variance64x64)
2386 OBFP(BLOCK_64X32, aom_obmc_sad64x32, aom_obmc_variance64x32,
2387 aom_obmc_sub_pixel_variance64x32)
2388 OBFP(BLOCK_32X64, aom_obmc_sad32x64, aom_obmc_variance32x64,
2389 aom_obmc_sub_pixel_variance32x64)
2390 OBFP(BLOCK_32X32, aom_obmc_sad32x32, aom_obmc_variance32x32,
2391 aom_obmc_sub_pixel_variance32x32)
2392 OBFP(BLOCK_32X16, aom_obmc_sad32x16, aom_obmc_variance32x16,
2393 aom_obmc_sub_pixel_variance32x16)
2394 OBFP(BLOCK_16X32, aom_obmc_sad16x32, aom_obmc_variance16x32,
2395 aom_obmc_sub_pixel_variance16x32)
2396 OBFP(BLOCK_16X16, aom_obmc_sad16x16, aom_obmc_variance16x16,
2397 aom_obmc_sub_pixel_variance16x16)
2398 OBFP(BLOCK_16X8, aom_obmc_sad16x8, aom_obmc_variance16x8,
2399 aom_obmc_sub_pixel_variance16x8)
2400 OBFP(BLOCK_8X16, aom_obmc_sad8x16, aom_obmc_variance8x16,
2401 aom_obmc_sub_pixel_variance8x16)
2402 OBFP(BLOCK_8X8, aom_obmc_sad8x8, aom_obmc_variance8x8,
2403 aom_obmc_sub_pixel_variance8x8)
2404 OBFP(BLOCK_4X8, aom_obmc_sad4x8, aom_obmc_variance4x8,
2405 aom_obmc_sub_pixel_variance4x8)
2406 OBFP(BLOCK_8X4, aom_obmc_sad8x4, aom_obmc_variance8x4,
2407 aom_obmc_sub_pixel_variance8x4)
2408 OBFP(BLOCK_4X4, aom_obmc_sad4x4, aom_obmc_variance4x4,
2409 aom_obmc_sub_pixel_variance4x4)
Yue Chencb60b182016-10-13 15:18:22 -07002410#endif // CONFIG_MOTION_VAR
Yaowu Xuc27fc142016-08-22 16:08:15 -07002411
2412#if CONFIG_EXT_INTER
David Barkerf19f35f2017-05-22 16:33:22 +01002413#define MBFP(BT, MCSDF, MCSVF) \
2414 cpi->fn_ptr[BT].msdf = MCSDF; \
2415 cpi->fn_ptr[BT].msvf = MCSVF;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002416
2417#if CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01002418 MBFP(BLOCK_128X128, aom_masked_sad128x128,
2419 aom_masked_sub_pixel_variance128x128)
2420 MBFP(BLOCK_128X64, aom_masked_sad128x64, aom_masked_sub_pixel_variance128x64)
2421 MBFP(BLOCK_64X128, aom_masked_sad64x128, aom_masked_sub_pixel_variance64x128)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002422#endif // CONFIG_EXT_PARTITION
David Barkerf19f35f2017-05-22 16:33:22 +01002423 MBFP(BLOCK_64X64, aom_masked_sad64x64, aom_masked_sub_pixel_variance64x64)
2424 MBFP(BLOCK_64X32, aom_masked_sad64x32, aom_masked_sub_pixel_variance64x32)
2425 MBFP(BLOCK_32X64, aom_masked_sad32x64, aom_masked_sub_pixel_variance32x64)
2426 MBFP(BLOCK_32X32, aom_masked_sad32x32, aom_masked_sub_pixel_variance32x32)
2427 MBFP(BLOCK_32X16, aom_masked_sad32x16, aom_masked_sub_pixel_variance32x16)
2428 MBFP(BLOCK_16X32, aom_masked_sad16x32, aom_masked_sub_pixel_variance16x32)
2429 MBFP(BLOCK_16X16, aom_masked_sad16x16, aom_masked_sub_pixel_variance16x16)
2430 MBFP(BLOCK_16X8, aom_masked_sad16x8, aom_masked_sub_pixel_variance16x8)
2431 MBFP(BLOCK_8X16, aom_masked_sad8x16, aom_masked_sub_pixel_variance8x16)
2432 MBFP(BLOCK_8X8, aom_masked_sad8x8, aom_masked_sub_pixel_variance8x8)
2433 MBFP(BLOCK_4X8, aom_masked_sad4x8, aom_masked_sub_pixel_variance4x8)
2434 MBFP(BLOCK_8X4, aom_masked_sad8x4, aom_masked_sub_pixel_variance8x4)
2435 MBFP(BLOCK_4X4, aom_masked_sad4x4, aom_masked_sub_pixel_variance4x4)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002436#endif // CONFIG_EXT_INTER
2437
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002438#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002439 highbd_set_var_fns(cpi);
2440#endif
2441
Yaowu Xuf883b422016-08-30 14:01:10 -07002442 /* av1_init_quantizer() is first called here. Add check in
2443 * av1_frame_init_quantizer() so that av1_init_quantizer is only
Yaowu Xuc27fc142016-08-22 16:08:15 -07002444 * called later when needed. This will avoid unnecessary calls of
Yaowu Xuf883b422016-08-30 14:01:10 -07002445 * av1_init_quantizer() for every frame.
Yaowu Xuc27fc142016-08-22 16:08:15 -07002446 */
Yaowu Xuf883b422016-08-30 14:01:10 -07002447 av1_init_quantizer(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002448#if CONFIG_AOM_QM
2449 aom_qm_init(cm);
2450#endif
2451
Yaowu Xuf883b422016-08-30 14:01:10 -07002452 av1_loop_filter_init(cm);
Fergus Simpsondac6aff2017-05-18 15:11:38 -07002453#if CONFIG_FRAME_SUPERRES
Fergus Simpsonbfbf6a52017-06-14 23:13:12 -07002454 cm->superres_scale_numerator = SCALE_DENOMINATOR;
Debargha Mukherjee29e40a62017-06-14 09:37:12 -07002455 cm->superres_upscaled_width = oxcf->width;
2456 cm->superres_upscaled_height = oxcf->height;
Fergus Simpsondac6aff2017-05-18 15:11:38 -07002457#endif // CONFIG_FRAME_SUPERRES
Yaowu Xuc27fc142016-08-22 16:08:15 -07002458#if CONFIG_LOOP_RESTORATION
Yaowu Xuf883b422016-08-30 14:01:10 -07002459 av1_loop_restoration_precal();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002460#endif // CONFIG_LOOP_RESTORATION
2461
2462 cm->error.setjmp = 0;
2463
2464 return cpi;
2465}
2466
2467#define SNPRINT(H, T) snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T))
2468
2469#define SNPRINT2(H, T, V) \
2470 snprintf((H) + strlen(H), sizeof(H) - strlen(H), (T), (V))
2471
Yaowu Xuf883b422016-08-30 14:01:10 -07002472void av1_remove_compressor(AV1_COMP *cpi) {
2473 AV1_COMMON *cm;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002474 unsigned int i;
2475 int t;
2476
2477 if (!cpi) return;
2478
2479 cm = &cpi->common;
2480 if (cm->current_video_frame > 0) {
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08002481#if CONFIG_ENTROPY_STATS
2482 if (cpi->oxcf.pass != 1) {
2483 fprintf(stderr, "Writing counts.stt\n");
2484 FILE *f = fopen("counts.stt", "wb");
2485 fwrite(&aggregate_fc, sizeof(aggregate_fc), 1, f);
Zoe Liua56f9162017-06-21 22:49:57 -07002486 fwrite(aggregate_fc_per_type, sizeof(aggregate_fc_per_type[0]),
2487 FRAME_CONTEXTS, f);
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08002488 fclose(f);
2489 }
2490#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002491#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07002492 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07002493
2494 if (cpi->oxcf.pass != 1) {
2495 char headings[512] = { 0 };
2496 char results[512] = { 0 };
2497 FILE *f = fopen("opsnr.stt", "a");
2498 double time_encoded =
2499 (cpi->last_end_time_stamp_seen - cpi->first_time_stamp_ever) /
2500 10000000.000;
2501 double total_encode_time =
2502 (cpi->time_receive_data + cpi->time_compress_data) / 1000.000;
2503 const double dr =
2504 (double)cpi->bytes * (double)8 / (double)1000 / time_encoded;
2505 const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1);
2506 const double target_rate = (double)cpi->oxcf.target_bandwidth / 1000;
2507 const double rate_err = ((100.0 * (dr - target_rate)) / target_rate);
2508
2509 if (cpi->b_calculate_psnr) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002510 const double total_psnr = aom_sse_to_psnr(
Yaowu Xuc27fc142016-08-22 16:08:15 -07002511 (double)cpi->total_samples, peak, (double)cpi->total_sq_error);
2512 const double total_ssim =
2513 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0);
2514 snprintf(headings, sizeof(headings),
2515 "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t"
Yaowu Xuf883b422016-08-30 14:01:10 -07002516 "AOMSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t"
Yaowu Xuc27fc142016-08-22 16:08:15 -07002517 "WstPsnr\tWstSsim\tWstFast\tWstHVS");
2518 snprintf(results, sizeof(results),
2519 "%7.2f\t%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2520 "%7.3f\t%7.3f\t%7.3f\t%7.3f\t"
2521 "%7.3f\t%7.3f\t%7.3f\t%7.3f",
2522 dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr,
2523 cpi->psnr.stat[ALL] / cpi->count, total_psnr, total_ssim,
2524 total_ssim, cpi->fastssim.stat[ALL] / cpi->count,
2525 cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst,
2526 cpi->worst_ssim, cpi->fastssim.worst, cpi->psnrhvs.worst);
2527
2528 if (cpi->b_calculate_blockiness) {
2529 SNPRINT(headings, "\t Block\tWstBlck");
2530 SNPRINT2(results, "\t%7.3f", cpi->total_blockiness / cpi->count);
2531 SNPRINT2(results, "\t%7.3f", cpi->worst_blockiness);
2532 }
2533
2534 if (cpi->b_calculate_consistency) {
2535 double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07002536 aom_sse_to_psnr((double)cpi->total_samples, peak,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002537 (double)cpi->total_inconsistency);
2538
2539 SNPRINT(headings, "\tConsist\tWstCons");
2540 SNPRINT2(results, "\t%7.3f", consistency);
2541 SNPRINT2(results, "\t%7.3f", cpi->worst_consistency);
2542 }
Sarah Parkerf97b7862016-08-25 17:42:57 -07002543 fprintf(f, "%s\t Time\tRcErr\tAbsErr\n", headings);
2544 fprintf(f, "%s\t%8.0f\t%7.2f\t%7.2f\n", results, total_encode_time,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002545 rate_err, fabs(rate_err));
2546 }
2547
2548 fclose(f);
2549 }
2550
2551#endif
2552
2553#if 0
2554 {
2555 printf("\n_pick_loop_filter_level:%d\n", cpi->time_pick_lpf / 1000);
2556 printf("\n_frames recive_data encod_mb_row compress_frame Total\n");
2557 printf("%6d %10ld %10ld %10ld %10ld\n", cpi->common.current_video_frame,
2558 cpi->time_receive_data / 1000, cpi->time_encode_sb_row / 1000,
2559 cpi->time_compress_data / 1000,
2560 (cpi->time_receive_data + cpi->time_compress_data) / 1000);
2561 }
2562#endif
2563 }
2564
2565 for (t = 0; t < cpi->num_workers; ++t) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002566 AVxWorker *const worker = &cpi->workers[t];
Yaowu Xuc27fc142016-08-22 16:08:15 -07002567 EncWorkerData *const thread_data = &cpi->tile_thr_data[t];
2568
2569 // Deallocate allocated threads.
Yaowu Xuf883b422016-08-30 14:01:10 -07002570 aom_get_worker_interface()->end(worker);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002571
2572 // Deallocate allocated thread data.
2573 if (t < cpi->num_workers - 1) {
Urvang Joshib100db72016-10-12 16:28:56 -07002574#if CONFIG_PALETTE
Yaowu Xuc27fc142016-08-22 16:08:15 -07002575 if (cpi->common.allow_screen_content_tools)
hui su5d493142017-05-08 12:06:12 -07002576 aom_free(thread_data->td->palette_buffer);
Urvang Joshib100db72016-10-12 16:28:56 -07002577#endif // CONFIG_PALETTE
Jingning Hand064cf02017-06-01 10:00:39 -07002578#if CONFIG_MOTION_VAR
2579 aom_free(thread_data->td->above_pred_buf);
2580 aom_free(thread_data->td->left_pred_buf);
2581 aom_free(thread_data->td->wsrc_buf);
2582 aom_free(thread_data->td->mask_buf);
2583#endif // CONFIG_MOTION_VAR
Yaowu Xuf883b422016-08-30 14:01:10 -07002584 aom_free(thread_data->td->counts);
2585 av1_free_pc_tree(thread_data->td);
Yaowu Xuf883b422016-08-30 14:01:10 -07002586 aom_free(thread_data->td);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002587 }
2588 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002589 aom_free(cpi->tile_thr_data);
2590 aom_free(cpi->workers);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002591
Yaowu Xuf883b422016-08-30 14:01:10 -07002592 if (cpi->num_workers > 1) av1_loop_filter_dealloc(&cpi->lf_row_sync);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002593
2594 dealloc_compressor_data(cpi);
2595
2596 for (i = 0; i < sizeof(cpi->mbgraph_stats) / sizeof(cpi->mbgraph_stats[0]);
2597 ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002598 aom_free(cpi->mbgraph_stats[i].mb_stats);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002599 }
2600
2601#if CONFIG_FP_MB_STATS
2602 if (cpi->use_fp_mb_stats) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002603 aom_free(cpi->twopass.frame_mb_stats_buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002604 cpi->twopass.frame_mb_stats_buf = NULL;
2605 }
2606#endif
Debargha Mukherjee5d157212017-01-10 14:44:47 -08002607#if CONFIG_INTERNAL_STATS
2608 aom_free(cpi->ssim_vars);
2609 cpi->ssim_vars = NULL;
2610#endif // CONFIG_INTERNAL_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07002611
Yaowu Xuf883b422016-08-30 14:01:10 -07002612 av1_remove_common(cm);
2613 av1_free_ref_frame_buffers(cm->buffer_pool);
2614 aom_free(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002615
2616#ifdef OUTPUT_YUV_SKINMAP
2617 fclose(yuv_skinmap_file);
2618#endif
2619#ifdef OUTPUT_YUV_REC
2620 fclose(yuv_rec_file);
2621#endif
2622
2623#if 0
2624
2625 if (keyfile)
2626 fclose(keyfile);
2627
2628 if (framepsnr)
2629 fclose(framepsnr);
2630
2631 if (kf_list)
2632 fclose(kf_list);
2633
2634#endif
2635}
2636
Yaowu Xuf883b422016-08-30 14:01:10 -07002637static void generate_psnr_packet(AV1_COMP *cpi) {
2638 struct aom_codec_cx_pkt pkt;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002639 int i;
2640 PSNR_STATS psnr;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002641#if CONFIG_HIGHBITDEPTH
Alex Conversef77fd0b2017-04-20 11:00:24 -07002642 aom_calc_highbd_psnr(cpi->source, cpi->common.frame_to_show, &psnr,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002643 cpi->td.mb.e_mbd.bd, cpi->oxcf.input_bit_depth);
2644#else
Alex Conversef77fd0b2017-04-20 11:00:24 -07002645 aom_calc_psnr(cpi->source, cpi->common.frame_to_show, &psnr);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002646#endif
2647
2648 for (i = 0; i < 4; ++i) {
2649 pkt.data.psnr.samples[i] = psnr.samples[i];
2650 pkt.data.psnr.sse[i] = psnr.sse[i];
2651 pkt.data.psnr.psnr[i] = psnr.psnr[i];
2652 }
Yaowu Xuf883b422016-08-30 14:01:10 -07002653 pkt.kind = AOM_CODEC_PSNR_PKT;
2654 aom_codec_pkt_list_add(cpi->output_pkt_list, &pkt);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002655}
2656
Yaowu Xuf883b422016-08-30 14:01:10 -07002657int av1_use_as_reference(AV1_COMP *cpi, int ref_frame_flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002658 if (ref_frame_flags > ((1 << INTER_REFS_PER_FRAME) - 1)) return -1;
2659
2660 cpi->ref_frame_flags = ref_frame_flags;
2661 return 0;
2662}
2663
Yaowu Xuf883b422016-08-30 14:01:10 -07002664void av1_update_reference(AV1_COMP *cpi, int ref_frame_flags) {
2665 cpi->ext_refresh_golden_frame = (ref_frame_flags & AOM_GOLD_FLAG) != 0;
2666 cpi->ext_refresh_alt_ref_frame = (ref_frame_flags & AOM_ALT_FLAG) != 0;
2667 cpi->ext_refresh_last_frame = (ref_frame_flags & AOM_LAST_FLAG) != 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002668 cpi->ext_refresh_frame_flags_pending = 1;
2669}
2670
Yaowu Xuf883b422016-08-30 14:01:10 -07002671static YV12_BUFFER_CONFIG *get_av1_ref_frame_buffer(
2672 AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag) {
Emil Keyder01770b32017-01-20 18:03:11 -05002673 MV_REFERENCE_FRAME ref_frame = NONE_FRAME;
Yaowu Xuf883b422016-08-30 14:01:10 -07002674 if (ref_frame_flag == AOM_LAST_FLAG) ref_frame = LAST_FRAME;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002675#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002676 else if (ref_frame_flag == AOM_LAST2_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002677 ref_frame = LAST2_FRAME;
Yaowu Xuf883b422016-08-30 14:01:10 -07002678 else if (ref_frame_flag == AOM_LAST3_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002679 ref_frame = LAST3_FRAME;
2680#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002681 else if (ref_frame_flag == AOM_GOLD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002682 ref_frame = GOLDEN_FRAME;
2683#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002684 else if (ref_frame_flag == AOM_BWD_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002685 ref_frame = BWDREF_FRAME;
2686#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07002687 else if (ref_frame_flag == AOM_ALT_FLAG)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002688 ref_frame = ALTREF_FRAME;
2689
Emil Keyder01770b32017-01-20 18:03:11 -05002690 return ref_frame == NONE_FRAME ? NULL : get_ref_frame_buffer(cpi, ref_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002691}
2692
Yaowu Xuf883b422016-08-30 14:01:10 -07002693int av1_copy_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002694 YV12_BUFFER_CONFIG *sd) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002695 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002696 if (cfg) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002697 aom_yv12_copy_frame(cfg, sd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002698 return 0;
2699 } else {
2700 return -1;
2701 }
2702}
2703
Yaowu Xuf883b422016-08-30 14:01:10 -07002704int av1_set_reference_enc(AV1_COMP *cpi, AOM_REFFRAME ref_frame_flag,
2705 YV12_BUFFER_CONFIG *sd) {
2706 YV12_BUFFER_CONFIG *cfg = get_av1_ref_frame_buffer(cpi, ref_frame_flag);
2707 if (cfg) {
2708 aom_yv12_copy_frame(sd, cfg);
2709 return 0;
2710 } else {
2711 return -1;
2712 }
2713}
2714
2715int av1_update_entropy(AV1_COMP *cpi, int update) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002716 cpi->ext_refresh_frame_context = update;
2717 cpi->ext_refresh_frame_context_pending = 1;
2718 return 0;
2719}
2720
2721#if defined(OUTPUT_YUV_DENOISED) || defined(OUTPUT_YUV_SKINMAP)
2722// The denoiser buffer is allocated as a YUV 440 buffer. This function writes it
2723// as YUV 420. We simply use the top-left pixels of the UV buffers, since we do
2724// not denoise the UV channels at this time. If ever we implement UV channel
2725// denoising we will have to modify this.
Yaowu Xuf883b422016-08-30 14:01:10 -07002726void aom_write_yuv_frame_420(YV12_BUFFER_CONFIG *s, FILE *f) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002727 uint8_t *src = s->y_buffer;
2728 int h = s->y_height;
2729
2730 do {
2731 fwrite(src, s->y_width, 1, f);
2732 src += s->y_stride;
2733 } while (--h);
2734
2735 src = s->u_buffer;
2736 h = s->uv_height;
2737
2738 do {
2739 fwrite(src, s->uv_width, 1, f);
2740 src += s->uv_stride;
2741 } while (--h);
2742
2743 src = s->v_buffer;
2744 h = s->uv_height;
2745
2746 do {
2747 fwrite(src, s->uv_width, 1, f);
2748 src += s->uv_stride;
2749 } while (--h);
2750}
2751#endif
2752
Zoe Liue04abf72017-04-19 15:37:11 -07002753#if CONFIG_EXT_REFS && !CONFIG_XIPHRC
Yaowu Xuf883b422016-08-30 14:01:10 -07002754static void check_show_existing_frame(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002755 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
Yaowu Xuf883b422016-08-30 14:01:10 -07002756 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002757 const FRAME_UPDATE_TYPE next_frame_update_type =
2758 gf_group->update_type[gf_group->index];
2759 const int which_arf = gf_group->arf_update_idx[gf_group->index];
Zoe Liu5fca7242016-10-10 17:18:57 -07002760
2761 if (cm->show_existing_frame == 1) {
2762 cm->show_existing_frame = 0;
2763 } else if (cpi->rc.is_last_bipred_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002764 // NOTE(zoeliu): If the current frame is a last bi-predictive frame, it is
2765 // needed next to show the BWDREF_FRAME, which is pointed by
2766 // the last_fb_idxes[0] after reference frame buffer update
2767 cpi->rc.is_last_bipred_frame = 0;
2768 cm->show_existing_frame = 1;
2769 cpi->existing_fb_idx_to_show = cpi->lst_fb_idxes[0];
2770 } else if (cpi->is_arf_filter_off[which_arf] &&
2771 (next_frame_update_type == OVERLAY_UPDATE ||
2772 next_frame_update_type == INTNL_OVERLAY_UPDATE)) {
2773 // Other parameters related to OVERLAY_UPDATE will be taken care of
Yaowu Xuf883b422016-08-30 14:01:10 -07002774 // in av1_rc_get_second_pass_params(cpi)
Yaowu Xuc27fc142016-08-22 16:08:15 -07002775 cm->show_existing_frame = 1;
2776 cpi->rc.is_src_frame_alt_ref = 1;
2777 cpi->existing_fb_idx_to_show = cpi->alt_fb_idx;
2778 cpi->is_arf_filter_off[which_arf] = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002779 }
2780 cpi->rc.is_src_frame_ext_arf = 0;
2781}
Zoe Liue04abf72017-04-19 15:37:11 -07002782#endif // CONFIG_EXT_REFS && !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07002783
2784#ifdef OUTPUT_YUV_REC
Yaowu Xuf883b422016-08-30 14:01:10 -07002785void aom_write_one_yuv_frame(AV1_COMMON *cm, YV12_BUFFER_CONFIG *s) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002786 uint8_t *src = s->y_buffer;
2787 int h = cm->height;
2788
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002789#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002790 if (s->flags & YV12_FLAG_HIGHBITDEPTH) {
2791 uint16_t *src16 = CONVERT_TO_SHORTPTR(s->y_buffer);
2792
2793 do {
2794 fwrite(src16, s->y_width, 2, yuv_rec_file);
2795 src16 += s->y_stride;
2796 } while (--h);
2797
2798 src16 = CONVERT_TO_SHORTPTR(s->u_buffer);
2799 h = s->uv_height;
2800
2801 do {
2802 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2803 src16 += s->uv_stride;
2804 } while (--h);
2805
2806 src16 = CONVERT_TO_SHORTPTR(s->v_buffer);
2807 h = s->uv_height;
2808
2809 do {
2810 fwrite(src16, s->uv_width, 2, yuv_rec_file);
2811 src16 += s->uv_stride;
2812 } while (--h);
2813
2814 fflush(yuv_rec_file);
2815 return;
2816 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002817#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002818
2819 do {
2820 fwrite(src, s->y_width, 1, yuv_rec_file);
2821 src += s->y_stride;
2822 } while (--h);
2823
2824 src = s->u_buffer;
2825 h = s->uv_height;
2826
2827 do {
2828 fwrite(src, s->uv_width, 1, yuv_rec_file);
2829 src += s->uv_stride;
2830 } while (--h);
2831
2832 src = s->v_buffer;
2833 h = s->uv_height;
2834
2835 do {
2836 fwrite(src, s->uv_width, 1, yuv_rec_file);
2837 src += s->uv_stride;
2838 } while (--h);
2839
2840 fflush(yuv_rec_file);
2841}
2842#endif // OUTPUT_YUV_REC
2843
Debargha Mukherjee405c8572017-07-10 09:29:17 -07002844/*
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002845#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002846static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2847 YV12_BUFFER_CONFIG *dst, int planes,
2848 int bd) {
2849#else
2850static void scale_and_extend_frame(const YV12_BUFFER_CONFIG *src,
2851 YV12_BUFFER_CONFIG *dst, int planes) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002852#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002853 const int src_w = src->y_crop_width;
2854 const int src_h = src->y_crop_height;
2855 const int dst_w = dst->y_crop_width;
2856 const int dst_h = dst->y_crop_height;
2857 const uint8_t *const srcs[3] = { src->y_buffer, src->u_buffer,
2858 src->v_buffer };
2859 const int src_strides[3] = { src->y_stride, src->uv_stride, src->uv_stride };
2860 uint8_t *const dsts[3] = { dst->y_buffer, dst->u_buffer, dst->v_buffer };
2861 const int dst_strides[3] = { dst->y_stride, dst->uv_stride, dst->uv_stride };
2862 const InterpFilterParams interp_filter_params =
Yaowu Xuf883b422016-08-30 14:01:10 -07002863 av1_get_interp_filter_params(EIGHTTAP_REGULAR);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002864 const int16_t *kernel = interp_filter_params.filter_ptr;
2865 const int taps = interp_filter_params.taps;
2866 int x, y, i;
2867
Yaowu Xu637590c2016-11-16 15:15:46 -08002868 assert(planes <= 3);
Timothy B. Terriberry6d99b212017-06-15 12:06:11 -07002869 assert(src->subsampling_x == dst->subsampling_x);
2870 assert(src->subsampling_y == dst->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002871 for (y = 0; y < dst_h; y += 16) {
2872 for (x = 0; x < dst_w; x += 16) {
2873 for (i = 0; i < planes; ++i) {
Timothy B. Terriberry6d99b212017-06-15 12:06:11 -07002874 int ss_x = i == AOM_PLANE_Y ? 0 : src->subsampling_x;
2875 int ss_y = i == AOM_PLANE_Y ? 0 : src->subsampling_y;
2876 const int x_q4 = x * (16 >> ss_x) * src_w / dst_w;
2877 const int y_q4 = y * (16 >> ss_y) * src_h / dst_h;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002878 const int src_stride = src_strides[i];
2879 const int dst_stride = dst_strides[i];
2880 const uint8_t *src_ptr = srcs[i] +
Timothy B. Terriberry6d99b212017-06-15 12:06:11 -07002881 (y >> ss_y) * src_h / dst_h * src_stride +
2882 (x >> ss_x) * src_w / dst_w;
2883 uint8_t *dst_ptr = dsts[i] + (y >> ss_y) * dst_stride + (x >> ss_x);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002884
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002885#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002886 if (src->flags & YV12_FLAG_HIGHBITDEPTH) {
Yaowu Xuf883b422016-08-30 14:01:10 -07002887 aom_highbd_convolve8(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002888 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2889 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
Timothy B. Terriberry6d99b212017-06-15 12:06:11 -07002890 16 >> ss_x, 16 >> ss_y, bd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002891 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07002892 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002893 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2894 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
Timothy B. Terriberry6d99b212017-06-15 12:06:11 -07002895 16 >> ss_x, 16 >> ss_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002896 }
2897#else
Yaowu Xuf883b422016-08-30 14:01:10 -07002898 aom_scaled_2d(src_ptr, src_stride, dst_ptr, dst_stride,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002899 &kernel[(x_q4 & 0xf) * taps], 16 * src_w / dst_w,
2900 &kernel[(y_q4 & 0xf) * taps], 16 * src_h / dst_h,
Timothy B. Terriberry6d99b212017-06-15 12:06:11 -07002901 16 >> ss_x, 16 >> ss_y);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02002902#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07002903 }
2904 }
2905 }
2906
2907 if (planes == 1)
Yaowu Xuf883b422016-08-30 14:01:10 -07002908 aom_extend_frame_borders_y(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002909 else
Yaowu Xuf883b422016-08-30 14:01:10 -07002910 aom_extend_frame_borders(dst);
Yaowu Xuc27fc142016-08-22 16:08:15 -07002911}
Debargha Mukherjee405c8572017-07-10 09:29:17 -07002912*/
Yaowu Xuc27fc142016-08-22 16:08:15 -07002913
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002914#if CONFIG_GLOBAL_MOTION
Debargha Mukherjee11f0e402017-03-29 07:42:40 -07002915#define GM_RECODE_LOOP_NUM4X4_FACTOR 192
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002916static int recode_loop_test_global_motion(AV1_COMP *cpi) {
2917 int i;
2918 int recode = 0;
Debargha Mukherjeea575d232017-04-28 17:46:47 -07002919 RD_COUNTS *const rdc = &cpi->td.rd_counts;
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002920 AV1_COMMON *const cm = &cpi->common;
2921 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
2922 if (cm->global_motion[i].wmtype != IDENTITY &&
Debargha Mukherjeea575d232017-04-28 17:46:47 -07002923 rdc->global_motion_used[i] * GM_RECODE_LOOP_NUM4X4_FACTOR <
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07002924 cpi->gmparams_cost[i]) {
Sarah Parker4c10a3c2017-04-10 19:37:59 -07002925 set_default_warp_params(&cm->global_motion[i]);
Debargha Mukherjee265db6d2017-03-28 11:15:27 -07002926 cpi->gmparams_cost[i] = 0;
David Barker43479c62016-11-30 10:34:20 +00002927 recode = 1;
Debargha Mukherjeea575d232017-04-28 17:46:47 -07002928 recode |= (rdc->global_motion_used[i] > 0);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08002929 }
2930 }
2931 return recode;
2932}
2933#endif // CONFIG_GLOBAL_MOTION
2934
Yaowu Xuc27fc142016-08-22 16:08:15 -07002935// Function to test for conditions that indicate we should loop
2936// back and recode a frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07002937static int recode_loop_test(AV1_COMP *cpi, int high_limit, int low_limit, int q,
2938 int maxq, int minq) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002939 const RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07002940 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002941 const int frame_is_kfgfarf = frame_is_kf_gf_arf(cpi);
2942 int force_recode = 0;
2943
2944 if ((rc->projected_frame_size >= rc->max_frame_bandwidth) ||
2945 (cpi->sf.recode_loop == ALLOW_RECODE) ||
2946 (frame_is_kfgfarf && (cpi->sf.recode_loop == ALLOW_RECODE_KFARFGF))) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002947 // TODO(agrange) high_limit could be greater than the scale-down threshold.
2948 if ((rc->projected_frame_size > high_limit && q < maxq) ||
2949 (rc->projected_frame_size < low_limit && q > minq)) {
2950 force_recode = 1;
Yaowu Xuf883b422016-08-30 14:01:10 -07002951 } else if (cpi->oxcf.rc_mode == AOM_CQ) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07002952 // Deal with frame undershoot and whether or not we are
2953 // below the automatically set cq level.
2954 if (q > oxcf->cq_level &&
2955 rc->projected_frame_size < ((rc->this_frame_target * 7) >> 3)) {
2956 force_recode = 1;
2957 }
2958 }
2959 }
2960 return force_recode;
2961}
2962
Yaowu Xuc27fc142016-08-22 16:08:15 -07002963#define DUMP_REF_FRAME_IMAGES 0
2964
2965#if DUMP_REF_FRAME_IMAGES == 1
Yaowu Xuf883b422016-08-30 14:01:10 -07002966static int dump_one_image(AV1_COMMON *cm,
Yaowu Xuc27fc142016-08-22 16:08:15 -07002967 const YV12_BUFFER_CONFIG *const ref_buf,
2968 char *file_name) {
2969 int h;
2970 FILE *f_ref = NULL;
2971
2972 if (ref_buf == NULL) {
2973 printf("Frame data buffer is NULL.\n");
Yaowu Xuf883b422016-08-30 14:01:10 -07002974 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002975 }
2976
2977 if ((f_ref = fopen(file_name, "wb")) == NULL) {
2978 printf("Unable to open file %s to write.\n", file_name);
Yaowu Xuf883b422016-08-30 14:01:10 -07002979 return AOM_CODEC_MEM_ERROR;
Yaowu Xuc27fc142016-08-22 16:08:15 -07002980 }
2981
2982 // --- Y ---
2983 for (h = 0; h < cm->height; ++h) {
2984 fwrite(&ref_buf->y_buffer[h * ref_buf->y_stride], 1, cm->width, f_ref);
2985 }
2986 // --- U ---
2987 for (h = 0; h < (cm->height >> 1); ++h) {
2988 fwrite(&ref_buf->u_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
2989 f_ref);
2990 }
2991 // --- V ---
2992 for (h = 0; h < (cm->height >> 1); ++h) {
2993 fwrite(&ref_buf->v_buffer[h * ref_buf->uv_stride], 1, (cm->width >> 1),
2994 f_ref);
2995 }
2996
2997 fclose(f_ref);
2998
Yaowu Xuf883b422016-08-30 14:01:10 -07002999 return AOM_CODEC_OK;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003000}
3001
Yaowu Xuf883b422016-08-30 14:01:10 -07003002static void dump_ref_frame_images(AV1_COMP *cpi) {
3003 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003004 MV_REFERENCE_FRAME ref_frame;
3005
3006 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3007 char file_name[256] = "";
3008 snprintf(file_name, sizeof(file_name), "/tmp/enc_F%d_ref_%d.yuv",
3009 cm->current_video_frame, ref_frame);
3010 dump_one_image(cm, get_ref_frame_buffer(cpi, ref_frame), file_name);
3011 }
3012}
3013#endif // DUMP_REF_FRAME_IMAGES == 1
3014
3015#if CONFIG_EXT_REFS
3016// This function is used to shift the virtual indices of last reference frames
3017// as follows:
3018// LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3019// when the LAST_FRAME is updated.
Yaowu Xuf883b422016-08-30 14:01:10 -07003020static INLINE void shift_last_ref_frames(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003021 int ref_frame;
3022 for (ref_frame = LAST_REF_FRAMES - 1; ref_frame > 0; --ref_frame) {
3023 cpi->lst_fb_idxes[ref_frame] = cpi->lst_fb_idxes[ref_frame - 1];
3024
3025 // [0] is allocated to the current coded frame. The statistics for the
Zoe Liuf0e46692016-10-12 12:31:43 -07003026 // reference frames start at [LAST_FRAME], i.e. [1].
Yaowu Xuc27fc142016-08-22 16:08:15 -07003027 if (!cpi->rc.is_src_frame_alt_ref) {
Zoe Liuf0e46692016-10-12 12:31:43 -07003028 memcpy(cpi->interp_filter_selected[ref_frame + LAST_FRAME],
3029 cpi->interp_filter_selected[ref_frame - 1 + LAST_FRAME],
3030 sizeof(cpi->interp_filter_selected[ref_frame - 1 + LAST_FRAME]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003031 }
3032 }
3033}
Zoe Liuf0e46692016-10-12 12:31:43 -07003034#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003035
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07003036#if CONFIG_VAR_REFS
3037static void enc_check_valid_ref_frames(AV1_COMP *const cpi) {
3038 AV1_COMMON *const cm = &cpi->common;
3039 MV_REFERENCE_FRAME ref_frame;
3040
3041 // TODO(zoeliu): To handle ALTREF_FRAME the same way as do with other
3042 // reference frames. Current encoder invalid ALTREF when ALTREF
3043 // is the same as LAST, but invalid all the other references
3044 // when they are the same as ALTREF.
3045 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3046 int ref_buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3047 RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - LAST_FRAME];
3048
3049 if (ref_buf_idx != INVALID_IDX) {
3050 ref_buf->is_valid = 1;
3051
3052 MV_REFERENCE_FRAME ref;
3053 for (ref = LAST_FRAME; ref < ref_frame; ++ref) {
3054 int buf_idx = get_ref_frame_buf_idx(cpi, ref);
3055 RefBuffer *const buf = &cm->frame_refs[ref - LAST_FRAME];
3056 if (buf->is_valid && buf_idx == ref_buf_idx) {
3057 if (ref_frame != ALTREF_FRAME || ref == LAST_FRAME) {
3058 ref_buf->is_valid = 0;
3059 break;
3060 } else {
3061 buf->is_valid = 0;
3062 }
3063 }
3064 }
3065 } else {
3066 ref_buf->is_valid = 0;
3067 }
3068 }
3069}
3070#endif // CONFIG_VAR_REFS
3071
Yaowu Xuf883b422016-08-30 14:01:10 -07003072void av1_update_reference_frames(AV1_COMP *cpi) {
3073 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003074 BufferPool *const pool = cm->buffer_pool;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003075
3076 // NOTE: Save the new show frame buffer index for --test-code=warn, i.e.,
3077 // for the purpose to verify no mismatch between encoder and decoder.
3078 if (cm->show_frame) cpi->last_show_frame_buf_idx = cm->new_fb_idx;
3079
Yaowu Xuc27fc142016-08-22 16:08:15 -07003080 // At this point the new frame has been encoded.
3081 // If any buffer copy / swapping is signaled it should be done here.
3082 if (cm->frame_type == KEY_FRAME) {
3083 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3084 cm->new_fb_idx);
3085#if CONFIG_EXT_REFS
3086 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3087 cm->new_fb_idx);
3088#endif // CONFIG_EXT_REFS
3089 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3090 cm->new_fb_idx);
Yaowu Xuf883b422016-08-30 14:01:10 -07003091 } else if (av1_preserve_existing_gf(cpi)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003092 // We have decided to preserve the previously existing golden frame as our
3093 // new ARF frame. However, in the short term in function
Yaowu Xuf883b422016-08-30 14:01:10 -07003094 // av1_bitstream.c::get_refresh_mask() we left it in the GF slot and, if
Yaowu Xuc27fc142016-08-22 16:08:15 -07003095 // we're updating the GF with the current decoded frame, we save it to the
3096 // ARF slot instead.
3097 // We now have to update the ARF with the current frame and swap gld_fb_idx
3098 // and alt_fb_idx so that, overall, we've stored the old GF in the new ARF
3099 // slot and, if we're updating the GF, the current frame becomes the new GF.
3100 int tmp;
3101
3102 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->alt_fb_idx],
3103 cm->new_fb_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003104 tmp = cpi->alt_fb_idx;
3105 cpi->alt_fb_idx = cpi->gld_fb_idx;
3106 cpi->gld_fb_idx = tmp;
3107
3108#if CONFIG_EXT_REFS
3109 // We need to modify the mapping accordingly
3110 cpi->arf_map[0] = cpi->alt_fb_idx;
3111#endif
3112// TODO(zoeliu): Do we need to copy cpi->interp_filter_selected[0] over to
3113// cpi->interp_filter_selected[GOLDEN_FRAME]?
3114#if CONFIG_EXT_REFS
3115 } else if (cpi->rc.is_last_bipred_frame) {
3116 // Refresh the LAST_FRAME with the BWDREF_FRAME and retire the LAST3_FRAME
3117 // by updating the virtual indices. Note that the frame BWDREF_FRAME points
3118 // to now should be retired, and it should not be used before refreshed.
3119 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3120
3121 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003122 cpi->lst_fb_idxes[0] = cpi->bwd_fb_idx;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003123 cpi->bwd_fb_idx = tmp;
Zoe Liuf0e46692016-10-12 12:31:43 -07003124
3125 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3126 cpi->interp_filter_selected[BWDREF_FRAME],
3127 sizeof(cpi->interp_filter_selected[BWDREF_FRAME]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003128 } else if (cpi->rc.is_src_frame_ext_arf && cm->show_existing_frame) {
3129 // Deal with the special case for showing existing internal ALTREF_FRAME
3130 // Refresh the LAST_FRAME with the ALTREF_FRAME and retire the LAST3_FRAME
3131 // by updating the virtual indices.
3132 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3133 int which_arf = gf_group->arf_ref_idx[gf_group->index];
3134 int tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3135
3136 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003137 cpi->lst_fb_idxes[0] = cpi->alt_fb_idx;
Zoe Liuf0e46692016-10-12 12:31:43 -07003138 cpi->alt_fb_idx = tmp;
3139
3140 // We need to modify the mapping accordingly
3141 cpi->arf_map[which_arf] = cpi->alt_fb_idx;
3142
Yaowu Xuc27fc142016-08-22 16:08:15 -07003143 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3144 cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3145 sizeof(cpi->interp_filter_selected[ALTREF_FRAME + which_arf]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003146#endif // CONFIG_EXT_REFS
3147 } else { /* For non key/golden frames */
3148 if (cpi->refresh_alt_ref_frame) {
3149 int arf_idx = cpi->alt_fb_idx;
3150 int which_arf = 0;
3151#if CONFIG_EXT_REFS
3152 if (cpi->oxcf.pass == 2) {
3153 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3154 which_arf = gf_group->arf_update_idx[gf_group->index];
3155 arf_idx = cpi->arf_map[which_arf];
3156 }
3157#else
3158 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
3159 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
3160 arf_idx = gf_group->arf_update_idx[gf_group->index];
3161 }
3162#endif // CONFIG_EXT_REFS
3163 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[arf_idx], cm->new_fb_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003164
3165 memcpy(cpi->interp_filter_selected[ALTREF_FRAME + which_arf],
3166 cpi->interp_filter_selected[0],
3167 sizeof(cpi->interp_filter_selected[0]));
3168 }
3169
3170 if (cpi->refresh_golden_frame) {
3171 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->gld_fb_idx],
3172 cm->new_fb_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003173
Zoe Liuf0e46692016-10-12 12:31:43 -07003174#if !CONFIG_EXT_REFS
3175 if (!cpi->rc.is_src_frame_alt_ref)
3176#endif // !CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003177 memcpy(cpi->interp_filter_selected[GOLDEN_FRAME],
3178 cpi->interp_filter_selected[0],
3179 sizeof(cpi->interp_filter_selected[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003180 }
3181
3182#if CONFIG_EXT_REFS
3183 if (cpi->refresh_bwd_ref_frame) {
3184 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3185 // We have swapped the virtual indices to allow bwd_ref_frame to use
3186 // ALT0 as reference frame. We need to swap them back.
3187 // NOTE: The ALT_REFs' are indexed reversely, and ALT0 refers to the
3188 // farthest ALT_REF from the first frame in the gf group.
3189 int tmp = cpi->arf_map[0];
3190 cpi->arf_map[0] = cpi->alt_fb_idx;
3191 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3192 cpi->bwd_fb_idx = tmp;
3193 }
Zoe Liuf0e46692016-10-12 12:31:43 -07003194
Yaowu Xuc27fc142016-08-22 16:08:15 -07003195 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->bwd_fb_idx],
3196 cm->new_fb_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003197
3198 memcpy(cpi->interp_filter_selected[BWDREF_FRAME],
3199 cpi->interp_filter_selected[0],
3200 sizeof(cpi->interp_filter_selected[0]));
3201 }
3202#endif // CONFIG_EXT_REFS
3203 }
3204
3205 if (cpi->refresh_last_frame) {
3206#if CONFIG_EXT_REFS
3207 // NOTE(zoeliu): We have two layers of mapping (1) from the per-frame
3208 // reference to the reference frame buffer virtual index; and then (2) from
3209 // the virtual index to the reference frame buffer physical index:
3210 //
3211 // LAST_FRAME, ..., LAST3_FRAME, ..., ALTREF_FRAME
3212 // | | |
3213 // v v v
3214 // lst_fb_idxes[0], ..., lst_fb_idxes[2], ..., alt_fb_idx
3215 // | | |
3216 // v v v
3217 // ref_frame_map[], ..., ref_frame_map[], ..., ref_frame_map[]
3218 //
3219 // When refresh_last_frame is set, it is intended to retire LAST3_FRAME,
3220 // have the other 2 LAST reference frames shifted as follows:
3221 // LAST_FRAME -> LAST2_FRAME -> LAST3_FRAME
3222 // , and then have LAST_FRAME refreshed by the newly coded frame.
3223 //
3224 // To fulfill it, the decoder will be notified to execute following 2 steps:
3225 //
3226 // (a) To change ref_frame_map[] and have the virtual index of LAST3_FRAME
3227 // to point to the newly coded frame, i.e.
3228 // ref_frame_map[lst_fb_idexes[2]] => new_fb_idx;
3229 //
3230 // (b) To change the 1st layer mapping to have LAST_FRAME mapped to the
3231 // original virtual index of LAST3_FRAME and have the other mappings
3232 // shifted as follows:
3233 // LAST_FRAME, LAST2_FRAME, LAST3_FRAME
3234 // | | |
3235 // v v v
3236 // lst_fb_idxes[2], lst_fb_idxes[0], lst_fb_idxes[1]
3237 int ref_frame;
Zoe Liu5fca7242016-10-10 17:18:57 -07003238
Yaowu Xuc27fc142016-08-22 16:08:15 -07003239 if (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs) {
3240 // We have swapped the virtual indices to use ALT0 as BWD_REF
3241 // and we need to swap them back.
3242 int tmp = cpi->arf_map[0];
3243 cpi->arf_map[0] = cpi->alt_fb_idx;
3244 cpi->alt_fb_idx = cpi->bwd_fb_idx;
3245 cpi->bwd_fb_idx = tmp;
3246 }
Zoe Liu5fca7242016-10-10 17:18:57 -07003247
Yaowu Xuc27fc142016-08-22 16:08:15 -07003248 if (cm->frame_type == KEY_FRAME) {
3249 for (ref_frame = 0; ref_frame < LAST_REF_FRAMES; ++ref_frame) {
3250 ref_cnt_fb(pool->frame_bufs,
3251 &cm->ref_frame_map[cpi->lst_fb_idxes[ref_frame]],
3252 cm->new_fb_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003253 }
3254 } else {
3255 int tmp;
3256
3257 ref_cnt_fb(pool->frame_bufs,
3258 &cm->ref_frame_map[cpi->lst_fb_idxes[LAST_REF_FRAMES - 1]],
3259 cm->new_fb_idx);
3260
Yaowu Xuc27fc142016-08-22 16:08:15 -07003261 tmp = cpi->lst_fb_idxes[LAST_REF_FRAMES - 1];
3262
3263 shift_last_ref_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003264 cpi->lst_fb_idxes[0] = tmp;
3265
Zoe Liuf0e46692016-10-12 12:31:43 -07003266 assert(cm->show_existing_frame == 0);
3267 // NOTE: Currently only LF_UPDATE and INTNL_OVERLAY_UPDATE frames are to
3268 // refresh the LAST_FRAME.
3269 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3270 cpi->interp_filter_selected[0],
3271 sizeof(cpi->interp_filter_selected[0]));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003272 }
3273#else
3274 ref_cnt_fb(pool->frame_bufs, &cm->ref_frame_map[cpi->lst_fb_idx],
3275 cm->new_fb_idx);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003276 if (!cpi->rc.is_src_frame_alt_ref) {
3277 memcpy(cpi->interp_filter_selected[LAST_FRAME],
3278 cpi->interp_filter_selected[0],
3279 sizeof(cpi->interp_filter_selected[0]));
3280 }
3281#endif // CONFIG_EXT_REFS
3282 }
3283
3284#if DUMP_REF_FRAME_IMAGES == 1
3285 // Dump out all reference frame images.
3286 dump_ref_frame_images(cpi);
3287#endif // DUMP_REF_FRAME_IMAGES
3288}
3289
Yaowu Xuf883b422016-08-30 14:01:10 -07003290static INLINE void alloc_frame_mvs(AV1_COMMON *const cm, int buffer_idx) {
Debargha Mukherjee887069f2017-06-16 18:54:36 -07003291 assert(buffer_idx != INVALID_IDX);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003292 RefCntBuffer *const new_fb_ptr = &cm->buffer_pool->frame_bufs[buffer_idx];
3293 if (new_fb_ptr->mvs == NULL || new_fb_ptr->mi_rows < cm->mi_rows ||
3294 new_fb_ptr->mi_cols < cm->mi_cols) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003295 aom_free(new_fb_ptr->mvs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003296 CHECK_MEM_ERROR(cm, new_fb_ptr->mvs,
Yaowu Xuf883b422016-08-30 14:01:10 -07003297 (MV_REF *)aom_calloc(cm->mi_rows * cm->mi_cols,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003298 sizeof(*new_fb_ptr->mvs)));
3299 new_fb_ptr->mi_rows = cm->mi_rows;
3300 new_fb_ptr->mi_cols = cm->mi_cols;
3301 }
3302}
3303
Yaowu Xuf883b422016-08-30 14:01:10 -07003304void av1_scale_references(AV1_COMP *cpi) {
3305 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003306 MV_REFERENCE_FRAME ref_frame;
Yaowu Xuf883b422016-08-30 14:01:10 -07003307 const AOM_REFFRAME ref_mask[INTER_REFS_PER_FRAME] = {
3308 AOM_LAST_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003309#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003310 AOM_LAST2_FLAG,
3311 AOM_LAST3_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003312#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003313 AOM_GOLD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003314#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003315 AOM_BWD_FLAG,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003316#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07003317 AOM_ALT_FLAG
Yaowu Xuc27fc142016-08-22 16:08:15 -07003318 };
3319
3320 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003321 // Need to convert from AOM_REFFRAME to index into ref_mask (subtract 1).
Yaowu Xuc27fc142016-08-22 16:08:15 -07003322 if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
3323 BufferPool *const pool = cm->buffer_pool;
3324 const YV12_BUFFER_CONFIG *const ref =
3325 get_ref_frame_buffer(cpi, ref_frame);
3326
3327 if (ref == NULL) {
3328 cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3329 continue;
3330 }
3331
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003332#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003333 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3334 RefCntBuffer *new_fb_ptr = NULL;
3335 int force_scaling = 0;
3336 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3337 if (new_fb == INVALID_IDX) {
3338 new_fb = get_free_fb(cm);
3339 force_scaling = 1;
3340 }
3341 if (new_fb == INVALID_IDX) return;
3342 new_fb_ptr = &pool->frame_bufs[new_fb];
3343 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3344 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003345 if (aom_realloc_frame_buffer(
3346 &new_fb_ptr->buf, cm->width, cm->height, cm->subsampling_x,
3347 cm->subsampling_y, cm->use_highbitdepth, AOM_BORDER_IN_PIXELS,
3348 cm->byte_alignment, NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003349 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003350 "Failed to allocate frame buffer");
Debargha Mukherjee405c8572017-07-10 09:29:17 -07003351 av1_resize_and_extend_frame(ref, &new_fb_ptr->buf,
3352 (int)cm->bit_depth);
3353 // scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE,
3354 // (int)cm->bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003355 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3356 alloc_frame_mvs(cm, new_fb);
3357 }
3358#else
3359 if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
3360 RefCntBuffer *new_fb_ptr = NULL;
3361 int force_scaling = 0;
3362 int new_fb = cpi->scaled_ref_idx[ref_frame - 1];
3363 if (new_fb == INVALID_IDX) {
3364 new_fb = get_free_fb(cm);
3365 force_scaling = 1;
3366 }
3367 if (new_fb == INVALID_IDX) return;
3368 new_fb_ptr = &pool->frame_bufs[new_fb];
3369 if (force_scaling || new_fb_ptr->buf.y_crop_width != cm->width ||
3370 new_fb_ptr->buf.y_crop_height != cm->height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003371 if (aom_realloc_frame_buffer(&new_fb_ptr->buf, cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003372 cm->subsampling_x, cm->subsampling_y,
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003373 AOM_BORDER_IN_PIXELS, cm->byte_alignment,
3374 NULL, NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003375 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003376 "Failed to allocate frame buffer");
Debargha Mukherjee405c8572017-07-10 09:29:17 -07003377 av1_resize_and_extend_frame(ref, &new_fb_ptr->buf);
3378 // scale_and_extend_frame(ref, &new_fb_ptr->buf, MAX_MB_PLANE);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003379 cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
3380 alloc_frame_mvs(cm, new_fb);
3381 }
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003382#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003383 } else {
3384 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3385 RefCntBuffer *const buf = &pool->frame_bufs[buf_idx];
3386 buf->buf.y_crop_width = ref->y_crop_width;
3387 buf->buf.y_crop_height = ref->y_crop_height;
3388 cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
3389 ++buf->ref_count;
3390 }
3391 } else {
3392 if (cpi->oxcf.pass != 0) cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
3393 }
3394 }
3395}
3396
Yaowu Xuf883b422016-08-30 14:01:10 -07003397static void release_scaled_references(AV1_COMP *cpi) {
3398 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003399 int i;
3400 if (cpi->oxcf.pass == 0) {
3401 // Only release scaled references under certain conditions:
3402 // if reference will be updated, or if scaled reference has same resolution.
3403 int refresh[INTER_REFS_PER_FRAME];
3404 refresh[0] = (cpi->refresh_last_frame) ? 1 : 0;
3405#if CONFIG_EXT_REFS
3406 refresh[1] = refresh[2] = 0;
3407 refresh[3] = (cpi->refresh_golden_frame) ? 1 : 0;
3408 refresh[4] = (cpi->refresh_bwd_ref_frame) ? 1 : 0;
3409 refresh[5] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3410#else
3411 refresh[1] = (cpi->refresh_golden_frame) ? 1 : 0;
3412 refresh[2] = (cpi->refresh_alt_ref_frame) ? 1 : 0;
3413#endif // CONFIG_EXT_REFS
3414 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
3415 const int idx = cpi->scaled_ref_idx[i - 1];
3416 RefCntBuffer *const buf =
3417 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3418 const YV12_BUFFER_CONFIG *const ref = get_ref_frame_buffer(cpi, i);
3419 if (buf != NULL &&
3420 (refresh[i - 1] || (buf->buf.y_crop_width == ref->y_crop_width &&
3421 buf->buf.y_crop_height == ref->y_crop_height))) {
3422 --buf->ref_count;
3423 cpi->scaled_ref_idx[i - 1] = INVALID_IDX;
3424 }
3425 }
3426 } else {
3427 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i) {
3428 const int idx = cpi->scaled_ref_idx[i];
3429 RefCntBuffer *const buf =
3430 idx != INVALID_IDX ? &cm->buffer_pool->frame_bufs[idx] : NULL;
3431 if (buf != NULL) {
3432 --buf->ref_count;
3433 cpi->scaled_ref_idx[i] = INVALID_IDX;
3434 }
3435 }
3436 }
3437}
3438
3439static void full_to_model_count(unsigned int *model_count,
3440 unsigned int *full_count) {
3441 int n;
3442 model_count[ZERO_TOKEN] = full_count[ZERO_TOKEN];
3443 model_count[ONE_TOKEN] = full_count[ONE_TOKEN];
3444 model_count[TWO_TOKEN] = full_count[TWO_TOKEN];
3445 for (n = THREE_TOKEN; n < EOB_TOKEN; ++n)
3446 model_count[TWO_TOKEN] += full_count[n];
3447 model_count[EOB_MODEL_TOKEN] = full_count[EOB_TOKEN];
3448}
3449
Yaowu Xuf883b422016-08-30 14:01:10 -07003450void av1_full_to_model_counts(av1_coeff_count_model *model_count,
3451 av1_coeff_count *full_count) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003452 int i, j, k, l;
3453
3454 for (i = 0; i < PLANE_TYPES; ++i)
3455 for (j = 0; j < REF_TYPES; ++j)
3456 for (k = 0; k < COEF_BANDS; ++k)
3457 for (l = 0; l < BAND_COEFF_CONTEXTS(k); ++l)
3458 full_to_model_count(model_count[i][j][k][l], full_count[i][j][k][l]);
3459}
3460
3461#if 0 && CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07003462static void output_frame_level_debug_stats(AV1_COMP *cpi) {
3463 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003464 FILE *const f = fopen("tmp.stt", cm->current_video_frame ? "a" : "w");
3465 int64_t recon_err;
3466
Yaowu Xuf883b422016-08-30 14:01:10 -07003467 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003468
Alex Conversef77fd0b2017-04-20 11:00:24 -07003469 recon_err = aom_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003470
3471 if (cpi->twopass.total_left_stats.coded_error != 0.0)
Yunqing Wang8c1e57c2016-10-25 15:15:23 -07003472 fprintf(f, "%10u %dx%d %d %d %10d %10d %10d %10d"
Yaowu Xuc27fc142016-08-22 16:08:15 -07003473 "%10"PRId64" %10"PRId64" %5d %5d %10"PRId64" "
3474 "%10"PRId64" %10"PRId64" %10d "
3475 "%7.2lf %7.2lf %7.2lf %7.2lf %7.2lf"
3476 "%6d %6d %5d %5d %5d "
3477 "%10"PRId64" %10.3lf"
3478 "%10lf %8u %10"PRId64" %10d %10d %10d\n",
3479 cpi->common.current_video_frame,
3480 cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003481 cpi->rc.source_alt_ref_pending,
3482 cpi->rc.source_alt_ref_active,
3483 cpi->rc.this_frame_target,
3484 cpi->rc.projected_frame_size,
3485 cpi->rc.projected_frame_size / cpi->common.MBs,
3486 (cpi->rc.projected_frame_size - cpi->rc.this_frame_target),
3487 cpi->rc.vbr_bits_off_target,
3488 cpi->rc.vbr_bits_off_target_fast,
3489 cpi->twopass.extend_minq,
3490 cpi->twopass.extend_minq_fast,
3491 cpi->rc.total_target_vs_actual,
3492 (cpi->rc.starting_buffer_level - cpi->rc.bits_off_target),
3493 cpi->rc.total_actual_bits, cm->base_qindex,
Yaowu Xuf883b422016-08-30 14:01:10 -07003494 av1_convert_qindex_to_q(cm->base_qindex, cm->bit_depth),
3495 (double)av1_dc_quant(cm->base_qindex, 0, cm->bit_depth) / 4.0,
3496 av1_convert_qindex_to_q(cpi->twopass.active_worst_quality,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003497 cm->bit_depth),
3498 cpi->rc.avg_q,
Yaowu Xuf883b422016-08-30 14:01:10 -07003499 av1_convert_qindex_to_q(cpi->oxcf.cq_level, cm->bit_depth),
Yaowu Xuc27fc142016-08-22 16:08:15 -07003500 cpi->refresh_last_frame, cpi->refresh_golden_frame,
3501 cpi->refresh_alt_ref_frame, cm->frame_type, cpi->rc.gfu_boost,
3502 cpi->twopass.bits_left,
3503 cpi->twopass.total_left_stats.coded_error,
3504 cpi->twopass.bits_left /
3505 (1 + cpi->twopass.total_left_stats.coded_error),
3506 cpi->tot_recode_hits, recon_err, cpi->rc.kf_boost,
3507 cpi->twopass.kf_zeromotion_pct,
3508 cpi->twopass.fr_content_type);
3509
3510 fclose(f);
3511
3512 if (0) {
3513 FILE *const fmodes = fopen("Modes.stt", "a");
3514 int i;
3515
3516 fprintf(fmodes, "%6d:%1d:%1d:%1d ", cpi->common.current_video_frame,
3517 cm->frame_type, cpi->refresh_golden_frame,
3518 cpi->refresh_alt_ref_frame);
3519
3520 for (i = 0; i < MAX_MODES; ++i)
3521 fprintf(fmodes, "%5d ", cpi->mode_chosen_counts[i]);
3522
3523 fprintf(fmodes, "\n");
3524
3525 fclose(fmodes);
3526 }
3527}
3528#endif
3529
Yaowu Xuf883b422016-08-30 14:01:10 -07003530static void set_mv_search_params(AV1_COMP *cpi) {
3531 const AV1_COMMON *const cm = &cpi->common;
3532 const unsigned int max_mv_def = AOMMIN(cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003533
3534 // Default based on max resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003535 cpi->mv_step_param = av1_init_search_range(max_mv_def);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003536
3537 if (cpi->sf.mv.auto_mv_step_size) {
3538 if (frame_is_intra_only(cm)) {
3539 // Initialize max_mv_magnitude for use in the first INTER frame
3540 // after a key/intra-only frame.
3541 cpi->max_mv_magnitude = max_mv_def;
3542 } else {
3543 if (cm->show_frame) {
3544 // Allow mv_steps to correspond to twice the max mv magnitude found
3545 // in the previous frame, capped by the default max_mv_magnitude based
3546 // on resolution.
Yaowu Xuf883b422016-08-30 14:01:10 -07003547 cpi->mv_step_param = av1_init_search_range(
3548 AOMMIN(max_mv_def, 2 * cpi->max_mv_magnitude));
Yaowu Xuc27fc142016-08-22 16:08:15 -07003549 }
3550 cpi->max_mv_magnitude = 0;
3551 }
3552 }
3553}
3554
Yaowu Xuf883b422016-08-30 14:01:10 -07003555static void set_size_independent_vars(AV1_COMP *cpi) {
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003556#if CONFIG_GLOBAL_MOTION
3557 int i;
3558 for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
Sarah Parker4c10a3c2017-04-10 19:37:59 -07003559 set_default_warp_params(&cpi->common.global_motion[i]);
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08003560 }
3561 cpi->global_motion_search_done = 0;
3562#endif // CONFIG_GLOBAL_MOTION
Yaowu Xuf883b422016-08-30 14:01:10 -07003563 av1_set_speed_features_framesize_independent(cpi);
3564 av1_set_rd_speed_thresholds(cpi);
3565 av1_set_rd_speed_thresholds_sub8x8(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003566 cpi->common.interp_filter = cpi->sf.default_interp_filter;
Debargha Mukherjee9e2c7a62017-05-23 21:18:42 -07003567#if CONFIG_EXT_INTER
3568 if (!frame_is_intra_only(&cpi->common)) set_compound_tools(&cpi->common);
3569#endif // CONFIG_EXT_INTER
Yaowu Xuc27fc142016-08-22 16:08:15 -07003570}
3571
Yaowu Xuf883b422016-08-30 14:01:10 -07003572static void set_size_dependent_vars(AV1_COMP *cpi, int *q, int *bottom_index,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003573 int *top_index) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003574 AV1_COMMON *const cm = &cpi->common;
3575 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003576
3577 // Setup variables that depend on the dimensions of the frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07003578 av1_set_speed_features_framesize_dependent(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003579
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00003580// Decide q and q bounds.
3581#if CONFIG_XIPHRC
3582 int frame_type = cm->frame_type == KEY_FRAME ? OD_I_FRAME : OD_P_FRAME;
3583 *q = od_enc_rc_select_quantizers_and_lambdas(
3584 &cpi->od_rc, cpi->refresh_golden_frame, cpi->refresh_alt_ref_frame,
3585 frame_type, bottom_index, top_index);
3586#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003587 *q = av1_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00003588#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003589
3590 if (!frame_is_intra_only(cm)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003591 av1_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003592 }
3593
3594 // Configure experimental use of segmentation for enhanced coding of
3595 // static regions if indicated.
3596 // Only allowed in the second pass of a two pass encode, as it requires
3597 // lagged coding, and if the relevant speed feature flag is set.
3598 if (oxcf->pass == 2 && cpi->sf.static_segmentation)
3599 configure_static_seg_features(cpi);
3600}
3601
Yaowu Xuf883b422016-08-30 14:01:10 -07003602static void init_motion_estimation(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003603 int y_stride = cpi->scaled_source.y_stride;
3604
3605 if (cpi->sf.mv.search_method == NSTEP) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003606 av1_init3smotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003607 } else if (cpi->sf.mv.search_method == DIAMOND) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003608 av1_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003609 }
3610}
3611
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003612#if CONFIG_LOOP_RESTORATION
Debargha Mukherjee84f567c2017-06-21 10:53:59 -07003613#define COUPLED_CHROMA_FROM_LUMA_RESTORATION 0
3614static void set_restoration_tilesize(int width, int height, int sx, int sy,
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003615 RestorationInfo *rst) {
3616 (void)width;
3617 (void)height;
Debargha Mukherjee84f567c2017-06-21 10:53:59 -07003618 (void)sx;
3619 (void)sy;
3620#if COUPLED_CHROMA_FROM_LUMA_RESTORATION
3621 int s = AOMMIN(sx, sy);
3622#else
3623 int s = 0;
3624#endif // !COUPLED_CHROMA_FROM_LUMA_RESTORATION
3625
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003626 rst[0].restoration_tilesize = (RESTORATION_TILESIZE_MAX >> 1);
Debargha Mukherjee84f567c2017-06-21 10:53:59 -07003627 rst[1].restoration_tilesize = rst[0].restoration_tilesize >> s;
3628 rst[2].restoration_tilesize = rst[1].restoration_tilesize;
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003629}
3630#endif // CONFIG_LOOP_RESTORATION
3631
Fergus Simpsonbc189932017-05-16 17:02:39 -07003632static void set_frame_size(AV1_COMP *cpi, int width, int height) {
Fergus Simpsonbc189932017-05-16 17:02:39 -07003633 AV1_COMMON *const cm = &cpi->common;
Fergus Simpsonbc189932017-05-16 17:02:39 -07003634 MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003635 int ref_frame;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003636
Fergus Simpsonbc189932017-05-16 17:02:39 -07003637 if (width != cm->width || height != cm->height) {
Fergus Simpson3502d082017-04-10 12:25:07 -07003638 // There has been a change in the encoded frame size
Fergus Simpsonbc189932017-05-16 17:02:39 -07003639 av1_set_size_literal(cpi, width, height);
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003640 set_mv_search_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003641 }
3642
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00003643#if !CONFIG_XIPHRC
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003644 if (cpi->oxcf.pass == 2) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003645 av1_set_target_rate(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003646 }
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00003647#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003648
3649 alloc_frame_mvs(cm, cm->new_fb_idx);
3650
3651 // Reset the frame pointers to the current frame size.
Yaowu Xuf883b422016-08-30 14:01:10 -07003652 if (aom_realloc_frame_buffer(get_frame_new_buffer(cm), cm->width, cm->height,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003653 cm->subsampling_x, cm->subsampling_y,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003654#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07003655 cm->use_highbitdepth,
3656#endif
Yaowu Xu671f2bd2016-09-30 15:07:57 -07003657 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL,
3658 NULL, NULL))
Yaowu Xuf883b422016-08-30 14:01:10 -07003659 aom_internal_error(&cm->error, AOM_CODEC_MEM_ERROR,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003660 "Failed to allocate frame buffer");
3661
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003662#if CONFIG_LOOP_RESTORATION
Fergus Simpson9cd57cf2017-06-12 17:02:03 -07003663 set_restoration_tilesize(
3664#if CONFIG_FRAME_SUPERRES
3665 cm->superres_upscaled_width, cm->superres_upscaled_height,
3666#else
3667 cm->width, cm->height,
3668#endif // CONFIG_FRAME_SUPERRES
Debargha Mukherjee84f567c2017-06-21 10:53:59 -07003669 cm->subsampling_x, cm->subsampling_y, cm->rst_info);
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003670 for (int i = 0; i < MAX_MB_PLANE; ++i)
3671 cm->rst_info[i].frame_restoration_type = RESTORE_NONE;
3672 av1_alloc_restoration_buffers(cm);
3673 for (int i = 0; i < MAX_MB_PLANE; ++i) {
3674 cpi->rst_search[i].restoration_tilesize =
3675 cm->rst_info[i].restoration_tilesize;
Fergus Simpson9cd57cf2017-06-12 17:02:03 -07003676 av1_alloc_restoration_struct(cm, &cpi->rst_search[i],
3677#if CONFIG_FRAME_SUPERRES
3678 cm->superres_upscaled_width,
3679 cm->superres_upscaled_height);
3680#else
3681 cm->width, cm->height);
3682#endif // CONFIG_FRAME_SUPERRES
Debargha Mukherjee1008c1e2017-03-06 19:18:43 -08003683 }
Fergus Simpson9cd57cf2017-06-12 17:02:03 -07003684#endif // CONFIG_LOOP_RESTORATION
3685 alloc_util_frame_buffers(cpi); // TODO(afergs): Remove? Gets called anyways.
Yaowu Xuc27fc142016-08-22 16:08:15 -07003686 init_motion_estimation(cpi);
3687
3688 for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
3689 RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - LAST_FRAME];
3690 const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
3691
3692 ref_buf->idx = buf_idx;
3693
3694 if (buf_idx != INVALID_IDX) {
3695 YV12_BUFFER_CONFIG *const buf = &cm->buffer_pool->frame_bufs[buf_idx].buf;
3696 ref_buf->buf = buf;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003697#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07003698 av1_setup_scale_factors_for_frame(
Yaowu Xuc27fc142016-08-22 16:08:15 -07003699 &ref_buf->sf, buf->y_crop_width, buf->y_crop_height, cm->width,
3700 cm->height, (buf->flags & YV12_FLAG_HIGHBITDEPTH) ? 1 : 0);
3701#else
Yaowu Xuf883b422016-08-30 14:01:10 -07003702 av1_setup_scale_factors_for_frame(&ref_buf->sf, buf->y_crop_width,
3703 buf->y_crop_height, cm->width,
3704 cm->height);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02003705#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07003706 if (av1_is_scaled(&ref_buf->sf)) aom_extend_frame_borders(buf);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003707 } else {
3708 ref_buf->buf = NULL;
3709 }
3710 }
Zoe Liu7b1ec7a2017-05-24 22:28:24 -07003711
3712#if CONFIG_VAR_REFS
3713 // Check duplicate reference frames
3714 enc_check_valid_ref_frames(cpi);
3715#endif // CONFIG_VAR_REFS
3716
Alex Conversee816b312017-05-01 09:51:24 -07003717#if CONFIG_INTRABC
3718#if CONFIG_HIGHBITDEPTH
Sebastien Alaiwan1dcb7072017-05-12 11:13:05 +02003719 av1_setup_scale_factors_for_frame(&xd->sf_identity, cm->width, cm->height,
3720 cm->width, cm->height,
3721 cm->use_highbitdepth);
Alex Conversee816b312017-05-01 09:51:24 -07003722#else
3723 av1_setup_scale_factors_for_frame(&xd->sf_identity, cm->width, cm->height,
3724 cm->width, cm->height);
3725#endif // CONFIG_HIGHBITDEPTH
3726#endif // CONFIG_INTRABC
Yaowu Xuc27fc142016-08-22 16:08:15 -07003727
3728 set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
3729}
3730
Fergus Simpsonbc189932017-05-16 17:02:39 -07003731static void setup_frame_size(AV1_COMP *cpi) {
Debargha Mukherjee29e40a62017-06-14 09:37:12 -07003732 int encode_width = cpi->oxcf.width;
3733 int encode_height = cpi->oxcf.height;
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003734
Debargha Mukherjee29e40a62017-06-14 09:37:12 -07003735 uint8_t resize_num = av1_calculate_next_resize_scale(cpi);
Fergus Simpsonbfbf6a52017-06-14 23:13:12 -07003736 av1_calculate_scaled_size(&encode_width, &encode_height, resize_num);
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003737
3738#if CONFIG_FRAME_SUPERRES
3739 AV1_COMMON *cm = &cpi->common;
3740 cm->superres_upscaled_width = encode_width;
3741 cm->superres_upscaled_height = encode_height;
Debargha Mukherjee29e40a62017-06-14 09:37:12 -07003742 cm->superres_scale_numerator =
3743 av1_calculate_next_superres_scale(cpi, encode_width, encode_width);
3744 av1_calculate_scaled_size(&encode_width, &encode_height,
Fergus Simpsonbfbf6a52017-06-14 23:13:12 -07003745 cm->superres_scale_numerator);
Fergus Simpsonbc189932017-05-16 17:02:39 -07003746#endif // CONFIG_FRAME_SUPERRES
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003747
3748 set_frame_size(cpi, encode_width, encode_height);
3749}
3750
3751#if CONFIG_FRAME_SUPERRES
3752static void superres_post_encode(AV1_COMP *cpi) {
3753 AV1_COMMON *cm = &cpi->common;
3754
3755 if (av1_superres_unscaled(cm)) return;
3756
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003757 av1_superres_upscale(cm, NULL);
3758
3759 // If regular resizing is occurring the source will need to be downscaled to
3760 // match the upscaled superres resolution. Otherwise the original source is
3761 // used.
3762 if (av1_resize_unscaled(cm)) {
3763 cpi->source = cpi->unscaled_source;
3764 if (cpi->last_source != NULL) cpi->last_source = cpi->unscaled_last_source;
3765 } else {
Fergus Simpsonabd43432017-06-12 15:54:43 -07003766 assert(cpi->unscaled_source->y_crop_width != cm->superres_upscaled_width);
3767 assert(cpi->unscaled_source->y_crop_height != cm->superres_upscaled_height);
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003768 // Do downscale. cm->(width|height) has been updated by av1_superres_upscale
3769 if (aom_realloc_frame_buffer(
3770 &cpi->scaled_source, cm->superres_upscaled_width,
3771 cm->superres_upscaled_height, cm->subsampling_x, cm->subsampling_y,
3772#if CONFIG_HIGHBITDEPTH
3773 cm->use_highbitdepth,
3774#endif // CONFIG_HIGHBITDEPTH
3775 AOM_BORDER_IN_PIXELS, cm->byte_alignment, NULL, NULL, NULL))
3776 aom_internal_error(
3777 &cm->error, AOM_CODEC_MEM_ERROR,
3778 "Failed to reallocate scaled source buffer for superres");
3779 assert(cpi->scaled_source.y_crop_width == cm->superres_upscaled_width);
3780 assert(cpi->scaled_source.y_crop_height == cm->superres_upscaled_height);
3781#if CONFIG_HIGHBITDEPTH
3782 av1_resize_and_extend_frame(cpi->unscaled_source, &cpi->scaled_source,
3783 (int)cm->bit_depth);
3784#else
3785 av1_resize_and_extend_frame(cpi->unscaled_source, &cpi->scaled_source);
3786#endif // CONFIG_HIGHBITDEPTH
3787 cpi->source = &cpi->scaled_source;
3788 }
3789}
3790#endif // CONFIG_FRAME_SUPERRES
3791
3792static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
3793 MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
3794 struct loopfilter *lf = &cm->lf;
3795 if (is_lossless_requested(&cpi->oxcf)) {
3796 lf->filter_level = 0;
3797 } else {
3798 struct aom_usec_timer timer;
3799
3800 aom_clear_system_state();
3801
3802 aom_usec_timer_start(&timer);
3803
3804 av1_pick_filter_level(cpi->source, cpi, cpi->sf.lpf_pick);
3805
3806 aom_usec_timer_mark(&timer);
3807 cpi->time_pick_lpf += aom_usec_timer_elapsed(&timer);
3808 }
3809
3810 if (lf->filter_level > 0) {
3811#if CONFIG_VAR_TX || CONFIG_EXT_PARTITION || CONFIG_CB4X4
3812 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
3813#else
3814 if (cpi->num_workers > 1)
3815 av1_loop_filter_frame_mt(cm->frame_to_show, cm, xd->plane,
3816 lf->filter_level, 0, 0, cpi->workers,
3817 cpi->num_workers, &cpi->lf_row_sync);
3818 else
3819 av1_loop_filter_frame(cm->frame_to_show, cm, xd, lf->filter_level, 0, 0);
3820#endif
3821 }
3822#if CONFIG_CDEF
3823 if (is_lossless_requested(&cpi->oxcf)) {
3824 cm->cdef_bits = 0;
3825 cm->cdef_strengths[0] = 0;
3826 cm->nb_cdef_strengths = 1;
3827 } else {
3828 // Find cm->dering_level, cm->clpf_strength_u and cm->clpf_strength_v
3829 av1_cdef_search(cm->frame_to_show, cpi->source, cm, xd,
3830 cpi->oxcf.speed > 0);
3831
3832 // Apply the filter
3833 av1_cdef_frame(cm->frame_to_show, cm, xd);
3834 }
3835#endif
3836
3837#if CONFIG_FRAME_SUPERRES
3838 superres_post_encode(cpi);
3839#endif // CONFIG_FRAME_SUPERRES
3840
3841#if CONFIG_LOOP_RESTORATION
3842 av1_pick_filter_restoration(cpi->source, cpi, cpi->sf.lpf_pick);
3843 if (cm->rst_info[0].frame_restoration_type != RESTORE_NONE ||
3844 cm->rst_info[1].frame_restoration_type != RESTORE_NONE ||
3845 cm->rst_info[2].frame_restoration_type != RESTORE_NONE) {
3846 av1_loop_restoration_frame(cm->frame_to_show, cm, cm->rst_info, 7, 0, NULL);
3847 }
3848#endif // CONFIG_LOOP_RESTORATION
3849 // TODO(debargha): Fix mv search range on encoder side
3850 // aom_extend_frame_inner_borders(cm->frame_to_show);
3851 aom_extend_frame_borders(cm->frame_to_show);
Fergus Simpsonbc189932017-05-16 17:02:39 -07003852}
3853
Yaowu Xuf883b422016-08-30 14:01:10 -07003854static void encode_without_recode_loop(AV1_COMP *cpi) {
3855 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003856 int q = 0, bottom_index = 0, top_index = 0; // Dummy variables.
Yaowu Xuc27fc142016-08-22 16:08:15 -07003857
Yaowu Xuf883b422016-08-30 14:01:10 -07003858 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003859
Debargha Mukherjee887069f2017-06-16 18:54:36 -07003860 set_size_independent_vars(cpi);
Fergus Simpsonbc189932017-05-16 17:02:39 -07003861 setup_frame_size(cpi);
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003862 assert(cm->width == cpi->scaled_source.y_crop_width);
3863 assert(cm->height == cpi->scaled_source.y_crop_height);
Fergus Simpsonfecb2ab2017-04-30 15:49:57 -07003864
Yaowu Xuc27fc142016-08-22 16:08:15 -07003865 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3866
Debargha Mukherjee887069f2017-06-16 18:54:36 -07003867 cpi->source =
3868 av1_scale_if_required(cm, cpi->unscaled_source, &cpi->scaled_source);
3869 if (cpi->unscaled_last_source != NULL)
3870 cpi->last_source = av1_scale_if_required(cm, cpi->unscaled_last_source,
3871 &cpi->scaled_last_source);
3872
3873 if (frame_is_intra_only(cm) == 0) {
3874 av1_scale_references(cpi);
3875 }
3876
Yaowu Xuf883b422016-08-30 14:01:10 -07003877 av1_set_quantizer(cm, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003878 setup_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003879 suppress_active_map(cpi);
hui sued5a30f2017-04-27 16:02:49 -07003880
Yaowu Xuc27fc142016-08-22 16:08:15 -07003881 // Variance adaptive and in frame q adjustment experiments are mutually
3882 // exclusive.
3883 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003884 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003885 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003886 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003887 } else if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003888 av1_cyclic_refresh_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003889 }
3890 apply_active_map(cpi);
3891
3892 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07003893 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003894
3895 // Update some stats from cyclic refresh, and check if we should not update
3896 // golden reference, for 1 pass CBR.
3897 if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ && cm->frame_type != KEY_FRAME &&
Yaowu Xuf883b422016-08-30 14:01:10 -07003898 (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == AOM_CBR))
3899 av1_cyclic_refresh_check_golden_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003900
3901 // Update the skip mb flag probabilities based on the distribution
3902 // seen in the last encoder iteration.
3903 // update_base_skip_probs(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07003904 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003905}
3906
Yaowu Xuf883b422016-08-30 14:01:10 -07003907static void encode_with_recode_loop(AV1_COMP *cpi, size_t *size,
Yaowu Xuc27fc142016-08-22 16:08:15 -07003908 uint8_t *dest) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003909 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003910 RATE_CONTROL *const rc = &cpi->rc;
3911 int bottom_index, top_index;
3912 int loop_count = 0;
3913 int loop_at_this_size = 0;
3914 int loop = 0;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00003915#if !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07003916 int overshoot_seen = 0;
3917 int undershoot_seen = 0;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00003918#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003919 int frame_over_shoot_limit;
3920 int frame_under_shoot_limit;
3921 int q = 0, q_low = 0, q_high = 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07003922
3923 set_size_independent_vars(cpi);
3924
Yaowu Xuc27fc142016-08-22 16:08:15 -07003925 do {
Yaowu Xuf883b422016-08-30 14:01:10 -07003926 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07003927
Fergus Simpsonbc189932017-05-16 17:02:39 -07003928 setup_frame_size(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003929
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003930 if (loop_count == 0) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07003931 set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
3932
3933 // TODO(agrange) Scale cpi->max_mv_magnitude if frame-size has changed.
3934 set_mv_search_params(cpi);
3935
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00003936#if !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07003937 // Reset the loop state for new frame size.
3938 overshoot_seen = 0;
3939 undershoot_seen = 0;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00003940#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07003941
Yaowu Xuc27fc142016-08-22 16:08:15 -07003942 q_low = bottom_index;
3943 q_high = top_index;
3944
3945 loop_at_this_size = 0;
3946 }
3947
3948 // Decide frame size bounds first time through.
3949 if (loop_count == 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003950 av1_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
3951 &frame_under_shoot_limit,
3952 &frame_over_shoot_limit);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003953 }
3954
Alex Conversef77fd0b2017-04-20 11:00:24 -07003955 cpi->source =
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07003956 av1_scale_if_required(cm, cpi->unscaled_source, &cpi->scaled_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003957 if (cpi->unscaled_last_source != NULL)
Alex Conversef77fd0b2017-04-20 11:00:24 -07003958 cpi->last_source = av1_scale_if_required(cm, cpi->unscaled_last_source,
Yaowu Xuf883b422016-08-30 14:01:10 -07003959 &cpi->scaled_last_source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003960
3961 if (frame_is_intra_only(cm) == 0) {
3962 if (loop_count > 0) {
3963 release_scaled_references(cpi);
3964 }
Yaowu Xuf883b422016-08-30 14:01:10 -07003965 av1_scale_references(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003966 }
3967
Yaowu Xuf883b422016-08-30 14:01:10 -07003968 av1_set_quantizer(cm, q);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003969
3970 if (loop_count == 0) setup_frame(cpi);
3971
hui su0d103572017-03-01 17:58:01 -08003972#if CONFIG_Q_ADAPT_PROBS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003973 // Base q-index may have changed, so we need to assign proper default coef
3974 // probs before every iteration.
3975 if (frame_is_intra_only(cm) || cm->error_resilient_mode) {
3976 int i;
Yaowu Xuf883b422016-08-30 14:01:10 -07003977 av1_default_coef_probs(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003978 if (cm->frame_type == KEY_FRAME || cm->error_resilient_mode ||
3979 cm->reset_frame_context == RESET_FRAME_CONTEXT_ALL) {
3980 for (i = 0; i < FRAME_CONTEXTS; ++i) cm->frame_contexts[i] = *cm->fc;
3981 } else if (cm->reset_frame_context == RESET_FRAME_CONTEXT_CURRENT) {
3982 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
3983 }
3984 }
hui su0d103572017-03-01 17:58:01 -08003985#endif // CONFIG_Q_ADAPT_PROBS
Yaowu Xuc27fc142016-08-22 16:08:15 -07003986
Yaowu Xuc27fc142016-08-22 16:08:15 -07003987 // Variance adaptive and in frame q adjustment experiments are mutually
3988 // exclusive.
3989 if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003990 av1_vaq_frame_setup(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003991 } else if (cpi->oxcf.aq_mode == COMPLEXITY_AQ) {
Yaowu Xuf883b422016-08-30 14:01:10 -07003992 av1_setup_in_frame_q_adj(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003993 }
3994
3995 // transform / motion compensation build reconstruction frame
Yaowu Xuf883b422016-08-30 14:01:10 -07003996 av1_encode_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07003997
3998 // Update the skip mb flag probabilities based on the distribution
3999 // seen in the last encoder iteration.
4000 // update_base_skip_probs(cpi);
4001
Yaowu Xuf883b422016-08-30 14:01:10 -07004002 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004003
4004 // Dummy pack of the bitstream using up to date stats to get an
4005 // accurate estimate of output frame size to determine if we need
4006 // to recode.
4007 if (cpi->sf.recode_loop >= ALLOW_RECODE_KFARFGF) {
4008 save_coding_context(cpi);
4009
Yaowu Xuf883b422016-08-30 14:01:10 -07004010 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004011
4012 rc->projected_frame_size = (int)(*size) << 3;
4013 restore_coding_context(cpi);
4014
4015 if (frame_over_shoot_limit == 0) frame_over_shoot_limit = 1;
4016 }
4017
Yaowu Xuf883b422016-08-30 14:01:10 -07004018 if (cpi->oxcf.rc_mode == AOM_Q) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004019 loop = 0;
4020 } else {
4021 if ((cm->frame_type == KEY_FRAME) && rc->this_key_frame_forced &&
4022 (rc->projected_frame_size < rc->max_frame_bandwidth)) {
4023 int last_q = q;
4024 int64_t kf_err;
4025
4026 int64_t high_err_target = cpi->ambient_err;
4027 int64_t low_err_target = cpi->ambient_err >> 1;
4028
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004029#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004030 if (cm->use_highbitdepth) {
Alex Conversef77fd0b2017-04-20 11:00:24 -07004031 kf_err = aom_highbd_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004032 } else {
Alex Conversef77fd0b2017-04-20 11:00:24 -07004033 kf_err = aom_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004034 }
4035#else
Alex Conversef77fd0b2017-04-20 11:00:24 -07004036 kf_err = aom_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004037#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004038
4039 // Prevent possible divide by zero error below for perfect KF
4040 kf_err += !kf_err;
4041
4042 // The key frame is not good enough or we can afford
4043 // to make it better without undue risk of popping.
4044 if ((kf_err > high_err_target &&
4045 rc->projected_frame_size <= frame_over_shoot_limit) ||
4046 (kf_err > low_err_target &&
4047 rc->projected_frame_size <= frame_under_shoot_limit)) {
4048 // Lower q_high
4049 q_high = q > q_low ? q - 1 : q_low;
4050
4051 // Adjust Q
4052 q = (int)((q * high_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004053 q = AOMMIN(q, (q_high + q_low) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004054 } else if (kf_err < low_err_target &&
4055 rc->projected_frame_size >= frame_under_shoot_limit) {
4056 // The key frame is much better than the previous frame
4057 // Raise q_low
4058 q_low = q < q_high ? q + 1 : q_high;
4059
4060 // Adjust Q
4061 q = (int)((q * low_err_target) / kf_err);
Yaowu Xuf883b422016-08-30 14:01:10 -07004062 q = AOMMIN(q, (q_high + q_low + 1) >> 1);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004063 }
4064
4065 // Clamp Q to upper and lower limits:
4066 q = clamp(q, q_low, q_high);
4067
4068 loop = q != last_q;
4069 } else if (recode_loop_test(cpi, frame_over_shoot_limit,
4070 frame_under_shoot_limit, q,
Yaowu Xuf883b422016-08-30 14:01:10 -07004071 AOMMAX(q_high, top_index), bottom_index)) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004072 // Is the projected frame size out of range and are we allowed
4073 // to attempt to recode.
4074 int last_q = q;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004075#if !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07004076 int retries = 0;
4077
Yaowu Xuc27fc142016-08-22 16:08:15 -07004078 // Frame size out of permitted range:
4079 // Update correction factor & compute new Q to try...
Yaowu Xuc27fc142016-08-22 16:08:15 -07004080 // Frame is too large
4081 if (rc->projected_frame_size > rc->this_frame_target) {
4082 // Special case if the projected size is > the max allowed.
4083 if (rc->projected_frame_size >= rc->max_frame_bandwidth)
4084 q_high = rc->worst_quality;
4085
4086 // Raise Qlow as to at least the current value
4087 q_low = q < q_high ? q + 1 : q_high;
4088
4089 if (undershoot_seen || loop_at_this_size > 1) {
4090 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004091 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004092
4093 q = (q_high + q_low + 1) / 2;
4094 } else {
4095 // Update rate_correction_factor unless
Yaowu Xuf883b422016-08-30 14:01:10 -07004096 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004097
Yaowu Xuf883b422016-08-30 14:01:10 -07004098 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4099 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004100
4101 while (q < q_low && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004102 av1_rc_update_rate_correction_factors(cpi);
4103 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4104 AOMMAX(q_high, top_index));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004105 retries++;
4106 }
4107 }
4108
4109 overshoot_seen = 1;
4110 } else {
4111 // Frame is too small
4112 q_high = q > q_low ? q - 1 : q_low;
4113
4114 if (overshoot_seen || loop_at_this_size > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004115 av1_rc_update_rate_correction_factors(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004116 q = (q_high + q_low) / 2;
4117 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004118 av1_rc_update_rate_correction_factors(cpi);
4119 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4120 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004121 // Special case reset for qlow for constrained quality.
4122 // This should only trigger where there is very substantial
4123 // undershoot on a frame and the auto cq level is above
4124 // the user passsed in value.
Yaowu Xuf883b422016-08-30 14:01:10 -07004125 if (cpi->oxcf.rc_mode == AOM_CQ && q < q_low) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004126 q_low = q;
4127 }
4128
4129 while (q > q_high && retries < 10) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004130 av1_rc_update_rate_correction_factors(cpi);
4131 q = av1_rc_regulate_q(cpi, rc->this_frame_target, bottom_index,
4132 top_index);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004133 retries++;
4134 }
4135 }
4136
4137 undershoot_seen = 1;
4138 }
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004139#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004140
4141 // Clamp Q to upper and lower limits:
4142 q = clamp(q, q_low, q_high);
4143
4144 loop = (q != last_q);
4145 } else {
4146 loop = 0;
4147 }
4148 }
4149
4150 // Special case for overlay frame.
4151 if (rc->is_src_frame_alt_ref &&
4152 rc->projected_frame_size < rc->max_frame_bandwidth)
4153 loop = 0;
4154
Debargha Mukherjeeb98a7022016-11-15 16:07:12 -08004155#if CONFIG_GLOBAL_MOTION
4156 if (recode_loop_test_global_motion(cpi)) {
4157 loop = 1;
4158 }
4159#endif // CONFIG_GLOBAL_MOTION
4160
Yaowu Xuc27fc142016-08-22 16:08:15 -07004161 if (loop) {
4162 ++loop_count;
4163 ++loop_at_this_size;
4164
4165#if CONFIG_INTERNAL_STATS
4166 ++cpi->tot_recode_hits;
4167#endif
4168 }
4169 } while (loop);
4170}
4171
Yaowu Xuf883b422016-08-30 14:01:10 -07004172static int get_ref_frame_flags(const AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004173 const int *const map = cpi->common.ref_frame_map;
4174
4175#if CONFIG_EXT_REFS
4176 const int last2_is_last =
4177 map[cpi->lst_fb_idxes[1]] == map[cpi->lst_fb_idxes[0]];
4178 const int last3_is_last =
4179 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[0]];
4180 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[0]];
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +02004181#if CONFIG_ONE_SIDED_COMPOUND
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +02004182 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[0]];
4183 const int last3_is_last2 =
4184 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[1]];
4185 const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[1]];
4186 const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[2]];
Zoe Liufcf5fa22017-06-26 16:00:38 -07004187#else // !CONFIG_ONE_SIDED_COMPOUND
Yaowu Xuc27fc142016-08-22 16:08:15 -07004188 const int bwd_is_last = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[0]];
4189 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idxes[0]];
4190
4191 const int last3_is_last2 =
4192 map[cpi->lst_fb_idxes[2]] == map[cpi->lst_fb_idxes[1]];
4193 const int gld_is_last2 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[1]];
4194 const int bwd_is_last2 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[1]];
4195
4196 const int gld_is_last3 = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idxes[2]];
4197 const int bwd_is_last3 = map[cpi->bwd_fb_idx] == map[cpi->lst_fb_idxes[2]];
4198
4199 const int bwd_is_gld = map[cpi->bwd_fb_idx] == map[cpi->gld_fb_idx];
4200
Zoe Liufcf5fa22017-06-26 16:00:38 -07004201#endif // CONFIG_ONE_SIDED_COMPOUND
Yaowu Xuc27fc142016-08-22 16:08:15 -07004202 const int last2_is_alt = map[cpi->lst_fb_idxes[1]] == map[cpi->alt_fb_idx];
4203 const int last3_is_alt = map[cpi->lst_fb_idxes[2]] == map[cpi->alt_fb_idx];
4204 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4205 const int bwd_is_alt = map[cpi->bwd_fb_idx] == map[cpi->alt_fb_idx];
Zoe Liufcf5fa22017-06-26 16:00:38 -07004206#else // !CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004207 const int gld_is_last = map[cpi->gld_fb_idx] == map[cpi->lst_fb_idx];
4208 const int gld_is_alt = map[cpi->gld_fb_idx] == map[cpi->alt_fb_idx];
4209 const int alt_is_last = map[cpi->alt_fb_idx] == map[cpi->lst_fb_idx];
4210#endif // CONFIG_EXT_REFS
4211
Yaowu Xuf883b422016-08-30 14:01:10 -07004212 int flags = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004213
4214#if CONFIG_EXT_REFS
4215 // Disable the use of BWDREF_FRAME for non-bipredictive frames.
4216 if (!(cpi->rc.is_bipred_frame || cpi->rc.is_last_bipred_frame ||
4217 (cpi->rc.is_bwd_ref_frame && cpi->num_extra_arfs)))
Yaowu Xuf883b422016-08-30 14:01:10 -07004218 flags &= ~AOM_BWD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004219#endif // CONFIG_EXT_REFS
4220
Yaowu Xuf883b422016-08-30 14:01:10 -07004221 if (gld_is_last || gld_is_alt) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004222
Yaowu Xuf883b422016-08-30 14:01:10 -07004223 if (cpi->rc.frames_till_gf_update_due == INT_MAX) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004224
Yaowu Xuf883b422016-08-30 14:01:10 -07004225 if (alt_is_last) flags &= ~AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004226
4227#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004228 if (last2_is_last || last2_is_alt) flags &= ~AOM_LAST2_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004229
Yaowu Xuf883b422016-08-30 14:01:10 -07004230 if (last3_is_last || last3_is_last2 || last3_is_alt) flags &= ~AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004231
Yaowu Xuf883b422016-08-30 14:01:10 -07004232 if (gld_is_last2 || gld_is_last3) flags &= ~AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004233
Arild Fuldseth (arilfuld)78bfc282017-05-24 12:06:35 +02004234#if CONFIG_ONE_SIDED_COMPOUND // Changes LL & HL bitstream
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +02004235 /* Allow biprediction between two identical frames (e.g. bwd_is_last = 1) */
4236 if (bwd_is_alt && (flags & AOM_BWD_FLAG)) flags &= ~AOM_BWD_FLAG;
4237#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004238 if ((bwd_is_last || bwd_is_last2 || bwd_is_last3 || bwd_is_gld ||
4239 bwd_is_alt) &&
Yaowu Xuf883b422016-08-30 14:01:10 -07004240 (flags & AOM_BWD_FLAG))
4241 flags &= ~AOM_BWD_FLAG;
Arild Fuldseth (arilfuld)3f429082017-04-28 15:54:28 +02004242#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004243#endif // CONFIG_EXT_REFS
4244
4245 return flags;
4246}
4247
Yaowu Xuf883b422016-08-30 14:01:10 -07004248static void set_ext_overrides(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004249 // Overrides the defaults with the externally supplied values with
Yaowu Xuf883b422016-08-30 14:01:10 -07004250 // av1_update_reference() and av1_update_entropy() calls
Yaowu Xuc27fc142016-08-22 16:08:15 -07004251 // Note: The overrides are valid only for the next frame passed
4252 // to encode_frame_to_data_rate() function
4253 if (cpi->ext_refresh_frame_context_pending) {
4254 cpi->common.refresh_frame_context = cpi->ext_refresh_frame_context;
4255 cpi->ext_refresh_frame_context_pending = 0;
4256 }
4257 if (cpi->ext_refresh_frame_flags_pending) {
4258 cpi->refresh_last_frame = cpi->ext_refresh_last_frame;
4259 cpi->refresh_golden_frame = cpi->ext_refresh_golden_frame;
4260 cpi->refresh_alt_ref_frame = cpi->ext_refresh_alt_ref_frame;
4261 cpi->ext_refresh_frame_flags_pending = 0;
4262 }
4263}
4264
Yaowu Xuf883b422016-08-30 14:01:10 -07004265static void set_arf_sign_bias(AV1_COMP *cpi) {
4266 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004267 int arf_sign_bias;
4268#if CONFIG_EXT_REFS
4269 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4270 // The arf_sign_bias will be one for internal ARFs'
4271 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4272 (!cpi->refresh_alt_ref_frame ||
4273 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4274#else
4275 if ((cpi->oxcf.pass == 2) && cpi->multi_arf_allowed) {
4276 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
4277 arf_sign_bias = cpi->rc.source_alt_ref_active &&
4278 (!cpi->refresh_alt_ref_frame ||
4279 (gf_group->rf_level[gf_group->index] == GF_ARF_LOW));
4280 } else {
4281 arf_sign_bias =
4282 (cpi->rc.source_alt_ref_active && !cpi->refresh_alt_ref_frame);
4283 }
Zoe Liu6cfaff92016-10-18 17:12:11 -07004284#endif // CONFIG_EXT_REFS
4285
Yaowu Xuc27fc142016-08-22 16:08:15 -07004286 cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
4287#if CONFIG_EXT_REFS
4288 cm->ref_frame_sign_bias[BWDREF_FRAME] = cm->ref_frame_sign_bias[ALTREF_FRAME];
4289#endif // CONFIG_EXT_REFS
4290}
4291
Yaowu Xuf883b422016-08-30 14:01:10 -07004292static int setup_interp_filter_search_mask(AV1_COMP *cpi) {
James Zern7b9407a2016-05-18 23:48:05 -07004293 InterpFilter ifilter;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004294 int ref_total[TOTAL_REFS_PER_FRAME] = { 0 };
4295 MV_REFERENCE_FRAME ref;
4296 int mask = 0;
4297 int arf_idx = ALTREF_FRAME;
4298
4299#if CONFIG_EXT_REFS
4300 // Get which arf used as ALTREF_FRAME
4301 if (cpi->oxcf.pass == 2)
4302 arf_idx += cpi->twopass.gf_group.arf_ref_idx[cpi->twopass.gf_group.index];
Zoe Liu6cfaff92016-10-18 17:12:11 -07004303#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004304
4305 if (cpi->common.last_frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame)
4306 return mask;
4307
4308#if CONFIG_EXT_REFS
4309 for (ref = LAST_FRAME; ref < ALTREF_FRAME; ++ref)
4310 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4311 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
4312
4313 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4314 ref_total[ref] += cpi->interp_filter_selected[arf_idx][ifilter];
4315#else
4316 for (ref = LAST_FRAME; ref <= ALTREF_FRAME; ++ref)
4317 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter)
4318 ref_total[ref] += cpi->interp_filter_selected[ref][ifilter];
Zoe Liu6cfaff92016-10-18 17:12:11 -07004319#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004320
4321 for (ifilter = EIGHTTAP_REGULAR; ifilter < SWITCHABLE_FILTERS; ++ifilter) {
4322 if ((ref_total[LAST_FRAME] &&
4323 cpi->interp_filter_selected[LAST_FRAME][ifilter] == 0) &&
4324#if CONFIG_EXT_REFS
4325 (ref_total[LAST2_FRAME] == 0 ||
4326 cpi->interp_filter_selected[LAST2_FRAME][ifilter] * 50 <
4327 ref_total[LAST2_FRAME]) &&
4328 (ref_total[LAST3_FRAME] == 0 ||
4329 cpi->interp_filter_selected[LAST3_FRAME][ifilter] * 50 <
4330 ref_total[LAST3_FRAME]) &&
4331#endif // CONFIG_EXT_REFS
4332 (ref_total[GOLDEN_FRAME] == 0 ||
4333 cpi->interp_filter_selected[GOLDEN_FRAME][ifilter] * 50 <
4334 ref_total[GOLDEN_FRAME]) &&
4335#if CONFIG_EXT_REFS
4336 (ref_total[BWDREF_FRAME] == 0 ||
4337 cpi->interp_filter_selected[BWDREF_FRAME][ifilter] * 50 <
4338 ref_total[BWDREF_FRAME]) &&
4339#endif // CONFIG_EXT_REFS
4340 (ref_total[ALTREF_FRAME] == 0 ||
4341 cpi->interp_filter_selected[arf_idx][ifilter] * 50 <
4342 ref_total[ALTREF_FRAME]))
4343 mask |= 1 << ifilter;
4344 }
4345 return mask;
4346}
4347
4348#define DUMP_RECON_FRAMES 0
4349
4350#if DUMP_RECON_FRAMES == 1
4351// NOTE(zoeliu): For debug - Output the filtered reconstructed video.
Yaowu Xuf883b422016-08-30 14:01:10 -07004352static void dump_filtered_recon_frames(AV1_COMP *cpi) {
4353 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004354 const YV12_BUFFER_CONFIG *recon_buf = cm->frame_to_show;
4355 int h;
4356 char file_name[256] = "/tmp/enc_filtered_recon.yuv";
4357 FILE *f_recon = NULL;
4358
4359 if (recon_buf == NULL || !cm->show_frame) {
4360 printf("Frame %d is not ready or no show to dump.\n",
4361 cm->current_video_frame);
4362 return;
4363 }
4364
4365 if (cm->current_video_frame == 0) {
4366 if ((f_recon = fopen(file_name, "wb")) == NULL) {
4367 printf("Unable to open file %s to write.\n", file_name);
4368 return;
4369 }
4370 } else {
4371 if ((f_recon = fopen(file_name, "ab")) == NULL) {
4372 printf("Unable to open file %s to append.\n", file_name);
4373 return;
4374 }
4375 }
4376 printf(
4377 "\nFrame=%5d, encode_update_type[%5d]=%1d, show_existing_frame=%d, "
Zoe Liufcf5fa22017-06-26 16:00:38 -07004378 "source_alt_ref_active=%d, refresh_alt_ref_frame=%d, rf_level=%d, "
4379 "y_stride=%4d, uv_stride=%4d, cm->width=%4d, cm->height=%4d\n",
Yaowu Xuc27fc142016-08-22 16:08:15 -07004380 cm->current_video_frame, cpi->twopass.gf_group.index,
4381 cpi->twopass.gf_group.update_type[cpi->twopass.gf_group.index],
Zoe Liufcf5fa22017-06-26 16:00:38 -07004382 cm->show_existing_frame, cpi->rc.source_alt_ref_active,
4383 cpi->refresh_alt_ref_frame,
4384 cpi->twopass.gf_group.rf_level[cpi->twopass.gf_group.index],
4385 recon_buf->y_stride, recon_buf->uv_stride, cm->width, cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004386
4387 // --- Y ---
4388 for (h = 0; h < cm->height; ++h) {
4389 fwrite(&recon_buf->y_buffer[h * recon_buf->y_stride], 1, cm->width,
4390 f_recon);
4391 }
4392 // --- U ---
4393 for (h = 0; h < (cm->height >> 1); ++h) {
4394 fwrite(&recon_buf->u_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4395 f_recon);
4396 }
4397 // --- V ---
4398 for (h = 0; h < (cm->height >> 1); ++h) {
4399 fwrite(&recon_buf->v_buffer[h * recon_buf->uv_stride], 1, (cm->width >> 1),
4400 f_recon);
4401 }
4402
4403 fclose(f_recon);
4404}
4405#endif // DUMP_RECON_FRAMES
4406
Thomas Davies028b57f2017-02-22 16:42:11 +00004407static void make_update_tile_list_enc(AV1_COMP *cpi, const int tile_rows,
4408 const int tile_cols,
4409 FRAME_CONTEXT *ec_ctxs[]) {
4410 int i;
4411 for (i = 0; i < tile_rows * tile_cols; ++i)
4412 ec_ctxs[i] = &cpi->tile_data[i].tctx;
4413}
4414
Yaowu Xuf883b422016-08-30 14:01:10 -07004415static void encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004416 uint8_t *dest, int skip_adapt,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004417 unsigned int *frame_flags) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004418 AV1_COMMON *const cm = &cpi->common;
4419 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004420 struct segmentation *const seg = &cm->seg;
4421 TX_SIZE t;
Thomas Davies493623e2017-03-31 16:12:25 +01004422 FRAME_CONTEXT **tile_ctxs = aom_malloc(cm->tile_rows * cm->tile_cols *
4423 sizeof(&cpi->tile_data[0].tctx));
4424 aom_cdf_prob **cdf_ptrs =
4425 aom_malloc(cm->tile_rows * cm->tile_cols *
4426 sizeof(&cpi->tile_data[0].tctx.partition_cdf[0][0]));
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004427#if CONFIG_XIPHRC
4428 int frame_type;
4429 int drop_this_frame = 0;
Zoe Liue04abf72017-04-19 15:37:11 -07004430#endif // CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07004431 set_ext_overrides(cpi);
Yaowu Xuf883b422016-08-30 14:01:10 -07004432 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004433
4434 // Set the arf sign bias for this frame.
4435 set_arf_sign_bias(cpi);
Fangwen Fu8d164de2016-12-14 13:40:54 -08004436#if CONFIG_TEMPMV_SIGNALING
4437 // frame type has been decided outside of this function call
4438 cm->cur_frame->intra_only = cm->frame_type == KEY_FRAME || cm->intra_only;
4439 cm->use_prev_frame_mvs =
4440 !cpi->oxcf.disable_tempmv && !cm->cur_frame->intra_only;
4441#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004442
4443#if CONFIG_EXT_REFS
4444 // NOTE:
4445 // (1) Move the setup of the ref_frame_flags upfront as it would be
4446 // determined by the current frame properties;
4447 // (2) The setup of the ref_frame_flags applies to both show_existing_frame's
4448 // and the other cases.
4449 if (cm->current_video_frame > 0)
4450 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4451
4452 if (cm->show_existing_frame) {
4453 // NOTE(zoeliu): In BIDIR_PRED, the existing frame to show is the current
4454 // BWDREF_FRAME in the reference frame buffer.
4455 cm->frame_type = INTER_FRAME;
4456 cm->show_frame = 1;
4457 cpi->frame_flags = *frame_flags;
4458
4459 // In the case of show_existing frame, we will not send fresh flag
4460 // to decoder. Any change in the reference frame buffer can be done by
4461 // switching the virtual indices.
4462
4463 cpi->refresh_last_frame = 0;
4464 cpi->refresh_golden_frame = 0;
4465 cpi->refresh_bwd_ref_frame = 0;
4466 cpi->refresh_alt_ref_frame = 0;
4467
4468 cpi->rc.is_bwd_ref_frame = 0;
4469 cpi->rc.is_last_bipred_frame = 0;
4470 cpi->rc.is_bipred_frame = 0;
4471
4472 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004473 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004474
4475 // Set up frame to show to get ready for stats collection.
4476 cm->frame_to_show = get_frame_new_buffer(cm);
4477
4478#if DUMP_RECON_FRAMES == 1
4479 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4480 dump_filtered_recon_frames(cpi);
4481#endif // DUMP_RECON_FRAMES
4482
4483 // Update the LAST_FRAME in the reference frame buffer.
Yaowu Xuf883b422016-08-30 14:01:10 -07004484 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004485
4486 // Update frame flags
4487 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4488 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4489 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4490
4491 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4492
4493 // Update the frame type
4494 cm->last_frame_type = cm->frame_type;
4495
Yaowu Xuc27fc142016-08-22 16:08:15 -07004496 // Since we allocate a spot for the OVERLAY frame in the gf group, we need
4497 // to do post-encoding update accordingly.
4498 if (cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004499 av1_set_target_rate(cpi);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004500#if CONFIG_XIPHRC
Zoe Liue04abf72017-04-19 15:37:11 -07004501 frame_type = cm->frame_type == INTER_FRAME ? OD_P_FRAME : OD_I_FRAME;
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004502 drop_this_frame = od_enc_rc_update_state(
4503 &cpi->od_rc, *size << 3, cpi->refresh_golden_frame,
4504 cpi->refresh_alt_ref_frame, frame_type, cpi->droppable);
4505#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004506 av1_rc_postencode_update(cpi, *size);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004507#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004508 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07004509
Yaowu Xuc27fc142016-08-22 16:08:15 -07004510 ++cm->current_video_frame;
4511
Jingning Hanf6214b92017-04-12 11:43:37 -07004512 aom_free(tile_ctxs);
4513 aom_free(cdf_ptrs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004514 return;
4515 }
4516#endif // CONFIG_EXT_REFS
4517
4518 // Set default state for segment based loop filter update flags.
4519 cm->lf.mode_ref_delta_update = 0;
4520
4521 if (cpi->oxcf.pass == 2 && cpi->sf.adaptive_interp_filter_search)
4522 cpi->sf.interp_filter_search_mask = setup_interp_filter_search_mask(cpi);
4523
4524 // Set various flags etc to special state if it is a key frame.
4525 if (frame_is_intra_only(cm)) {
4526 // Reset the loop filter deltas and segmentation map.
Yaowu Xuf883b422016-08-30 14:01:10 -07004527 av1_reset_segment_features(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004528
4529 // If segmentation is enabled force a map update for key frames.
4530 if (seg->enabled) {
4531 seg->update_map = 1;
4532 seg->update_data = 1;
4533 }
4534
4535 // The alternate reference frame cannot be active for a key frame.
4536 cpi->rc.source_alt_ref_active = 0;
4537
4538 cm->error_resilient_mode = oxcf->error_resilient_mode;
4539
4540 // By default, encoder assumes decoder can use prev_mi.
4541 if (cm->error_resilient_mode) {
4542 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
4543 cm->refresh_frame_context = REFRESH_FRAME_CONTEXT_FORWARD;
4544 } else if (cm->intra_only) {
4545 // Only reset the current context.
4546 cm->reset_frame_context = RESET_FRAME_CONTEXT_CURRENT;
4547 }
4548 }
Thomas Davies80188d12016-10-26 16:08:35 -07004549#if CONFIG_TILE_GROUPS
Thomas Daviesaf6df172016-11-09 14:04:18 +00004550 if (cpi->oxcf.mtu == 0) {
4551 cm->num_tg = cpi->oxcf.num_tile_groups;
4552 } else {
Yaowu Xu859a5272016-11-10 15:32:21 -08004553 // Use a default value for the purposes of weighting costs in probability
4554 // updates
Thomas Daviesaf6df172016-11-09 14:04:18 +00004555 cm->num_tg = DEFAULT_MAX_NUM_TG;
4556 }
Thomas Davies80188d12016-10-26 16:08:35 -07004557#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004558
Yunqing Wangd8cd55f2017-02-27 12:16:00 -08004559#if CONFIG_EXT_TILE
4560 cm->tile_encoding_mode = cpi->oxcf.tile_encoding_mode;
4561#endif // CONFIG_EXT_TILE
4562
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004563#if CONFIG_XIPHRC
4564 if (drop_this_frame) {
4565 av1_rc_postencode_update_drop_frame(cpi);
4566 ++cm->current_video_frame;
Jingning Hanf6214b92017-04-12 11:43:37 -07004567 aom_free(tile_ctxs);
4568 aom_free(cdf_ptrs);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004569 return;
4570 }
4571#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07004572 // For 1 pass CBR, check if we are dropping this frame.
4573 // Never drop on key frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07004574 if (oxcf->pass == 0 && oxcf->rc_mode == AOM_CBR &&
Yaowu Xuc27fc142016-08-22 16:08:15 -07004575 cm->frame_type != KEY_FRAME) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004576 if (av1_rc_drop_frame(cpi)) {
4577 av1_rc_postencode_update_drop_frame(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004578 ++cm->current_video_frame;
Jingning Hanf6214b92017-04-12 11:43:37 -07004579 aom_free(tile_ctxs);
4580 aom_free(cdf_ptrs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004581 return;
4582 }
4583 }
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004584#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004585
Yaowu Xuf883b422016-08-30 14:01:10 -07004586 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07004587
4588#if CONFIG_INTERNAL_STATS
4589 memset(cpi->mode_chosen_counts, 0,
4590 MAX_MODES * sizeof(*cpi->mode_chosen_counts));
4591#endif
4592
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004593#if CONFIG_REFERENCE_BUFFER
4594 {
4595 /* Non-normative definition of current_frame_id ("frame counter" with
4596 * wraparound) */
Arild Fuldseth (arilfuld)788dc232016-12-20 17:55:52 +01004597 const int frame_id_length = FRAME_ID_LENGTH_MINUS7 + 7;
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004598 if (cm->current_frame_id == -1) {
David Barker49a76562016-12-07 14:50:21 +00004599 int lsb, msb;
Arild Fuldseth (arilfuld)bac17c12016-12-02 12:01:06 +01004600/* quasi-random initialization of current_frame_id for a key frame */
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004601#if CONFIG_HIGHBITDEPTH
Alex Conversef77fd0b2017-04-20 11:00:24 -07004602 if (cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) {
4603 lsb = CONVERT_TO_SHORTPTR(cpi->source->y_buffer)[0] & 0xff;
4604 msb = CONVERT_TO_SHORTPTR(cpi->source->y_buffer)[1] & 0xff;
David Barker49a76562016-12-07 14:50:21 +00004605 } else {
4606#endif
Alex Conversef77fd0b2017-04-20 11:00:24 -07004607 lsb = cpi->source->y_buffer[0] & 0xff;
4608 msb = cpi->source->y_buffer[1] & 0xff;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004609#if CONFIG_HIGHBITDEPTH
David Barker49a76562016-12-07 14:50:21 +00004610 }
Arild Fuldseth (arilfuld)bac17c12016-12-02 12:01:06 +01004611#endif
Arild Fuldseth (arilfuld)788dc232016-12-20 17:55:52 +01004612 cm->current_frame_id = ((msb << 8) + lsb) % (1 << frame_id_length);
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004613 } else {
4614 cm->current_frame_id =
Arild Fuldseth (arilfuld)788dc232016-12-20 17:55:52 +01004615 (cm->current_frame_id + 1 + (1 << frame_id_length)) %
4616 (1 << frame_id_length);
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004617 }
4618 }
4619#endif
4620
Fangwen Fu6160df22017-04-24 09:45:51 -07004621#if CONFIG_EXT_DELTA_Q
4622 cm->delta_q_present_flag = cpi->oxcf.deltaq_mode != NO_DELTA_Q;
Fangwen Fu231fe422017-04-24 17:52:29 -07004623 cm->delta_lf_present_flag = cpi->oxcf.deltaq_mode == DELTA_Q_LF;
Fangwen Fu6160df22017-04-24 09:45:51 -07004624#endif
4625
Yaowu Xuc27fc142016-08-22 16:08:15 -07004626 if (cpi->sf.recode_loop == DISALLOW_RECODE) {
4627 encode_without_recode_loop(cpi);
4628 } else {
4629 encode_with_recode_loop(cpi, size, dest);
4630 }
4631
4632#ifdef OUTPUT_YUV_SKINMAP
4633 if (cpi->common.current_video_frame > 1) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004634 av1_compute_skin_map(cpi, yuv_skinmap_file);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004635 }
4636#endif // OUTPUT_YUV_SKINMAP
4637
4638 // Special case code to reduce pulsing when key frames are forced at a
4639 // fixed interval. Note the reconstruction error if it is the frame before
4640 // the force key frame
4641 if (cpi->rc.next_key_frame_forced && cpi->rc.frames_to_key == 1) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004642#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004643 if (cm->use_highbitdepth) {
4644 cpi->ambient_err =
Alex Conversef77fd0b2017-04-20 11:00:24 -07004645 aom_highbd_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004646 } else {
Alex Conversef77fd0b2017-04-20 11:00:24 -07004647 cpi->ambient_err = aom_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Yaowu Xuc27fc142016-08-22 16:08:15 -07004648 }
4649#else
Alex Conversef77fd0b2017-04-20 11:00:24 -07004650 cpi->ambient_err = aom_get_y_sse(cpi->source, get_frame_new_buffer(cm));
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004651#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004652 }
4653
4654 // If the encoder forced a KEY_FRAME decision
4655 if (cm->frame_type == KEY_FRAME) {
4656 cpi->refresh_last_frame = 1;
4657 }
4658
4659 cm->frame_to_show = get_frame_new_buffer(cm);
4660 cm->frame_to_show->color_space = cm->color_space;
anorkin76fb1262017-03-22 15:12:12 -07004661#if CONFIG_COLORSPACE_HEADERS
4662 cm->frame_to_show->transfer_function = cm->transfer_function;
4663 cm->frame_to_show->chroma_sample_position = cm->chroma_sample_position;
4664#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004665 cm->frame_to_show->color_range = cm->color_range;
4666 cm->frame_to_show->render_width = cm->render_width;
4667 cm->frame_to_show->render_height = cm->render_height;
4668
4669#if CONFIG_EXT_REFS
4670// TODO(zoeliu): For non-ref frames, loop filtering may need to be turned
4671// off.
4672#endif // CONFIG_EXT_REFS
4673
4674 // Pick the loop filter level for the frame.
4675 loopfilter_frame(cpi, cm);
4676
4677 // Build the bitstream
Yaowu Xuf883b422016-08-30 14:01:10 -07004678 av1_pack_bitstream(cpi, dest, size);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004679
Jingning Hanf6214b92017-04-12 11:43:37 -07004680 if (skip_adapt) {
Jingning Hanf6214b92017-04-12 11:43:37 -07004681 aom_free(tile_ctxs);
4682 aom_free(cdf_ptrs);
Jingning Hanf6214b92017-04-12 11:43:37 -07004683 return;
4684 }
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004685
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01004686#if CONFIG_REFERENCE_BUFFER
4687 {
4688 int i;
4689 /* Update reference frame id values based on the value of refresh_mask */
4690 for (i = 0; i < REF_FRAMES; i++) {
4691 if ((cm->refresh_mask >> i) & 1) {
4692 cm->ref_frame_id[i] = cm->current_frame_id;
4693 }
4694 }
4695 }
4696#endif
4697
Yaowu Xuc27fc142016-08-22 16:08:15 -07004698#if DUMP_RECON_FRAMES == 1
4699 // NOTE(zoeliu): For debug - Output the filtered reconstructed video.
4700 if (cm->show_frame) dump_filtered_recon_frames(cpi);
4701#endif // DUMP_RECON_FRAMES
4702
4703 if (cm->seg.update_map) update_reference_segmentation_map(cpi);
4704
4705 if (frame_is_intra_only(cm) == 0) {
4706 release_scaled_references(cpi);
4707 }
4708
Yaowu Xuf883b422016-08-30 14:01:10 -07004709 av1_update_reference_frames(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004710
Jingning Han6de954c2016-12-16 09:52:04 -08004711 for (t = 0; t < TX_SIZES; t++)
Yaowu Xuf883b422016-08-30 14:01:10 -07004712 av1_full_to_model_counts(cpi->td.counts->coef[t],
4713 cpi->td.rd_counts.coef_counts[t]);
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08004714#if CONFIG_ENTROPY_STATS
4715 av1_accumulate_frame_counts(&aggregate_fc, &cm->counts);
Zoe Liua56f9162017-06-21 22:49:57 -07004716 assert(cm->frame_context_idx < FRAME_CONTEXTS);
4717 av1_accumulate_frame_counts(&aggregate_fc_per_type[cm->frame_context_idx],
4718 &cm->counts);
Debargha Mukherjee5802ebe2016-12-21 04:17:24 -08004719#endif // CONFIG_ENTROPY_STATS
Yaowu Xuc27fc142016-08-22 16:08:15 -07004720 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004721 av1_adapt_coef_probs(cm);
4722 av1_adapt_intra_frame_probs(cm);
Thomas Davies028b57f2017-02-22 16:42:11 +00004723 make_update_tile_list_enc(cpi, cm->tile_rows, cm->tile_cols, tile_ctxs);
Thomas Davies493623e2017-03-31 16:12:25 +01004724 av1_average_tile_coef_cdfs(cpi->common.fc, tile_ctxs, cdf_ptrs,
Thomas Davies028b57f2017-02-22 16:42:11 +00004725 cm->tile_rows * cm->tile_cols);
Thomas Davies493623e2017-03-31 16:12:25 +01004726 av1_average_tile_intra_cdfs(cpi->common.fc, tile_ctxs, cdf_ptrs,
Thomas Davies028b57f2017-02-22 16:42:11 +00004727 cm->tile_rows * cm->tile_cols);
Yushin Chob188ea12017-03-13 13:45:23 -07004728#if CONFIG_PVQ
4729 av1_average_tile_pvq_cdfs(cpi->common.fc, tile_ctxs,
4730 cm->tile_rows * cm->tile_cols);
4731#endif // CONFIG_PVQ
hui suff0da2b2017-03-07 15:51:37 -08004732#if CONFIG_ADAPT_SCAN
4733 av1_adapt_scan_order(cm);
4734#endif // CONFIG_ADAPT_SCAN
Yaowu Xuc27fc142016-08-22 16:08:15 -07004735 }
4736
4737 if (!frame_is_intra_only(cm)) {
4738 if (cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_BACKWARD) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004739 av1_adapt_inter_frame_probs(cm);
4740 av1_adapt_mv_probs(cm, cm->allow_high_precision_mv);
Thomas Davies028b57f2017-02-22 16:42:11 +00004741 av1_average_tile_inter_cdfs(&cpi->common, cpi->common.fc, tile_ctxs,
Thomas Davies493623e2017-03-31 16:12:25 +01004742 cdf_ptrs, cm->tile_rows * cm->tile_cols);
4743 av1_average_tile_mv_cdfs(cpi->common.fc, tile_ctxs, cdf_ptrs,
Thomas Davies028b57f2017-02-22 16:42:11 +00004744 cm->tile_rows * cm->tile_cols);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004745 }
4746 }
4747
4748 if (cpi->refresh_golden_frame == 1)
4749 cpi->frame_flags |= FRAMEFLAGS_GOLDEN;
4750 else
4751 cpi->frame_flags &= ~FRAMEFLAGS_GOLDEN;
4752
4753 if (cpi->refresh_alt_ref_frame == 1)
4754 cpi->frame_flags |= FRAMEFLAGS_ALTREF;
4755 else
4756 cpi->frame_flags &= ~FRAMEFLAGS_ALTREF;
4757
4758#if CONFIG_EXT_REFS
4759 if (cpi->refresh_bwd_ref_frame == 1)
4760 cpi->frame_flags |= FRAMEFLAGS_BWDREF;
4761 else
4762 cpi->frame_flags &= ~FRAMEFLAGS_BWDREF;
4763#endif // CONFIG_EXT_REFS
4764
4765#if !CONFIG_EXT_REFS
4766 cpi->ref_frame_flags = get_ref_frame_flags(cpi);
4767#endif // !CONFIG_EXT_REFS
4768
Yaowu Xuc27fc142016-08-22 16:08:15 -07004769 cm->last_frame_type = cm->frame_type;
4770
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004771#if CONFIG_XIPHRC
4772 frame_type = cm->frame_type == KEY_FRAME ? OD_I_FRAME : OD_P_FRAME;
4773
4774 drop_this_frame =
4775 od_enc_rc_update_state(&cpi->od_rc, *size << 3, cpi->refresh_golden_frame,
4776 cpi->refresh_alt_ref_frame, frame_type, 0);
4777 if (drop_this_frame) {
4778 av1_rc_postencode_update_drop_frame(cpi);
4779 ++cm->current_video_frame;
Jingning Hanf6214b92017-04-12 11:43:37 -07004780 aom_free(tile_ctxs);
4781 aom_free(cdf_ptrs);
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004782 return;
4783 }
Zoe Liue04abf72017-04-19 15:37:11 -07004784#else // !CONFIG_XIPHRC
Yaowu Xuf883b422016-08-30 14:01:10 -07004785 av1_rc_postencode_update(cpi, *size);
Zoe Liue04abf72017-04-19 15:37:11 -07004786#endif // CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07004787
4788#if 0
4789 output_frame_level_debug_stats(cpi);
4790#endif
4791
4792 if (cm->frame_type == KEY_FRAME) {
4793 // Tell the caller that the frame was coded as a key frame
4794 *frame_flags = cpi->frame_flags | FRAMEFLAGS_KEY;
4795 } else {
4796 *frame_flags = cpi->frame_flags & ~FRAMEFLAGS_KEY;
4797 }
4798
4799 // Clear the one shot update flags for segmentation map and mode/ref loop
4800 // filter deltas.
4801 cm->seg.update_map = 0;
4802 cm->seg.update_data = 0;
4803 cm->lf.mode_ref_delta_update = 0;
4804
Yaowu Xuc27fc142016-08-22 16:08:15 -07004805 if (cm->show_frame) {
4806#if CONFIG_EXT_REFS
4807// TODO(zoeliu): We may only swamp mi and prev_mi for those frames that are
4808// being used as reference.
4809#endif // CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07004810 av1_swap_mi_and_prev_mi(cm);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004811 // Don't increment frame counters if this was an altref buffer
4812 // update not a real frame
4813 ++cm->current_video_frame;
4814 }
4815
4816#if CONFIG_EXT_REFS
4817 // NOTE: Shall not refer to any frame not used as reference.
Fergus Simpson2b4ea112017-06-19 11:33:59 -07004818 if (cm->is_reference_frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004819#endif // CONFIG_EXT_REFS
4820 cm->prev_frame = cm->cur_frame;
Fergus Simpson2b4ea112017-06-19 11:33:59 -07004821 // keep track of the last coded dimensions
4822 cm->last_width = cm->width;
4823 cm->last_height = cm->height;
4824
4825 // reset to normal state now that we are done.
4826 cm->last_show_frame = cm->show_frame;
4827#if CONFIG_EXT_REFS
4828 }
4829#endif // CONFIG_EXT_REFS
Thomas Davies493623e2017-03-31 16:12:25 +01004830 aom_free(tile_ctxs);
4831 aom_free(cdf_ptrs);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004832}
4833
Yaowu Xuf883b422016-08-30 14:01:10 -07004834static void Pass0Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004835 int skip_adapt, unsigned int *frame_flags) {
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004836#if CONFIG_XIPHRC
4837 int64_t ip_count;
4838 int frame_type, is_golden, is_altref;
4839
4840 /* Not updated during init so update it here */
4841 if (cpi->oxcf.rc_mode == AOM_Q) cpi->od_rc.quality = cpi->oxcf.cq_level;
4842
4843 frame_type = od_frame_type(&cpi->od_rc, cpi->od_rc.cur_frame, &is_golden,
4844 &is_altref, &ip_count);
4845
4846 if (frame_type == OD_I_FRAME) {
4847 frame_type = KEY_FRAME;
4848 cpi->frame_flags &= FRAMEFLAGS_KEY;
4849 } else if (frame_type == OD_P_FRAME) {
4850 frame_type = INTER_FRAME;
4851 }
4852
4853 if (is_altref) {
4854 cpi->refresh_alt_ref_frame = 1;
4855 cpi->rc.source_alt_ref_active = 1;
4856 }
4857
4858 cpi->refresh_golden_frame = is_golden;
4859 cpi->common.frame_type = frame_type;
4860 if (is_golden) cpi->frame_flags &= FRAMEFLAGS_GOLDEN;
4861#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004862 if (cpi->oxcf.rc_mode == AOM_CBR) {
4863 av1_rc_get_one_pass_cbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004864 } else {
Yaowu Xuf883b422016-08-30 14:01:10 -07004865 av1_rc_get_one_pass_vbr_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004866 }
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00004867#endif
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004868 encode_frame_to_data_rate(cpi, size, dest, skip_adapt, frame_flags);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004869}
4870
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004871#if !CONFIG_XIPHRC
Yaowu Xuf883b422016-08-30 14:01:10 -07004872static void Pass2Encode(AV1_COMP *cpi, size_t *size, uint8_t *dest,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004873 unsigned int *frame_flags) {
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004874 encode_frame_to_data_rate(cpi, size, dest, 0, frame_flags);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004875
4876#if CONFIG_EXT_REFS
4877 // Do not do post-encoding update for those frames that do not have a spot in
4878 // a gf group, but note that an OVERLAY frame always has a spot in a gf group,
4879 // even when show_existing_frame is used.
4880 if (!cpi->common.show_existing_frame || cpi->rc.is_src_frame_alt_ref) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004881 av1_twopass_postencode_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004882 }
4883 check_show_existing_frame(cpi);
4884#else
Yaowu Xuf883b422016-08-30 14:01:10 -07004885 av1_twopass_postencode_update(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004886#endif // CONFIG_EXT_REFS
4887}
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00004888#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07004889
Yaowu Xuf883b422016-08-30 14:01:10 -07004890static void init_ref_frame_bufs(AV1_COMMON *cm) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07004891 int i;
4892 BufferPool *const pool = cm->buffer_pool;
4893 cm->new_fb_idx = INVALID_IDX;
4894 for (i = 0; i < REF_FRAMES; ++i) {
4895 cm->ref_frame_map[i] = INVALID_IDX;
4896 pool->frame_bufs[i].ref_count = 0;
4897 }
4898}
4899
Yaowu Xuf883b422016-08-30 14:01:10 -07004900static void check_initial_width(AV1_COMP *cpi,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004901#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004902 int use_highbitdepth,
4903#endif
4904 int subsampling_x, int subsampling_y) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004905 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004906
4907 if (!cpi->initial_width ||
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004908#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004909 cm->use_highbitdepth != use_highbitdepth ||
4910#endif
4911 cm->subsampling_x != subsampling_x ||
4912 cm->subsampling_y != subsampling_y) {
4913 cm->subsampling_x = subsampling_x;
4914 cm->subsampling_y = subsampling_y;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004915#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004916 cm->use_highbitdepth = use_highbitdepth;
4917#endif
4918
4919 alloc_raw_frame_buffers(cpi);
4920 init_ref_frame_bufs(cm);
4921 alloc_util_frame_buffers(cpi);
4922
4923 init_motion_estimation(cpi); // TODO(agrange) This can be removed.
4924
4925 cpi->initial_width = cm->width;
4926 cpi->initial_height = cm->height;
4927 cpi->initial_mbs = cm->MBs;
4928 }
4929}
4930
James Zern3e2613b2017-03-30 23:14:40 -07004931int av1_receive_raw_frame(AV1_COMP *cpi, aom_enc_frame_flags_t frame_flags,
Yaowu Xuf883b422016-08-30 14:01:10 -07004932 YV12_BUFFER_CONFIG *sd, int64_t time_stamp,
4933 int64_t end_time) {
4934 AV1_COMMON *const cm = &cpi->common;
4935 struct aom_usec_timer timer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004936 int res = 0;
4937 const int subsampling_x = sd->subsampling_x;
4938 const int subsampling_y = sd->subsampling_y;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004939#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004940 const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
4941#endif
4942
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004943#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004944 check_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y);
4945#else
4946 check_initial_width(cpi, subsampling_x, subsampling_y);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004947#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07004948
Yaowu Xuf883b422016-08-30 14:01:10 -07004949 aom_usec_timer_start(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004950
Yaowu Xuf883b422016-08-30 14:01:10 -07004951 if (av1_lookahead_push(cpi->lookahead, sd, time_stamp, end_time,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004952#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004953 use_highbitdepth,
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02004954#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07004955 frame_flags))
Yaowu Xuc27fc142016-08-22 16:08:15 -07004956 res = -1;
Yaowu Xuf883b422016-08-30 14:01:10 -07004957 aom_usec_timer_mark(&timer);
4958 cpi->time_receive_data += aom_usec_timer_elapsed(&timer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07004959
4960 if ((cm->profile == PROFILE_0 || cm->profile == PROFILE_2) &&
4961 (subsampling_x != 1 || subsampling_y != 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004962 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004963 "Non-4:2:0 color format requires profile 1 or 3");
4964 res = -1;
4965 }
4966 if ((cm->profile == PROFILE_1 || cm->profile == PROFILE_3) &&
4967 (subsampling_x == 1 && subsampling_y == 1)) {
Yaowu Xuf883b422016-08-30 14:01:10 -07004968 aom_internal_error(&cm->error, AOM_CODEC_INVALID_PARAM,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004969 "4:2:0 color format requires profile 0 or 2");
4970 res = -1;
4971 }
4972
4973 return res;
4974}
4975
Yaowu Xuf883b422016-08-30 14:01:10 -07004976static int frame_is_reference(const AV1_COMP *cpi) {
4977 const AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07004978
4979 return cm->frame_type == KEY_FRAME || cpi->refresh_last_frame ||
4980 cpi->refresh_golden_frame ||
4981#if CONFIG_EXT_REFS
4982 cpi->refresh_bwd_ref_frame ||
4983#endif // CONFIG_EXT_REFS
4984 cpi->refresh_alt_ref_frame || !cm->error_resilient_mode ||
4985 cm->lf.mode_ref_delta_update || cm->seg.update_map ||
4986 cm->seg.update_data;
4987}
4988
Yaowu Xuf883b422016-08-30 14:01:10 -07004989static void adjust_frame_rate(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07004990 const struct lookahead_entry *source) {
4991 int64_t this_duration;
4992 int step = 0;
4993
4994 if (source->ts_start == cpi->first_time_stamp_ever) {
4995 this_duration = source->ts_end - source->ts_start;
4996 step = 1;
4997 } else {
4998 int64_t last_duration =
4999 cpi->last_end_time_stamp_seen - cpi->last_time_stamp_seen;
5000
5001 this_duration = source->ts_end - cpi->last_end_time_stamp_seen;
5002
5003 // do a step update if the duration changes by 10%
5004 if (last_duration)
5005 step = (int)((this_duration - last_duration) * 10 / last_duration);
5006 }
5007
5008 if (this_duration) {
5009 if (step) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005010 av1_new_framerate(cpi, 10000000.0 / this_duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005011 } else {
5012 // Average this frame's rate into the last second's average
5013 // frame rate. If we haven't seen 1 second yet, then average
5014 // over the whole interval seen.
Yaowu Xuf883b422016-08-30 14:01:10 -07005015 const double interval = AOMMIN(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005016 (double)(source->ts_end - cpi->first_time_stamp_ever), 10000000.0);
5017 double avg_duration = 10000000.0 / cpi->framerate;
5018 avg_duration *= (interval - avg_duration + this_duration);
5019 avg_duration /= interval;
5020
Yaowu Xuf883b422016-08-30 14:01:10 -07005021 av1_new_framerate(cpi, 10000000.0 / avg_duration);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005022 }
5023 }
5024 cpi->last_time_stamp_seen = source->ts_start;
5025 cpi->last_end_time_stamp_seen = source->ts_end;
5026}
5027
5028// Returns 0 if this is not an alt ref else the offset of the source frame
5029// used as the arf midpoint.
Yaowu Xuf883b422016-08-30 14:01:10 -07005030static int get_arf_src_index(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005031 RATE_CONTROL *const rc = &cpi->rc;
5032 int arf_src_index = 0;
5033 if (is_altref_enabled(cpi)) {
5034 if (cpi->oxcf.pass == 2) {
5035 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5036 if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
5037 arf_src_index = gf_group->arf_src_offset[gf_group->index];
5038 }
5039 } else if (rc->source_alt_ref_pending) {
5040 arf_src_index = rc->frames_till_gf_update_due;
5041 }
5042 }
5043 return arf_src_index;
5044}
5045
5046#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005047static int get_brf_src_index(AV1_COMP *cpi) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005048 int brf_src_index = 0;
5049 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5050
5051 // TODO(zoeliu): We need to add the check on the -bwd_ref command line setup
5052 // flag.
5053 if (gf_group->bidir_pred_enabled[gf_group->index]) {
5054 if (cpi->oxcf.pass == 2) {
5055 if (gf_group->update_type[gf_group->index] == BRF_UPDATE)
5056 brf_src_index = gf_group->brf_src_offset[gf_group->index];
5057 } else {
5058 // TODO(zoeliu): To re-visit the setup for this scenario
5059 brf_src_index = cpi->rc.bipred_group_interval - 1;
5060 }
5061 }
5062
5063 return brf_src_index;
5064}
5065#endif // CONFIG_EXT_REFS
5066
Yaowu Xuf883b422016-08-30 14:01:10 -07005067static void check_src_altref(AV1_COMP *cpi,
Yaowu Xuc27fc142016-08-22 16:08:15 -07005068 const struct lookahead_entry *source) {
5069 RATE_CONTROL *const rc = &cpi->rc;
5070
5071 // If pass == 2, the parameters set here will be reset in
Yaowu Xuf883b422016-08-30 14:01:10 -07005072 // av1_rc_get_second_pass_params()
Yaowu Xuc27fc142016-08-22 16:08:15 -07005073
5074 if (cpi->oxcf.pass == 2) {
5075 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5076 rc->is_src_frame_alt_ref =
5077#if CONFIG_EXT_REFS
5078 (gf_group->update_type[gf_group->index] == INTNL_OVERLAY_UPDATE) ||
Zoe Liu6cfaff92016-10-18 17:12:11 -07005079#endif // CONFIG_EXT_REFS
Yaowu Xuc27fc142016-08-22 16:08:15 -07005080 (gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
5081 } else {
5082 rc->is_src_frame_alt_ref =
5083 cpi->alt_ref_source && (source == cpi->alt_ref_source);
5084 }
5085
5086 if (rc->is_src_frame_alt_ref) {
5087 // Current frame is an ARF overlay frame.
5088 cpi->alt_ref_source = NULL;
5089
5090 // Don't refresh the last buffer for an ARF overlay frame. It will
5091 // become the GF so preserve last as an alternative prediction option.
5092 cpi->refresh_last_frame = 0;
5093 }
5094}
5095
5096#if CONFIG_INTERNAL_STATS
Yaowu Xuf883b422016-08-30 14:01:10 -07005097extern double av1_get_blockiness(const unsigned char *img1, int img1_pitch,
5098 const unsigned char *img2, int img2_pitch,
5099 int width, int height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005100
5101static void adjust_image_stat(double y, double u, double v, double all,
5102 ImageStat *s) {
5103 s->stat[Y] += y;
5104 s->stat[U] += u;
5105 s->stat[V] += v;
5106 s->stat[ALL] += all;
Yaowu Xuf883b422016-08-30 14:01:10 -07005107 s->worst = AOMMIN(s->worst, all);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005108}
5109
Yaowu Xuf883b422016-08-30 14:01:10 -07005110static void compute_internal_stats(AV1_COMP *cpi) {
5111 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005112 double samples = 0.0;
5113 uint32_t in_bit_depth = 8;
5114 uint32_t bit_depth = 8;
5115
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005116#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005117 if (cm->use_highbitdepth) {
5118 in_bit_depth = cpi->oxcf.input_bit_depth;
5119 bit_depth = cm->bit_depth;
5120 }
5121#endif
5122 if (cm->show_frame) {
Alex Conversef77fd0b2017-04-20 11:00:24 -07005123 const YV12_BUFFER_CONFIG *orig = cpi->source;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005124 const YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show;
5125 double y, u, v, frame_all;
5126
5127 cpi->count++;
5128 if (cpi->b_calculate_psnr) {
5129 PSNR_STATS psnr;
5130 double frame_ssim2 = 0.0, weight = 0.0;
Yaowu Xuf883b422016-08-30 14:01:10 -07005131 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005132// TODO(yaowu): unify these two versions into one.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005133#if CONFIG_HIGHBITDEPTH
Yaowu Xuf883b422016-08-30 14:01:10 -07005134 aom_calc_highbd_psnr(orig, recon, &psnr, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005135#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005136 aom_calc_psnr(orig, recon, &psnr);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005137#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005138
5139 adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], psnr.psnr[0],
5140 &cpi->psnr);
5141 cpi->total_sq_error += psnr.sse[0];
5142 cpi->total_samples += psnr.samples[0];
5143 samples = psnr.samples[0];
5144// TODO(yaowu): unify these two versions into one.
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005145#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005146 if (cm->use_highbitdepth)
5147 frame_ssim2 =
Yaowu Xuf883b422016-08-30 14:01:10 -07005148 aom_highbd_calc_ssim(orig, recon, &weight, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005149 else
Yaowu Xuf883b422016-08-30 14:01:10 -07005150 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005151#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005152 frame_ssim2 = aom_calc_ssim(orig, recon, &weight);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005153#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005154
Yaowu Xuf883b422016-08-30 14:01:10 -07005155 cpi->worst_ssim = AOMMIN(cpi->worst_ssim, frame_ssim2);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005156 cpi->summed_quality += frame_ssim2 * weight;
5157 cpi->summed_weights += weight;
5158
5159#if 0
5160 {
5161 FILE *f = fopen("q_used.stt", "a");
5162 fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n",
5163 cpi->common.current_video_frame, y2, u2, v2,
5164 frame_psnr2, frame_ssim2);
5165 fclose(f);
5166 }
5167#endif
5168 }
5169 if (cpi->b_calculate_blockiness) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005170#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005171 if (!cm->use_highbitdepth)
5172#endif
5173 {
5174 const double frame_blockiness =
Yaowu Xuf883b422016-08-30 14:01:10 -07005175 av1_get_blockiness(orig->y_buffer, orig->y_stride, recon->y_buffer,
5176 recon->y_stride, orig->y_width, orig->y_height);
5177 cpi->worst_blockiness = AOMMAX(cpi->worst_blockiness, frame_blockiness);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005178 cpi->total_blockiness += frame_blockiness;
5179 }
5180
5181 if (cpi->b_calculate_consistency) {
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005182#if CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005183 if (!cm->use_highbitdepth)
5184#endif
5185 {
Yaowu Xuf883b422016-08-30 14:01:10 -07005186 const double this_inconsistency = aom_get_ssim_metrics(
Yaowu Xuc27fc142016-08-22 16:08:15 -07005187 orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride,
5188 orig->y_width, orig->y_height, cpi->ssim_vars, &cpi->metrics, 1);
5189
5190 const double peak = (double)((1 << in_bit_depth) - 1);
5191 const double consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07005192 aom_sse_to_psnr(samples, peak, cpi->total_inconsistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005193 if (consistency > 0.0)
5194 cpi->worst_consistency =
Yaowu Xuf883b422016-08-30 14:01:10 -07005195 AOMMIN(cpi->worst_consistency, consistency);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005196 cpi->total_inconsistency += this_inconsistency;
5197 }
5198 }
5199 }
5200
5201 frame_all =
Yaowu Xuf883b422016-08-30 14:01:10 -07005202 aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005203 adjust_image_stat(y, u, v, frame_all, &cpi->fastssim);
Yaowu Xuf883b422016-08-30 14:01:10 -07005204 frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005205 adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs);
5206 }
5207}
5208#endif // CONFIG_INTERNAL_STATS
5209
Yaowu Xuf883b422016-08-30 14:01:10 -07005210int av1_get_compressed_data(AV1_COMP *cpi, unsigned int *frame_flags,
5211 size_t *size, uint8_t *dest, int64_t *time_stamp,
5212 int64_t *time_end, int flush) {
5213 const AV1EncoderConfig *const oxcf = &cpi->oxcf;
5214 AV1_COMMON *const cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005215 BufferPool *const pool = cm->buffer_pool;
5216 RATE_CONTROL *const rc = &cpi->rc;
Yaowu Xuf883b422016-08-30 14:01:10 -07005217 struct aom_usec_timer cmptimer;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005218 YV12_BUFFER_CONFIG *force_src_buffer = NULL;
5219 struct lookahead_entry *last_source = NULL;
5220 struct lookahead_entry *source = NULL;
5221 int arf_src_index;
5222#if CONFIG_EXT_REFS
5223 int brf_src_index;
5224#endif // CONFIG_EXT_REFS
5225 int i;
5226
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00005227#if CONFIG_XIPHRC
5228 cpi->od_rc.end_of_input = flush;
5229#endif
5230
Yaowu Xuc27fc142016-08-22 16:08:15 -07005231#if CONFIG_BITSTREAM_DEBUG
5232 assert(cpi->oxcf.max_threads == 0 &&
5233 "bitstream debug tool does not support multithreading");
5234 bitstream_queue_record_write();
Angie Chiangcb9a9eb2016-09-01 16:10:50 -07005235 bitstream_queue_set_frame_write(cm->current_video_frame * 2 + cm->show_frame);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005236#endif
5237
Yaowu Xuf883b422016-08-30 14:01:10 -07005238 aom_usec_timer_start(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005239
Yaowu Xuf883b422016-08-30 14:01:10 -07005240 av1_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005241
5242 // Is multi-arf enabled.
5243 // Note that at the moment multi_arf is only configured for 2 pass VBR
5244 if ((oxcf->pass == 2) && (cpi->oxcf.enable_auto_arf > 1))
5245 cpi->multi_arf_allowed = 1;
5246 else
5247 cpi->multi_arf_allowed = 0;
5248
5249 // Normal defaults
5250 cm->reset_frame_context = RESET_FRAME_CONTEXT_NONE;
5251 cm->refresh_frame_context =
5252 (oxcf->error_resilient_mode || oxcf->frame_parallel_decoding_mode)
5253 ? REFRESH_FRAME_CONTEXT_FORWARD
5254 : REFRESH_FRAME_CONTEXT_BACKWARD;
5255
5256 cpi->refresh_last_frame = 1;
5257 cpi->refresh_golden_frame = 0;
5258#if CONFIG_EXT_REFS
5259 cpi->refresh_bwd_ref_frame = 0;
5260#endif // CONFIG_EXT_REFS
5261 cpi->refresh_alt_ref_frame = 0;
5262
Zoe Liue04abf72017-04-19 15:37:11 -07005263#if CONFIG_EXT_REFS && !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07005264 if (oxcf->pass == 2 && cm->show_existing_frame) {
5265 // Manage the source buffer and flush out the source frame that has been
5266 // coded already; Also get prepared for PSNR calculation if needed.
Yaowu Xuf883b422016-08-30 14:01:10 -07005267 if ((source = av1_lookahead_pop(cpi->lookahead, flush)) == NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005268 *size = 0;
5269 return -1;
5270 }
Alex Conversef77fd0b2017-04-20 11:00:24 -07005271 cpi->source = &source->img;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005272 // TODO(zoeliu): To track down to determine whether it's needed to adjust
5273 // the frame rate.
5274 *time_stamp = source->ts_start;
5275 *time_end = source->ts_end;
5276
5277 // We need to adjust frame rate for an overlay frame
Zoe Liue04abf72017-04-19 15:37:11 -07005278 if (cpi->rc.is_src_frame_alt_ref) adjust_frame_rate(cpi, source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005279
5280 // Find a free buffer for the new frame, releasing the reference previously
5281 // held.
5282 if (cm->new_fb_idx != INVALID_IDX) {
5283 --pool->frame_bufs[cm->new_fb_idx].ref_count;
5284 }
5285 cm->new_fb_idx = get_free_fb(cm);
5286
5287 if (cm->new_fb_idx == INVALID_IDX) return -1;
5288
5289 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005290 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005291
5292 // Start with a 0 size frame.
5293 *size = 0;
5294
5295 // We need to update the gf_group for show_existing overlay frame
Zoe Liue04abf72017-04-19 15:37:11 -07005296 if (cpi->rc.is_src_frame_alt_ref) av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005297
5298 Pass2Encode(cpi, size, dest, frame_flags);
5299
5300 if (cpi->b_calculate_psnr) generate_psnr_packet(cpi);
5301
5302#if CONFIG_INTERNAL_STATS
5303 compute_internal_stats(cpi);
5304 cpi->bytes += (int)(*size);
5305#endif // CONFIG_INTERNAL_STATS
5306
5307 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005308 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005309
5310 cm->show_existing_frame = 0;
5311 return 0;
5312 }
Zoe Liue04abf72017-04-19 15:37:11 -07005313#endif // CONFIG_EXT_REFS && !CONFIG_XIPHRC
Yaowu Xuc27fc142016-08-22 16:08:15 -07005314
5315 // Should we encode an arf frame.
5316 arf_src_index = get_arf_src_index(cpi);
5317 if (arf_src_index) {
5318 for (i = 0; i <= arf_src_index; ++i) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005319 struct lookahead_entry *e = av1_lookahead_peek(cpi->lookahead, i);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005320 // Avoid creating an alt-ref if there's a forced keyframe pending.
5321 if (e == NULL) {
5322 break;
Yaowu Xuf883b422016-08-30 14:01:10 -07005323 } else if (e->flags == AOM_EFLAG_FORCE_KF) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005324 arf_src_index = 0;
5325 flush = 1;
5326 break;
5327 }
5328 }
5329 }
5330
5331 if (arf_src_index) {
5332 assert(arf_src_index <= rc->frames_to_key);
5333
Yaowu Xuf883b422016-08-30 14:01:10 -07005334 if ((source = av1_lookahead_peek(cpi->lookahead, arf_src_index)) != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005335 cpi->alt_ref_source = source;
5336
5337 if (oxcf->arnr_max_frames > 0) {
Todd Nguyen302d0972017-06-16 16:16:29 -07005338// Produce the filtered ARF frame.
5339#if CONFIG_BGSPRITE
5340 int bgsprite_ret = av1_background_sprite(cpi, arf_src_index);
5341 if (bgsprite_ret != EXIT_SUCCESS) {
5342 av1_temporal_filter(cpi, arf_src_index);
5343 }
5344#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005345 av1_temporal_filter(cpi, arf_src_index);
Todd Nguyen302d0972017-06-16 16:16:29 -07005346#endif // CONFIG_BGSPRITE
Yaowu Xuf883b422016-08-30 14:01:10 -07005347 aom_extend_frame_borders(&cpi->alt_ref_buffer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005348 force_src_buffer = &cpi->alt_ref_buffer;
5349 }
5350
5351 cm->show_frame = 0;
5352 cm->intra_only = 0;
5353 cpi->refresh_alt_ref_frame = 1;
5354 cpi->refresh_golden_frame = 0;
5355 cpi->refresh_last_frame = 0;
5356 rc->is_src_frame_alt_ref = 0;
5357 }
5358 rc->source_alt_ref_pending = 0;
5359 }
5360
5361#if CONFIG_EXT_REFS
5362 rc->is_bwd_ref_frame = 0;
5363 brf_src_index = get_brf_src_index(cpi);
5364 if (brf_src_index) {
5365 assert(brf_src_index <= rc->frames_to_key);
Yaowu Xuf883b422016-08-30 14:01:10 -07005366 if ((source = av1_lookahead_peek(cpi->lookahead, brf_src_index)) != NULL) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005367 cm->show_frame = 0;
5368 cm->intra_only = 0;
5369
5370 cpi->refresh_bwd_ref_frame = 1;
5371 cpi->refresh_last_frame = 0;
5372 cpi->refresh_golden_frame = 0;
5373 cpi->refresh_alt_ref_frame = 0;
5374
5375 rc->is_bwd_ref_frame = 1;
5376 }
5377 }
5378#endif // CONFIG_EXT_REFS
5379
5380 if (!source) {
5381 // Get last frame source.
5382 if (cm->current_video_frame > 0) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005383 if ((last_source = av1_lookahead_peek(cpi->lookahead, -1)) == NULL)
Yaowu Xuc27fc142016-08-22 16:08:15 -07005384 return -1;
5385 }
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07005386 if (cm->current_video_frame > 0) assert(last_source != NULL);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005387 // Read in the source frame.
Yaowu Xuf883b422016-08-30 14:01:10 -07005388 source = av1_lookahead_pop(cpi->lookahead, flush);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005389
5390 if (source != NULL) {
5391 cm->show_frame = 1;
5392 cm->intra_only = 0;
5393
5394 // Check to see if the frame should be encoded as an arf overlay.
5395 check_src_altref(cpi, source);
5396 }
5397 }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005398 if (source) {
Fergus Simpsond2bcbb52017-05-22 23:15:05 -07005399 cpi->unscaled_source = cpi->source =
Yaowu Xuc27fc142016-08-22 16:08:15 -07005400 force_src_buffer ? force_src_buffer : &source->img;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005401 cpi->unscaled_last_source = last_source != NULL ? &last_source->img : NULL;
5402
5403 *time_stamp = source->ts_start;
5404 *time_end = source->ts_end;
Yaowu Xuf883b422016-08-30 14:01:10 -07005405 *frame_flags = (source->flags & AOM_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005406
5407 } else {
5408 *size = 0;
5409 if (flush && oxcf->pass == 1 && !cpi->twopass.first_pass_done) {
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00005410#if CONFIG_XIPHRC
5411 od_enc_rc_2pass_out(&cpi->od_rc, cpi->output_pkt_list, 1);
5412#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005413 av1_end_first_pass(cpi); /* get last stats packet */
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00005414#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005415 cpi->twopass.first_pass_done = 1;
5416 }
5417 return -1;
5418 }
5419
5420 if (source->ts_start < cpi->first_time_stamp_ever) {
5421 cpi->first_time_stamp_ever = source->ts_start;
5422 cpi->last_end_time_stamp_seen = source->ts_start;
5423 }
5424
5425 // Clear down mmx registers
Yaowu Xuf883b422016-08-30 14:01:10 -07005426 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005427
5428 // adjust frame rates based on timestamps given
5429 if (cm->show_frame) adjust_frame_rate(cpi, source);
5430
5431 // Find a free buffer for the new frame, releasing the reference previously
5432 // held.
5433 if (cm->new_fb_idx != INVALID_IDX) {
5434 --pool->frame_bufs[cm->new_fb_idx].ref_count;
5435 }
5436 cm->new_fb_idx = get_free_fb(cm);
5437
5438 if (cm->new_fb_idx == INVALID_IDX) return -1;
5439
5440 cm->cur_frame = &pool->frame_bufs[cm->new_fb_idx];
5441
5442#if CONFIG_EXT_REFS
5443 if (oxcf->pass == 2) {
5444 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5445 cpi->alt_fb_idx = cpi->arf_map[gf_group->arf_ref_idx[gf_group->index]];
5446 }
5447#else
5448 if (cpi->multi_arf_allowed) {
5449 if (cm->frame_type == KEY_FRAME) {
5450 init_buffer_indices(cpi);
5451 } else if (oxcf->pass == 2) {
5452 const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
5453 cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
5454 }
5455 }
Zoe Liu6cfaff92016-10-18 17:12:11 -07005456#endif // CONFIG_EXT_REFS
5457
Yaowu Xuc27fc142016-08-22 16:08:15 -07005458 // Start with a 0 size frame.
5459 *size = 0;
5460
5461 cpi->frame_flags = *frame_flags;
5462
5463 if (oxcf->pass == 2) {
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00005464#if CONFIG_XIPHRC
5465 if (od_enc_rc_2pass_in(&cpi->od_rc) < 0) return -1;
5466 }
5467#else
Yaowu Xuf883b422016-08-30 14:01:10 -07005468 av1_rc_get_second_pass_params(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005469 } else if (oxcf->pass == 1) {
Fergus Simpsonbc189932017-05-16 17:02:39 -07005470 setup_frame_size(cpi);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005471 }
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00005472#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005473
5474 if (cpi->oxcf.pass != 0 || frame_is_intra_only(cm) == 1) {
5475 for (i = 0; i < TOTAL_REFS_PER_FRAME; ++i)
5476 cpi->scaled_ref_idx[i] = INVALID_IDX;
5477 }
5478
5479#if CONFIG_AOM_QM
5480 cm->using_qmatrix = cpi->oxcf.using_qm;
5481 cm->min_qmlevel = cpi->oxcf.qm_minlevel;
5482 cm->max_qmlevel = cpi->oxcf.qm_maxlevel;
5483#endif
5484
Arild Fuldseth (arilfuld)5114b7b2016-11-09 13:32:54 +01005485#if CONFIG_REFERENCE_BUFFER
5486 if (*time_stamp == 0) {
5487 cpi->common.current_frame_id = -1;
5488 }
5489#endif
5490
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00005491#if CONFIG_XIPHRC
5492 if (oxcf->pass == 1) {
5493 size_t tmp;
5494 if (cpi->od_rc.cur_frame == 0) Pass0Encode(cpi, &tmp, dest, 1, frame_flags);
5495 cpi->od_rc.firstpass_quant = cpi->od_rc.target_quantizer;
5496 Pass0Encode(cpi, &tmp, dest, 0, frame_flags);
5497 od_enc_rc_2pass_out(&cpi->od_rc, cpi->output_pkt_list, 0);
5498 } else if (oxcf->pass == 2) {
5499 Pass0Encode(cpi, size, dest, 0, frame_flags);
5500 } else {
5501 if (cpi->od_rc.cur_frame == 0) {
5502 size_t tmp;
5503 Pass0Encode(cpi, &tmp, dest, 1, frame_flags);
5504 }
5505 Pass0Encode(cpi, size, dest, 0, frame_flags);
5506 }
5507#else
Yaowu Xuc27fc142016-08-22 16:08:15 -07005508 if (oxcf->pass == 1) {
5509 cpi->td.mb.e_mbd.lossless[0] = is_lossless_requested(oxcf);
Yaowu Xuf883b422016-08-30 14:01:10 -07005510 av1_first_pass(cpi, source);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005511 } else if (oxcf->pass == 2) {
5512 Pass2Encode(cpi, size, dest, frame_flags);
5513 } else {
5514 // One pass encode
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00005515 Pass0Encode(cpi, size, dest, 0, frame_flags);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005516 }
Rostislav Pehlivanov74021a52017-03-09 09:05:29 +00005517#endif
Yaowu Xuc27fc142016-08-22 16:08:15 -07005518
5519 if (!cm->error_resilient_mode)
5520 cm->frame_contexts[cm->frame_context_idx] = *cm->fc;
5521
5522 // No frame encoded, or frame was dropped, release scaled references.
5523 if ((*size == 0) && (frame_is_intra_only(cm) == 0)) {
5524 release_scaled_references(cpi);
5525 }
5526
5527 if (*size > 0) {
5528 cpi->droppable = !frame_is_reference(cpi);
5529 }
5530
Yaowu Xuf883b422016-08-30 14:01:10 -07005531 aom_usec_timer_mark(&cmptimer);
5532 cpi->time_compress_data += aom_usec_timer_elapsed(&cmptimer);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005533
5534 if (cpi->b_calculate_psnr && oxcf->pass != 1 && cm->show_frame)
5535 generate_psnr_packet(cpi);
5536
5537#if CONFIG_INTERNAL_STATS
5538 if (oxcf->pass != 1) {
5539 compute_internal_stats(cpi);
5540 cpi->bytes += (int)(*size);
5541 }
5542#endif // CONFIG_INTERNAL_STATS
5543
Rostislav Pehlivanov002e7b72017-02-15 19:45:54 +00005544#if CONFIG_XIPHRC
5545 cpi->od_rc.cur_frame++;
5546#endif
5547
Yaowu Xuf883b422016-08-30 14:01:10 -07005548 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005549
5550 return 0;
5551}
5552
Yaowu Xuf883b422016-08-30 14:01:10 -07005553int av1_get_preview_raw_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *dest) {
5554 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005555 if (!cm->show_frame) {
5556 return -1;
5557 } else {
5558 int ret;
5559 if (cm->frame_to_show) {
5560 *dest = *cm->frame_to_show;
5561 dest->y_width = cm->width;
5562 dest->y_height = cm->height;
5563 dest->uv_width = cm->width >> cm->subsampling_x;
5564 dest->uv_height = cm->height >> cm->subsampling_y;
5565 ret = 0;
5566 } else {
5567 ret = -1;
5568 }
Yaowu Xuf883b422016-08-30 14:01:10 -07005569 aom_clear_system_state();
Yaowu Xuc27fc142016-08-22 16:08:15 -07005570 return ret;
5571 }
5572}
5573
Yaowu Xuf883b422016-08-30 14:01:10 -07005574int av1_get_last_show_frame(AV1_COMP *cpi, YV12_BUFFER_CONFIG *frame) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005575 if (cpi->last_show_frame_buf_idx == INVALID_IDX) return -1;
5576
5577 *frame =
5578 cpi->common.buffer_pool->frame_bufs[cpi->last_show_frame_buf_idx].buf;
5579 return 0;
5580}
5581
Yaowu Xuf883b422016-08-30 14:01:10 -07005582int av1_set_internal_size(AV1_COMP *cpi, AOM_SCALING horiz_mode,
5583 AOM_SCALING vert_mode) {
5584 AV1_COMMON *cm = &cpi->common;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005585 int hr = 0, hs = 0, vr = 0, vs = 0;
5586
5587 if (horiz_mode > ONETWO || vert_mode > ONETWO) return -1;
5588
5589 Scale2Ratio(horiz_mode, &hr, &hs);
5590 Scale2Ratio(vert_mode, &vr, &vs);
5591
5592 // always go to the next whole number
5593 cm->width = (hs - 1 + cpi->oxcf.width * hr) / hs;
5594 cm->height = (vs - 1 + cpi->oxcf.height * vr) / vs;
5595 assert(cm->width <= cpi->initial_width);
5596 assert(cm->height <= cpi->initial_height);
5597
5598 update_frame_size(cpi);
5599
5600 return 0;
5601}
5602
Fergus Simpson0a30c882017-05-16 16:54:51 -07005603int av1_set_size_literal(AV1_COMP *cpi, int width, int height) {
Yaowu Xuf883b422016-08-30 14:01:10 -07005604 AV1_COMMON *cm = &cpi->common;
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005605#if CONFIG_HIGHBITDEPTH
Debargha Mukherjee887069f2017-06-16 18:54:36 -07005606 check_initial_width(cpi, cm->use_highbitdepth, cm->subsampling_x,
5607 cm->subsampling_y);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005608#else
Debargha Mukherjee887069f2017-06-16 18:54:36 -07005609 check_initial_width(cpi, cm->subsampling_x, cm->subsampling_y);
Sebastien Alaiwan71e87842017-04-12 16:03:28 +02005610#endif // CONFIG_HIGHBITDEPTH
Yaowu Xuc27fc142016-08-22 16:08:15 -07005611
Fergus Simpson0a30c882017-05-16 16:54:51 -07005612 if (width <= 0 || height <= 0) return 1;
5613
5614 cm->width = width;
5615 if (cm->width > cpi->initial_width) {
5616 cm->width = cpi->initial_width;
5617 printf("Warning: Desired width too large, changed to %d\n", cm->width);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005618 }
5619
Fergus Simpson0a30c882017-05-16 16:54:51 -07005620 cm->height = height;
5621 if (cm->height > cpi->initial_height) {
5622 cm->height = cpi->initial_height;
5623 printf("Warning: Desired height too large, changed to %d\n", cm->height);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005624 }
Fergus Simpson0a30c882017-05-16 16:54:51 -07005625
Yaowu Xuc27fc142016-08-22 16:08:15 -07005626 assert(cm->width <= cpi->initial_width);
5627 assert(cm->height <= cpi->initial_height);
5628
5629 update_frame_size(cpi);
5630
5631 return 0;
5632}
5633
Yaowu Xuf883b422016-08-30 14:01:10 -07005634int av1_get_quantizer(AV1_COMP *cpi) { return cpi->common.base_qindex; }
Yaowu Xuc27fc142016-08-22 16:08:15 -07005635
Yaowu Xuf883b422016-08-30 14:01:10 -07005636void av1_apply_encoding_flags(AV1_COMP *cpi, aom_enc_frame_flags_t flags) {
Yaowu Xuc27fc142016-08-22 16:08:15 -07005637 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005638 (AOM_EFLAG_NO_REF_LAST | AOM_EFLAG_NO_REF_GF | AOM_EFLAG_NO_REF_ARF)) {
5639 int ref = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005640
Yaowu Xuf883b422016-08-30 14:01:10 -07005641 if (flags & AOM_EFLAG_NO_REF_LAST) {
5642 ref ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005643#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005644 ref ^= AOM_LAST2_FLAG;
5645 ref ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005646#endif // CONFIG_EXT_REFS
5647 }
5648
Yaowu Xuf883b422016-08-30 14:01:10 -07005649 if (flags & AOM_EFLAG_NO_REF_GF) ref ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005650
Yaowu Xuf883b422016-08-30 14:01:10 -07005651 if (flags & AOM_EFLAG_NO_REF_ARF) ref ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005652
Yaowu Xuf883b422016-08-30 14:01:10 -07005653 av1_use_as_reference(cpi, ref);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005654 }
5655
5656 if (flags &
Yaowu Xuf883b422016-08-30 14:01:10 -07005657 (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
5658 AOM_EFLAG_FORCE_GF | AOM_EFLAG_FORCE_ARF)) {
5659 int upd = AOM_REFFRAME_ALL;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005660
Yaowu Xuf883b422016-08-30 14:01:10 -07005661 if (flags & AOM_EFLAG_NO_UPD_LAST) {
5662 upd ^= AOM_LAST_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005663#if CONFIG_EXT_REFS
Yaowu Xuf883b422016-08-30 14:01:10 -07005664 upd ^= AOM_LAST2_FLAG;
5665 upd ^= AOM_LAST3_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005666#endif // CONFIG_EXT_REFS
5667 }
5668
Yaowu Xuf883b422016-08-30 14:01:10 -07005669 if (flags & AOM_EFLAG_NO_UPD_GF) upd ^= AOM_GOLD_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005670
Yaowu Xuf883b422016-08-30 14:01:10 -07005671 if (flags & AOM_EFLAG_NO_UPD_ARF) upd ^= AOM_ALT_FLAG;
Yaowu Xuc27fc142016-08-22 16:08:15 -07005672
Yaowu Xuf883b422016-08-30 14:01:10 -07005673 av1_update_reference(cpi, upd);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005674 }
5675
Yaowu Xuf883b422016-08-30 14:01:10 -07005676 if (flags & AOM_EFLAG_NO_UPD_ENTROPY) {
5677 av1_update_entropy(cpi, 0);
Yaowu Xuc27fc142016-08-22 16:08:15 -07005678 }
5679}